bulletml/0000755000076400007640000000000010370171151007622 5ustar bulletml/README.bulletml0000644000076400007640000001507007665333613012344 0ustar BulletML Reference ver. 0.21 (c) 長健太(ABA."Saba") ABA Games BulletMLの簡易リファレンスです。 - Defines the BulletML's body ━━━━━━━━━━━━━━━━━━━ ・ Attribute - type = (none | vertical | horizontal) ・ Contents - (bullet | action | fire)* BulletML本体を定義します。 type属性は、この弾幕が縦スクロールシューティング用か、横スクロールシューティン グ用かを規定します。 - Defines attributes of a bullet ━━━━━━━━━━━━━━━━━━ ・ Attribute - label = STRING ・ Contents - direction?, speed?, (action | actionRef)* ・ Exapmle 270 2 3 120 弾の方向、速度およびアクションを定義します。 ラベル属性でラベル名をつけることができます。ラベル付けされたbullet要素は、 bulletRef要素によって参照されます。 - Defines the action of bullet ━━━━━━━━━━━━━━━━━━━ ・ Attribute - label = STRING ・ Contents - (repeat | fire | fireRef | changeSpeed | changeDirection | accel | wait | vanish | action | actionRef)* ・ Exapmle 0 60 60 330+$rand*25 弾のアクションを定義します。ラベル付けされたaction要素は、actionRef要素によって 参照されます。 - Fires a bullet ━━━━━━━━━━━━━━━━━━━━━━━━━━━ ・ Attribute - label = STRING ・ Contents - direction?, speed?, (bullet | bulletRef) ・ Exapmle 270 2 弾を度方向に速度で撃ちます。ラベル付けされたfire要素は、 fireRef要素によって参照されます。 - Changes the direction of bullet ━━━━━━━━━━━━━ ・ Contents - direction, term 弾の方向を度にフレームかけて曲げます。 1フレームは1/60秒です。 - Changes the speed of bullet ━━━━━━━━━━━━━━━━━ ・ Contents - speed, term 弾の速度をフレームかけて変えます。 - Accelerates a bullet ━━━━━━━━━━━━━━━━━━━━━━━━ ・ Contents - horizontal?, vertical?, term 弾を水平方向に、垂直方向にフレームかけて加速しま す。 - Waits ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ ・ Contents - NUMBER NUMBERフレーム待ちます。 - Vanishes a bullet ━━━━━━━━━━━━━━━━━━━━━━━━━ 弾を消します。 - Repeats an action ━━━━━━━━━━━━━━━━━━━━━━━━━ ・ Contents - times, (action | actionRef) ・ Exapmle 100 220+$rand*100 6 アクションを回繰り返します。 - Specifies a direction ━━━━━━━━━━━━━━━━━━━━━ ・ Attribute - type = (aim | absolute | relative | sequence) ・ Contents - NUMBER 方向を度単位で指定します。 typeが"aim"の場合、自機を狙う方向が0の相対値になります。 typeが"absolute"の場合、NUMBERは絶対値(上方向が0で時計回り)です。 typeが"relative"の場合、NUMBERはこの弾の方向が0の相対値になります。 typeが"sequence"の場合、直前の弾を撃った方向が0の相対値になります。 - Specifies a speed ━━━━━━━━━━━━━━━━━━━━━━━━━ ・ Attribute - type = (absolute | relative | sequence) ・ Contents - NUMBER 速度を指定します。 typeが"relative"の場合、 changeSpeed要素内では現在の弾の速度との相対値、それ以 外の要素内ではこの弾の速度との相対値です。 typeが"sequence"の場合、 changeSpeed要素内では弾の速度を連続的に変化させ、それ 以外の要素内では直前の弾の速度との相対値です。 - Specifies the acceleration in a horizontal line ━━━━━━━━ ・ Attribute - type = (absolute | relative | sequence) ・ Contents - NUMBER 水平方向の弾の加速度を指定します。 typeが"relative"の場合、現在の弾の速度との相対値です。 typeが"sequence"の場合、 加速度を連続的に変化させます。 - Specifies the acceleration in a vertical line ━━━━━━━━━━ ・ Attribute - type = (absolute | relative | sequence) ・ Contents - NUMBER 垂直方向の弾の加速度を指定します。 typeが"sequence"の場合、現在の弾の速度との相対値です。 typeが"sequence"の場合、 加速度を連続的に変化させます。 - Specifies a term ━━━━━━━━━━━━━━━━━━━━━━━━━━ ・ Contents - NUMBER 期間を指定します。 - Specifies the number of times ━━━━━━━━━━━━━━━━━━━ ・ Contents - NUMBER 繰り返し回数を指定します。 - Refers to the bullet ━━━━━━━━━━━━━━━━━━━━━━ ・ Attribute - label = STRING ・ Contents - param* ラベル付けされたbullet要素を参照します。この要素は同名のラベルでラベル付けされ たbullet要素と同じに扱われます。 参照されたbullet要素内の変数($1, $2, $3, ...)は、 要素に指定された数値 に置き換えられます。(最初に出現したparam要素が$1に、次に出現したparam要素が$2 に、...) - Refers to the action ━━━━━━━━━━━━━━━━━━━━━━ ・ Attribute - label = STRING ・ Contents - param* ラベル付けされたaction要素を参照します。この要素は同名のラベルでラベル付けされ たaction要素と同じに扱われます。 参照されたaction要素内の変数は、要素に指定された数値に置き換えられます。 - Refers to the fire action ━━━━━━━━━━━━━━━━━━━━ ・ Attribute - label = STRING ・ Contents - param* ラベル付けされたfire要素を参照します。この要素は同名のラベルでラベル付けされた fire要素と同じに扱われます。 参照されたfire要素内の変数は、要素に指定された数値に置き換えられます。 - Specifies the parameter ━━━━━━━━━━━━━━━━━━━━━━ ・ Contents - NUMBER パラメタを指定します。 STRING - any string ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ ラベル用文字列です。 NUMBER - expression ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ ・ Exapmles 35 360/16 0.7 + 0.9*$rand 180-$rank*20 (2+$1)*0.3 数値を指定するための式です。 四則演算と剰余算、括弧、変数(パラメタ用に$1, $2, $3...、乱数(0から1までの値) 用に$rand、難易度(0から1までの値)用に$rank)が使えます。 bulletml/libbulletml.dsp0000644000076400007640000001246507726415420012664 0ustar # Microsoft Developer Studio Project File - Name="libbulletml" - Package Owner=<4> # Microsoft Developer Studio Generated Build File, Format Version 6.00 # ** W ** # TARGTYPE "Win32 (x86) Static Library" 0x0104 CFG=libbulletml - Win32 Debug !MESSAGE L頒恩箕荷B 面炳灼個靄湶爪 NMAKE gpB !MESSAGE [匆弧Р夢現累按] 栽歡gpタs !MESSAGE !MESSAGE NMAKE /f "libbulletml.mak". !MESSAGE !MESSAGE NMAKE タs\w !MESSAGE 栽歡 弉渡雇`B: !MESSAGE !MESSAGE NMAKE /f "libbulletml.mak" CFG="libbulletml - Win32 Debug" !MESSAGE !MESSAGE I\繁湶爪 唹爪: !MESSAGE !MESSAGE "libbulletml - Win32 Release" ("Win32 (x86) Static Library" p) !MESSAGE "libbulletml - Win32 Debug" ("Win32 (x86) Static Library" p) !MESSAGE # Begin Project # PROP AllowPerConfigDependencies 0 # PROP Scc_ProjName "" # PROP Scc_LocalPath "" CPP=cl.exe RSC=rc.exe !IF "$(CFG)" == "libbulletml - Win32 Release" # PROP BASE Use_MFC 0 # PROP BASE Use_Debug_Libraries 0 # PROP BASE Output_Dir "Release" # PROP BASE Intermediate_Dir "Release" # PROP BASE Target_Dir "" # PROP Use_MFC 0 # PROP Use_Debug_Libraries 0 # PROP Output_Dir "Release" # PROP Intermediate_Dir "Release" # PROP Target_Dir "" # ADD BASE CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_MBCS" /D "_LIB" /YX /FD /c # ADD CPP /nologo /W3 /GR /GX /O2 /I "src/" /D "WIN32" /D "NDEBUG" /D "_MBCS" /D "_LIB" /YX /FD /c # ADD BASE RSC /l 0x411 /d "NDEBUG" # ADD RSC /l 0x411 /d "NDEBUG" BSC32=bscmake.exe # ADD BASE BSC32 /nologo # ADD BSC32 /nologo LIB32=link.exe -lib # ADD BASE LIB32 /nologo # ADD LIB32 /nologo !ELSEIF "$(CFG)" == "libbulletml - Win32 Debug" # PROP BASE Use_MFC 0 # PROP BASE Use_Debug_Libraries 1 # PROP BASE Output_Dir "Debug" # PROP BASE Intermediate_Dir "Debug" # PROP BASE Target_Dir "" # PROP Use_MFC 0 # PROP Use_Debug_Libraries 1 # PROP Output_Dir "Debug" # PROP Intermediate_Dir "Debug" # PROP Target_Dir "" # ADD BASE CPP /nologo /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_MBCS" /D "_LIB" /YX /FD /GZ /c # ADD CPP /nologo /W3 /Gm /GR /GX /ZI /Od /I "src/" /D "WIN32" /D "_DEBUG" /D "_MBCS" /D "_LIB" /YX /FD /GZ /c # ADD BASE RSC /l 0x411 /d "_DEBUG" # ADD RSC /l 0x411 /d "_DEBUG" BSC32=bscmake.exe # ADD BASE BSC32 /nologo # ADD BSC32 /nologo LIB32=link.exe -lib # ADD BASE LIB32 /nologo # ADD LIB32 /nologo !ENDIF # Begin Target # Name "libbulletml - Win32 Release" # Name "libbulletml - Win32 Debug" # Begin Group "Source Files" # PROP Default_Filter "cpp;c;cxx;rc;def;r;odl;idl;hpj;bat" # Begin Group "libBulletML src" # PROP Default_Filter "" # Begin Source File SOURCE=".\src\bulletmlparser-tinyxml.cpp" # End Source File # Begin Source File SOURCE=".\src\bulletmlparser-xerces.cpp" # End Source File # Begin Source File SOURCE=".\src\bulletmlparser-ygg.cpp" # End Source File # Begin Source File SOURCE=.\src\bulletmlparser.cpp # End Source File # Begin Source File SOURCE=.\src\bulletmlrunner.cpp # End Source File # Begin Source File SOURCE=.\src\bulletmlrunnerimpl.cpp # End Source File # Begin Source File SOURCE=.\src\bulletmltree.cpp # End Source File # Begin Source File SOURCE=.\src\calc.cpp # End Source File # Begin Source File SOURCE=".\src\formula-variables.cpp" # End Source File # End Group # Begin Group "TinyXML src" # PROP Default_Filter "" # Begin Source File SOURCE=.\src\tinyxml\tinyxml.cpp # End Source File # Begin Source File SOURCE=.\src\tinyxml\tinyxmlerror.cpp # End Source File # Begin Source File SOURCE=.\src\tinyxml\tinyxmlparser.cpp # End Source File # End Group # Begin Group "ygg src" # PROP Default_Filter "" # Begin Source File SOURCE=.\src\ygg\ygg.cpp # End Source File # End Group # End Group # Begin Group "Header Files" # PROP Default_Filter "h;hpp;hxx;hm;inl" # Begin Group "libBulletML header" # PROP Default_Filter "" # Begin Source File SOURCE=.\src\auto_ptr_fix.h # End Source File # Begin Source File SOURCE=.\src\bulletmlcommon.h # End Source File # Begin Source File SOURCE=.\src\bulletmlerror.h # End Source File # Begin Source File SOURCE=".\src\bulletmlparser-tinyxml.h" # End Source File # Begin Source File SOURCE=".\src\bulletmlparser-xerces.h" # End Source File # Begin Source File SOURCE=".\src\bulletmlparser-ygg.h" # End Source File # Begin Source File SOURCE=.\src\bulletmlparser.h # End Source File # Begin Source File SOURCE=.\src\bulletmlrunner.h # End Source File # Begin Source File SOURCE=.\src\bulletmlrunnerimpl.h # End Source File # Begin Source File SOURCE=.\src\bulletmltree.h # End Source File # Begin Source File SOURCE=.\src\calc.h # End Source File # Begin Source File SOURCE=".\src\formula-variables.h" # End Source File # Begin Source File SOURCE=.\src\formula.h # End Source File # Begin Source File SOURCE=.\src\tree.h # End Source File # End Group # Begin Group "TinyXML header" # PROP Default_Filter "" # Begin Source File SOURCE=.\src\tinyxml\tinyxml.h # End Source File # End Group # Begin Group "ygg header" # PROP Default_Filter "" # Begin Source File SOURCE=.\src\ygg\ygg.h # End Source File # End Group # End Group # End Target # End Project bulletml/src/0000755000076400007640000000000010664634273010430 5ustar bulletml/src/formula-variables.cpp0000644000076400007640000000020107726413361014536 0ustar #include "formula-variables.h" namespace Variables { double rank; std::vector* parameters; BulletMLRunner* runner; } bulletml/src/bulletmlparser-ygg.cpp0000644000076400007640000000432707726413361014761 0ustar #include "bulletmlparser.h" #include "bulletmlparser-ygg.h" #include "bulletmlerror.h" #include "bulletmltree.h" #include "ygg/ygg.h" #include #include using namespace yggdrasil; void BulletMLParserYggdrasil::on_error(yggdrasil::ygg_error* parse_error) { if (parse_error->is_error()) { char buf[2000]; sprintf(buf, "BulletML sox error !!!\n" "\tlocation %d:%d\n" "\tcode %02x:%02x:%02x:%02x\n" "\tmessage %s\n", parse_error->get_line(), parse_error->get_row(), parse_error->get_genre(), parse_error->get_category(), parse_error->get_sequence(), parse_error->get_sequence_case(), parse_error->get_message().c_str()); throw BulletMLError(buf); } } void BulletMLParserYggdrasil::start_document(yggdrasil::ygg_node) { } void BulletMLParserYggdrasil::end_document(yggdrasil::ygg_node&) { } void BulletMLParserYggdrasil::start_element(yggdrasil::ygg_node element) { BulletMLNode* xmlNode = addContent(trimString(element.get_name())); if (xmlNode->getName() != BulletMLNode::bulletml) { MyAttributes mattr; for (ygg_iterator ite = element["@*"].begin(); ite.is_not_end(); ++ite) { mattr.push_back(trimString(ite->get_name())); mattr.push_back(trimString(ite->get_value())); } if (!mattr.empty()) addAttribute(mattr, xmlNode); if (curNode_ != 0) curNode_->addChild(xmlNode); } curNode_ = xmlNode; } void BulletMLParserYggdrasil::end_element(yggdrasil::ygg_node element) { // @todo if (element.get_name() != curNode_ if (curNode_ != 0) curNode_ = curNode_->getParent(); } void BulletMLParserYggdrasil::catch_text(yggdrasil::ygg_node text) { curNode_->setValue(trimString(text.get_text())); } BulletMLParserYggdrasil::BulletMLParserYggdrasil(const std::string& filename) : xmlFile_(filename), curNode_(0) { setName(filename); } BulletMLParserYggdrasil::~BulletMLParserYggdrasil() {} void BulletMLParserYggdrasil::parse() { sox_file(xmlFile_).read(this); } std::string BulletMLParserYggdrasil::trimString(const std::string& str) { std::string ret(str); if (!ret.empty() && ret[0] == ' ') ret.erase(0, ret.find_first_not_of(' ')); if (!ret.empty() && ret[str.length()-1] == ' ') ret.erase(ret.find_last_not_of(' ') + 1); return ret; } bulletml/src/calc.cpp0000644000076400007640000006513607726413361012047 0ustar /* A Bison parser, made from calc.yy by GNU Bison version 1.28 */ #define YYBISON 1 /* Identify Bison output. */ #define NUM 257 #define RAND 258 #define RANK 259 #define PARAM 260 #define NEG 261 #line 3 "calc.yy" typedef double NumType; #define YYSTYPE double #define YYERROR_VERBOSE #include #include #include #include #include "calc.h" #include "formula.h" #include "formula-variables.h" int yyerror(char* s); int yylex(); const char* yyinStr; typedef Formula CalcFormula; typedef Number CalcNumber; typedef Random CalcRandom; typedef Rank CalcRank; typedef Param CalcParam; typedef Operator CalcOperator; namespace { CalcFormula* formula; std::vector formulas; CalcFormula* f(double d) { return formulas[(int)d]; } int paramId; } #ifndef YYSTYPE #define YYSTYPE int #endif #include #ifndef __cplusplus #ifndef __STDC__ #define const #endif #endif #define YYFINAL 24 #define YYFLAG -32768 #define YYNTBASE 16 #define YYTRANSLATE(x) ((unsigned)(x) <= 261 ? yytranslate[x] : 19) static const char yytranslate[] = { 0, 2, 2, 2, 2, 2, 2, 2, 2, 2, 13, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 14, 15, 9, 8, 2, 7, 2, 10, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 12, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 1, 3, 4, 5, 6, 11 }; #if YYDEBUG != 0 static const short yyprhs[] = { 0, 0, 1, 4, 6, 9, 11, 13, 15, 17, 21, 25, 29, 33, 36 }; static const short yyrhs[] = { -1, 16, 17, 0, 13, 0, 18, 13, 0, 3, 0, 4, 0, 5, 0, 6, 0, 18, 8, 18, 0, 18, 7, 18, 0, 18, 9, 18, 0, 18, 10, 18, 0, 7, 18, 0, 14, 18, 15, 0 }; #endif #if YYDEBUG != 0 static const short yyrline[] = { 0, 51, 52, 55, 56, 59, 63, 67, 71, 75, 79, 83, 87, 91, 95 }; #endif #if YYDEBUG != 0 || defined (YYERROR_VERBOSE) static const char * const yytname[] = { "$","error","$undefined.","NUM","RAND", "RANK","PARAM","'-'","'+'","'*'","'/'","NEG","'^'","'\\n'","'('","')'","input", "line","exp", NULL }; #endif static const short yyr1[] = { 0, 16, 16, 17, 17, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18 }; static const short yyr2[] = { 0, 0, 2, 1, 2, 1, 1, 1, 1, 3, 3, 3, 3, 2, 3 }; static const short yydefact[] = { 1, 0, 5, 6, 7, 8, 0, 3, 0, 2, 0, 13, 0, 0, 0, 0, 0, 4, 14, 10, 9, 11, 12, 0, 0 }; static const short yydefgoto[] = { 1, 9, 10 }; static const short yypact[] = {-32768, 0,-32768,-32768,-32768,-32768, 5,-32768, 5,-32768, 23, -32768, 19, 5, 5, 5, 5,-32768,-32768, -8, -8, -32768,-32768, 16,-32768 }; static const short yypgoto[] = {-32768, -32768, 9 }; #define YYLAST 36 static const short yytable[] = { 23, 15, 16, 2, 3, 4, 5, 6, 2, 3, 4, 5, 6, 7, 8, 11, 24, 12, 0, 8, 0, 0, 19, 20, 21, 22, 13, 14, 15, 16, 13, 14, 15, 16, 18, 0, 17 }; static const short yycheck[] = { 0, 9, 10, 3, 4, 5, 6, 7, 3, 4, 5, 6, 7, 13, 14, 6, 0, 8, -1, 14, -1, -1, 13, 14, 15, 16, 7, 8, 9, 10, 7, 8, 9, 10, 15, -1, 13 }; /* -*-C-*- Note some compilers choke on comments on `#line' lines. */ #line 3 "/usr/lib/bison.simple" /* This file comes from bison-1.28. */ /* Skeleton output parser for bison, Copyright (C) 1984, 1989, 1990 Free Software Foundation, Inc. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ /* As a special exception, when this file is copied by Bison into a Bison output file, you may use that output file without restriction. This special exception was added by the Free Software Foundation in version 1.24 of Bison. */ /* This is the parser code that is written into each bison parser when the %semantic_parser declaration is not specified in the grammar. It was written by Richard Stallman by simplifying the hairy parser used when %semantic_parser is specified. */ #ifndef YYSTACK_USE_ALLOCA #ifdef alloca #define YYSTACK_USE_ALLOCA #else /* alloca not defined */ #ifdef __GNUC__ #define YYSTACK_USE_ALLOCA #define alloca __builtin_alloca #else /* not GNU C. */ #if (!defined (__STDC__) && defined (sparc)) || defined (__sparc__) || defined (__sparc) || defined (__sgi) || (defined (__sun) && defined (__i386)) #define YYSTACK_USE_ALLOCA #include #else /* not sparc */ /* We think this test detects Watcom and Microsoft C. */ /* This used to test MSDOS, but that is a bad idea since that symbol is in the user namespace. */ #if (defined (_MSDOS) || defined (_MSDOS_)) && !defined (__TURBOC__) #if 0 /* No need for malloc.h, which pollutes the namespace; instead, just don't use alloca. */ #include #endif #else /* not MSDOS, or __TURBOC__ */ #if defined(_AIX) /* I don't know what this was needed for, but it pollutes the namespace. So I turned it off. rms, 2 May 1997. */ /* #include */ #pragma alloca #define YYSTACK_USE_ALLOCA #else /* not MSDOS, or __TURBOC__, or _AIX */ #if 0 #ifdef __hpux /* haible@ilog.fr says this works for HPUX 9.05 and up, and on HPUX 10. Eventually we can turn this on. */ #define YYSTACK_USE_ALLOCA #define alloca __builtin_alloca #endif /* __hpux */ #endif #endif /* not _AIX */ #endif /* not MSDOS, or __TURBOC__ */ #endif /* not sparc */ #endif /* not GNU C */ #endif /* alloca not defined */ #endif /* YYSTACK_USE_ALLOCA not defined */ #ifdef YYSTACK_USE_ALLOCA #define YYSTACK_ALLOC alloca #else #define YYSTACK_ALLOC malloc #endif /* Note: there must be only one dollar sign in this file. It is replaced by the list of actions, each action as one case of the switch. */ #define yyerrok (yyerrstatus = 0) #define yyclearin (yychar = YYEMPTY) #define YYEMPTY -2 #define YYEOF 0 #define YYACCEPT goto yyacceptlab #define YYABORT goto yyabortlab #define YYERROR goto yyerrlab1 /* Like YYERROR except do call yyerror. This remains here temporarily to ease the transition to the new meaning of YYERROR, for GCC. Once GCC version 2 has supplanted version 1, this can go. */ #define YYFAIL goto yyerrlab #define YYRECOVERING() (!!yyerrstatus) #define YYBACKUP(token, value) \ do \ if (yychar == YYEMPTY && yylen == 1) \ { yychar = (token), yylval = (value); \ yychar1 = YYTRANSLATE (yychar); \ YYPOPSTACK; \ goto yybackup; \ } \ else \ { yyerror ("syntax error: cannot back up"); YYERROR; } \ while (0) #define YYTERROR 1 #define YYERRCODE 256 #ifndef YYPURE #define YYLEX yylex() #endif #ifdef YYPURE #ifdef YYLSP_NEEDED #ifdef YYLEX_PARAM #define YYLEX yylex(&yylval, &yylloc, YYLEX_PARAM) #else #define YYLEX yylex(&yylval, &yylloc) #endif #else /* not YYLSP_NEEDED */ #ifdef YYLEX_PARAM #define YYLEX yylex(&yylval, YYLEX_PARAM) #else #define YYLEX yylex(&yylval) #endif #endif /* not YYLSP_NEEDED */ #endif /* If nonreentrant, generate the variables here */ #ifndef YYPURE int yychar; /* the lookahead symbol */ YYSTYPE yylval; /* the semantic value of the */ /* lookahead symbol */ #ifdef YYLSP_NEEDED YYLTYPE yylloc; /* location data for the lookahead */ /* symbol */ #endif int yynerrs; /* number of parse errors so far */ #endif /* not YYPURE */ #if YYDEBUG != 0 int yydebug; /* nonzero means print parse trace */ /* Since this is uninitialized, it does not stop multiple parsers from coexisting. */ #endif /* YYINITDEPTH indicates the initial size of the parser's stacks */ #ifndef YYINITDEPTH #define YYINITDEPTH 200 #endif /* YYMAXDEPTH is the maximum size the stacks can grow to (effective only if the built-in stack extension method is used). */ #if YYMAXDEPTH == 0 #undef YYMAXDEPTH #endif #ifndef YYMAXDEPTH #define YYMAXDEPTH 10000 #endif /* Define __yy_memcpy. Note that the size argument should be passed with type unsigned int, because that is what the non-GCC definitions require. With GCC, __builtin_memcpy takes an arg of type size_t, but it can handle unsigned int. */ #if __GNUC__ > 1 /* GNU C and GNU C++ define this. */ #define __yy_memcpy(TO,FROM,COUNT) __builtin_memcpy(TO,FROM,COUNT) #else /* not GNU C or C++ */ #ifndef __cplusplus /* This is the most reliable way to avoid incompatibilities in available built-in functions on various systems. */ static void __yy_memcpy (to, from, count) char *to; char *from; unsigned int count; { register char *f = from; register char *t = to; register int i = count; while (i-- > 0) *t++ = *f++; } #else /* __cplusplus */ /* This is the most reliable way to avoid incompatibilities in available built-in functions on various systems. */ static void __yy_memcpy (char *to, char *from, unsigned int count) { register char *t = to; register char *f = from; register int i = count; while (i-- > 0) *t++ = *f++; } #endif #endif #line 217 "/usr/lib/bison.simple" /* The user can define YYPARSE_PARAM as the name of an argument to be passed into yyparse. The argument should have type void *. It should actually point to an object. Grammar actions can access the variable by casting it to the proper pointer type. */ #ifdef YYPARSE_PARAM #ifdef __cplusplus #define YYPARSE_PARAM_ARG void *YYPARSE_PARAM #define YYPARSE_PARAM_DECL #else /* not __cplusplus */ #define YYPARSE_PARAM_ARG YYPARSE_PARAM #define YYPARSE_PARAM_DECL void *YYPARSE_PARAM; #endif /* not __cplusplus */ #else /* not YYPARSE_PARAM */ #define YYPARSE_PARAM_ARG #define YYPARSE_PARAM_DECL #endif /* not YYPARSE_PARAM */ /* Prevent warning if -Wstrict-prototypes. */ #ifdef __GNUC__ #ifdef YYPARSE_PARAM int yyparse (void *); #else int yyparse (void); #endif #endif int yyparse(YYPARSE_PARAM_ARG) YYPARSE_PARAM_DECL { register int yystate; register int yyn; register short *yyssp; register YYSTYPE *yyvsp; int yyerrstatus; /* number of tokens to shift before error messages enabled */ int yychar1 = 0; /* lookahead token as an internal (translated) token number */ short yyssa[YYINITDEPTH]; /* the state stack */ YYSTYPE yyvsa[YYINITDEPTH]; /* the semantic value stack */ short *yyss = yyssa; /* refer to the stacks thru separate pointers */ YYSTYPE *yyvs = yyvsa; /* to allow yyoverflow to reallocate them elsewhere */ #ifdef YYLSP_NEEDED YYLTYPE yylsa[YYINITDEPTH]; /* the location stack */ YYLTYPE *yyls = yylsa; YYLTYPE *yylsp; #define YYPOPSTACK (yyvsp--, yyssp--, yylsp--) #else #define YYPOPSTACK (yyvsp--, yyssp--) #endif int yystacksize = YYINITDEPTH; int yyfree_stacks = 0; #ifdef YYPURE int yychar; YYSTYPE yylval; int yynerrs; #ifdef YYLSP_NEEDED YYLTYPE yylloc; #endif #endif YYSTYPE yyval; /* the variable used to return */ /* semantic values from the action */ /* routines */ int yylen; #if YYDEBUG != 0 if (yydebug) fprintf(stderr, "Starting parse\n"); #endif yystate = 0; yyerrstatus = 0; yynerrs = 0; yychar = YYEMPTY; /* Cause a token to be read. */ /* Initialize stack pointers. Waste one element of value and location stack so that they stay on the same level as the state stack. The wasted elements are never initialized. */ yyssp = yyss - 1; yyvsp = yyvs; #ifdef YYLSP_NEEDED yylsp = yyls; #endif /* Push a new state, which is found in yystate . */ /* In all cases, when you get here, the value and location stacks have just been pushed. so pushing a state here evens the stacks. */ yynewstate: *++yyssp = yystate; if (yyssp >= yyss + yystacksize - 1) { /* Give user a chance to reallocate the stack */ /* Use copies of these so that the &'s don't force the real ones into memory. */ YYSTYPE *yyvs1 = yyvs; short *yyss1 = yyss; #ifdef YYLSP_NEEDED YYLTYPE *yyls1 = yyls; #endif /* Get the current used size of the three stacks, in elements. */ int size = yyssp - yyss + 1; #ifdef yyoverflow /* Each stack pointer address is followed by the size of the data in use in that stack, in bytes. */ #ifdef YYLSP_NEEDED /* This used to be a conditional around just the two extra args, but that might be undefined if yyoverflow is a macro. */ yyoverflow("parser stack overflow", &yyss1, size * sizeof (*yyssp), &yyvs1, size * sizeof (*yyvsp), &yyls1, size * sizeof (*yylsp), &yystacksize); #else yyoverflow("parser stack overflow", &yyss1, size * sizeof (*yyssp), &yyvs1, size * sizeof (*yyvsp), &yystacksize); #endif yyss = yyss1; yyvs = yyvs1; #ifdef YYLSP_NEEDED yyls = yyls1; #endif #else /* no yyoverflow */ /* Extend the stack our own way. */ if (yystacksize >= YYMAXDEPTH) { yyerror("parser stack overflow"); if (yyfree_stacks) { free (yyss); free (yyvs); #ifdef YYLSP_NEEDED free (yyls); #endif } return 2; } yystacksize *= 2; if (yystacksize > YYMAXDEPTH) yystacksize = YYMAXDEPTH; #ifndef YYSTACK_USE_ALLOCA yyfree_stacks = 1; #endif yyss = (short *) YYSTACK_ALLOC (yystacksize * sizeof (*yyssp)); __yy_memcpy ((char *)yyss, (char *)yyss1, size * (unsigned int) sizeof (*yyssp)); yyvs = (YYSTYPE *) YYSTACK_ALLOC (yystacksize * sizeof (*yyvsp)); __yy_memcpy ((char *)yyvs, (char *)yyvs1, size * (unsigned int) sizeof (*yyvsp)); #ifdef YYLSP_NEEDED yyls = (YYLTYPE *) YYSTACK_ALLOC (yystacksize * sizeof (*yylsp)); __yy_memcpy ((char *)yyls, (char *)yyls1, size * (unsigned int) sizeof (*yylsp)); #endif #endif /* no yyoverflow */ yyssp = yyss + size - 1; yyvsp = yyvs + size - 1; #ifdef YYLSP_NEEDED yylsp = yyls + size - 1; #endif #if YYDEBUG != 0 if (yydebug) fprintf(stderr, "Stack size increased to %d\n", yystacksize); #endif if (yyssp >= yyss + yystacksize - 1) YYABORT; } #if YYDEBUG != 0 if (yydebug) fprintf(stderr, "Entering state %d\n", yystate); #endif goto yybackup; yybackup: /* Do appropriate processing given the current state. */ /* Read a lookahead token if we need one and don't already have one. */ /* yyresume: */ /* First try to decide what to do without reference to lookahead token. */ yyn = yypact[yystate]; if (yyn == YYFLAG) goto yydefault; /* Not known => get a lookahead token if don't already have one. */ /* yychar is either YYEMPTY or YYEOF or a valid token in external form. */ if (yychar == YYEMPTY) { #if YYDEBUG != 0 if (yydebug) fprintf(stderr, "Reading a token: "); #endif yychar = YYLEX; } /* Convert token to internal form (in yychar1) for indexing tables with */ if (yychar <= 0) /* This means end of input. */ { yychar1 = 0; yychar = YYEOF; /* Don't call YYLEX any more */ #if YYDEBUG != 0 if (yydebug) fprintf(stderr, "Now at end of input.\n"); #endif } else { yychar1 = YYTRANSLATE(yychar); #if YYDEBUG != 0 if (yydebug) { fprintf (stderr, "Next token is %d (%s", yychar, yytname[yychar1]); /* Give the individual parser a way to print the precise meaning of a token, for further debugging info. */ #ifdef YYPRINT YYPRINT (stderr, yychar, yylval); #endif fprintf (stderr, ")\n"); } #endif } yyn += yychar1; if (yyn < 0 || yyn > YYLAST || yycheck[yyn] != yychar1) goto yydefault; yyn = yytable[yyn]; /* yyn is what to do for this token type in this state. Negative => reduce, -yyn is rule number. Positive => shift, yyn is new state. New state is final state => don't bother to shift, just return success. 0, or most negative number => error. */ if (yyn < 0) { if (yyn == YYFLAG) goto yyerrlab; yyn = -yyn; goto yyreduce; } else if (yyn == 0) goto yyerrlab; if (yyn == YYFINAL) YYACCEPT; /* Shift the lookahead token. */ #if YYDEBUG != 0 if (yydebug) fprintf(stderr, "Shifting token %d (%s), ", yychar, yytname[yychar1]); #endif /* Discard the token being shifted unless it is eof. */ if (yychar != YYEOF) yychar = YYEMPTY; *++yyvsp = yylval; #ifdef YYLSP_NEEDED *++yylsp = yylloc; #endif /* count tokens shifted since error; after three, turn off error status. */ if (yyerrstatus) yyerrstatus--; yystate = yyn; goto yynewstate; /* Do the default action for the current state. */ yydefault: yyn = yydefact[yystate]; if (yyn == 0) goto yyerrlab; /* Do a reduction. yyn is the number of a rule to reduce with. */ yyreduce: yylen = yyr2[yyn]; if (yylen > 0) yyval = yyvsp[1-yylen]; /* implement default value of the action */ #if YYDEBUG != 0 if (yydebug) { int i; fprintf (stderr, "Reducing via rule %d (line %d), ", yyn, yyrline[yyn]); /* Print the symbols being reduced, and their result. */ for (i = yyprhs[yyn]; yyrhs[i] > 0; i++) fprintf (stderr, "%s ", yytname[yyrhs[i]]); fprintf (stderr, " -> %s\n", yytname[yyr1[yyn]]); } #endif switch (yyn) { case 4: #line 56 "calc.yy" { formula = f(yyvsp[-1]); return 0; ; break;} case 5: #line 59 "calc.yy" { yyval = formulas.size(); formulas.push_back(new CalcFormula(new CalcNumber(yyvsp[0]))); ; break;} case 6: #line 63 "calc.yy" { yyval = formulas.size(); formulas.push_back(new CalcFormula(new CalcRandom())); ; break;} case 7: #line 67 "calc.yy" { yyval = formulas.size(); formulas.push_back(new CalcFormula(new CalcRank())); ; break;} case 8: #line 71 "calc.yy" { yyval = formulas.size(); formulas.push_back(new CalcFormula(new CalcParam(paramId))); ; break;} case 9: #line 75 "calc.yy" { yyval = formulas.size(); formulas.push_back(new CalcFormula(f(yyvsp[-2]), op_add, f(yyvsp[0]))); ; break;} case 10: #line 79 "calc.yy" { yyval = formulas.size(); formulas.push_back(new CalcFormula(f(yyvsp[-2]), op_sub, f(yyvsp[0]))); ; break;} case 11: #line 83 "calc.yy" { yyval = formulas.size(); formulas.push_back(new CalcFormula(f(yyvsp[-2]), op_mul, f(yyvsp[0]))); ; break;} case 12: #line 87 "calc.yy" { yyval = formulas.size(); formulas.push_back(new CalcFormula(f(yyvsp[-2]), op_div, f(yyvsp[0]))); ; break;} case 13: #line 91 "calc.yy" { yyval = yyvsp[0]; f(yyvsp[0])->setHeadSub(); ; break;} case 14: #line 95 "calc.yy" { yyval = yyvsp[-1]; ; break;} } /* the action file gets copied in in place of this dollarsign */ #line 543 "/usr/lib/bison.simple" yyvsp -= yylen; yyssp -= yylen; #ifdef YYLSP_NEEDED yylsp -= yylen; #endif #if YYDEBUG != 0 if (yydebug) { short *ssp1 = yyss - 1; fprintf (stderr, "state stack now"); while (ssp1 != yyssp) fprintf (stderr, " %d", *++ssp1); fprintf (stderr, "\n"); } #endif *++yyvsp = yyval; #ifdef YYLSP_NEEDED yylsp++; if (yylen == 0) { yylsp->first_line = yylloc.first_line; yylsp->first_column = yylloc.first_column; yylsp->last_line = (yylsp-1)->last_line; yylsp->last_column = (yylsp-1)->last_column; yylsp->text = 0; } else { yylsp->last_line = (yylsp+yylen-1)->last_line; yylsp->last_column = (yylsp+yylen-1)->last_column; } #endif /* Now "shift" the result of the reduction. Determine what state that goes to, based on the state we popped back to and the rule number reduced by. */ yyn = yyr1[yyn]; yystate = yypgoto[yyn - YYNTBASE] + *yyssp; if (yystate >= 0 && yystate <= YYLAST && yycheck[yystate] == *yyssp) yystate = yytable[yystate]; else yystate = yydefgoto[yyn - YYNTBASE]; goto yynewstate; yyerrlab: /* here on detecting error */ if (! yyerrstatus) /* If not already recovering from an error, report this error. */ { ++yynerrs; #ifdef YYERROR_VERBOSE yyn = yypact[yystate]; if (yyn > YYFLAG && yyn < YYLAST) { int size = 0; char *msg; int x, count; count = 0; /* Start X at -yyn if nec to avoid negative indexes in yycheck. */ for (x = (yyn < 0 ? -yyn : 0); x < (sizeof(yytname) / sizeof(char *)); x++) if (yycheck[x + yyn] == x) size += strlen(yytname[x]) + 15, count++; msg = (char *) malloc(size + 15); if (msg != 0) { strcpy(msg, "parse error"); if (count < 5) { count = 0; for (x = (yyn < 0 ? -yyn : 0); x < (sizeof(yytname) / sizeof(char *)); x++) if (yycheck[x + yyn] == x) { strcat(msg, count == 0 ? ", expecting `" : " or `"); strcat(msg, yytname[x]); strcat(msg, "'"); count++; } } yyerror(msg); free(msg); } else yyerror ("parse error; also virtual memory exceeded"); } else #endif /* YYERROR_VERBOSE */ yyerror("parse error"); } goto yyerrlab1; yyerrlab1: /* here on error raised explicitly by an action */ if (yyerrstatus == 3) { /* if just tried and failed to reuse lookahead token after an error, discard it. */ /* return failure if at end of input */ if (yychar == YYEOF) YYABORT; #if YYDEBUG != 0 if (yydebug) fprintf(stderr, "Discarding token %d (%s).\n", yychar, yytname[yychar1]); #endif yychar = YYEMPTY; } /* Else will try to reuse lookahead token after shifting the error token. */ yyerrstatus = 3; /* Each real token shifted decrements this */ goto yyerrhandle; yyerrdefault: /* current state does not do anything special for the error token. */ #if 0 /* This is wrong; only states that explicitly want error tokens should shift them. */ yyn = yydefact[yystate]; /* If its default is to accept any token, ok. Otherwise pop it.*/ if (yyn) goto yydefault; #endif yyerrpop: /* pop the current state because it cannot handle the error token */ if (yyssp == yyss) YYABORT; yyvsp--; yystate = *--yyssp; #ifdef YYLSP_NEEDED yylsp--; #endif #if YYDEBUG != 0 if (yydebug) { short *ssp1 = yyss - 1; fprintf (stderr, "Error: state stack now"); while (ssp1 != yyssp) fprintf (stderr, " %d", *++ssp1); fprintf (stderr, "\n"); } #endif yyerrhandle: yyn = yypact[yystate]; if (yyn == YYFLAG) goto yyerrdefault; yyn += YYTERROR; if (yyn < 0 || yyn > YYLAST || yycheck[yyn] != YYTERROR) goto yyerrdefault; yyn = yytable[yyn]; if (yyn < 0) { if (yyn == YYFLAG) goto yyerrpop; yyn = -yyn; goto yyreduce; } else if (yyn == 0) goto yyerrpop; if (yyn == YYFINAL) YYACCEPT; #if YYDEBUG != 0 if (yydebug) fprintf(stderr, "Shifting error token, "); #endif *++yyvsp = yylval; #ifdef YYLSP_NEEDED *++yylsp = yylloc; #endif yystate = yyn; goto yynewstate; yyacceptlab: /* YYACCEPT comes here. */ if (yyfree_stacks) { free (yyss); free (yyvs); #ifdef YYLSP_NEEDED free (yyls); #endif } return 0; yyabortlab: /* YYABORT comes here. */ if (yyfree_stacks) { free (yyss); free (yyvs); #ifdef YYLSP_NEEDED free (yyls); #endif } return 1; } #line 99 "calc.yy" /** * AlAdouble^lX^bN * g[NuNUMvAlOAAXL[B * ^uBt@CI0B */ #include #include int yylex () { int c; /* */ while ((c = *(yyinStr++)) == ' ' || c == '\t') ; /* l */ if (c == '.' || isdigit (c)) { yyinStr--; sscanf (yyinStr, "%lf", &yylval); while ((c = *(++yyinStr)) == '.' || isdigit(c)) {} return NUM; } // */ if (c == '$') { if (strncmp(yyinStr, "rand", 4) == 0) { yyinStr += 4; return RAND; } else if (strncmp(yyinStr, "rank", 4) == 0) { yyinStr += 4; return RANK; } else { std::istringstream iss(std::string(yyinStr).substr(0, 1)); iss >> paramId; yyinStr++; return PARAM; } } /* t@CI */ if (c == '\0') return 0; /* 1 */ return c; } int yyerror(char* s) { printf("yyerror: %s\n", s); return 0; } std::auto_ptr calc(const std::string& str) { std::string fml = str + '\n'; yyinStr = fml.c_str(); yyparse(); return std::auto_ptr(formula); } bulletml/src/bulletmlcommon.h0000644000076400007640000000026407726413362013633 0ustar #ifndef bulletmlcommon_h_ #define bulletmlcommon_h_ #ifdef WIN32_DLL_EXPORT # define DECLSPEC __declspec(dllexport) #else # define DECLSPEC #endif #endif // ! bulletmlcommon_h_ bulletml/src/bulletmlerror.h0000644000076400007640000000125607726413362013476 0ustar #ifndef BULLETMLERROR_H_ #define BULLETMLERROR_H_ #include "bulletmlcommon.h" #include /// [タ class BulletMLError : public std::runtime_error { public: DECLSPEC BulletMLError(const std::string& msg) : std::runtime_error(msg) {} DECLSPEC static void doAssert(const char* str) { throw BulletMLError(str); } DECLSPEC static void doAssert(const std::string& str) { throw BulletMLError(str); } DECLSPEC static void doAssert(bool t, const char* str) { if (!t) throw BulletMLError(str); } DECLSPEC static void doAssert(bool t, const std::string& str) { if (!t) throw BulletMLError(str); } }; #endif // ! BULLETMLERROR_H_ bulletml/src/bulletmlparser-tinyxml.cpp0000644000076400007640000000346207726413361015676 0ustar #include "bulletmlparser.h" #include "bulletmlparser-tinyxml.h" #include "bulletmlerror.h" #include "bulletmltree.h" #include BulletMLParserTinyXML::BulletMLParserTinyXML(const std::string& filename) : xmlFile_(filename), curNode_(0) { setName(filename); } BulletMLParserTinyXML::~BulletMLParserTinyXML() {} void BulletMLParserTinyXML::getTree(TiXmlNode* node) { if (node->ToComment() != 0) return; translateNode(node); TiXmlNode* child; for (child = node->FirstChild(); child; child = child->NextSibling()) { TiXmlText* text; if ((text = child->ToText()) != 0) { curNode_->setValue(text->Value()); break; } getTree(child); } curNode_ = curNode_->getParent(); } void BulletMLParserTinyXML::translateNode(TiXmlNode* node) { TiXmlElement* elem = node->ToElement(); assert(elem != 0); BulletMLNode* xmlNode = addContent(elem->Value()); if (xmlNode->getName() == BulletMLNode::bulletml) { TiXmlAttribute* attr; for (attr = elem->FirstAttribute(); attr; attr = attr->Next()) { if (attr->Value() == "horizontal") setHorizontal(); } } else { MyAttributes mattr; TiXmlAttribute* attr; for (attr = elem->FirstAttribute(); attr; attr = attr->Next()) { mattr.push_back(attr->Name()); mattr.push_back(attr->Value()); } addAttribute(mattr, xmlNode); if (curNode_ != 0) curNode_->addChild(xmlNode); } curNode_ = xmlNode; } void BulletMLParserTinyXML::parseImpl(TiXmlDocument& doc) { if (doc.Error()) { throw BulletMLError(doc.Value() + ": " + doc.ErrorDesc()); } TiXmlNode* node; for (node = doc.FirstChild(); node; node = node->NextSibling()) { if (node->ToElement() != 0) { getTree(node); break; } } } void BulletMLParserTinyXML::parse() { TiXmlDocument doc(xmlFile_.c_str()); doc.LoadFile(); parseImpl(doc); } bulletml/src/calc.yy0000644000076400007640000000621307714245610011712 0ustar /* 中間記法電卓 -- calc */ %{ typedef double NumType; #define YYSTYPE double #define YYERROR_VERBOSE #include #include #include #include #include "calc.h" #include "formula.h" #include "formula-variables.h" int yyerror(char* s); int yylex(); const char* yyinStr; typedef Formula CalcFormula; typedef Number CalcNumber; typedef Random CalcRandom; typedef Rank CalcRank; typedef Param CalcParam; typedef Operator CalcOperator; namespace { CalcFormula* formula; std::vector formulas; CalcFormula* f(double d) { return formulas[(int)d]; } int paramId; } %} /* BISON宣言 */ %token NUM RAND RANK PARAM %left '-' '+' %left '*' '/' %left NEG /* negation--単項マイナス */ %right '^' /* べき乗関数 */ /* 文法規則が続く */ %% input: /* 空文字列 */ | input line ; line: '\n' | exp '\n' { formula = f($1); return 0; } ; exp: NUM { $$ = formulas.size(); formulas.push_back(new CalcFormula(new CalcNumber($1))); } | RAND { $$ = formulas.size(); formulas.push_back(new CalcFormula(new CalcRandom())); } | RANK { $$ = formulas.size(); formulas.push_back(new CalcFormula(new CalcRank())); } | PARAM { $$ = formulas.size(); formulas.push_back(new CalcFormula(new CalcParam(paramId))); } | exp '+' exp { $$ = formulas.size(); formulas.push_back(new CalcFormula(f($1), op_add, f($3))); } | exp '-' exp { $$ = formulas.size(); formulas.push_back(new CalcFormula(f($1), op_sub, f($3))); } | exp '*' exp { $$ = formulas.size(); formulas.push_back(new CalcFormula(f($1), op_mul, f($3))); } | exp '/' exp { $$ = formulas.size(); formulas.push_back(new CalcFormula(f($1), op_div, f($3))); } | '-' exp %prec NEG { $$ = $2; f($2)->setHeadSub(); } | '(' exp ')' { $$ = $2; } ; %% /** * 字句解析器は、数値を読めば、double型の値をスタックに積んで * トークン「NUM」を返し、数値以外を読めば、その文字のアスキー符号を返す。 * 空白とタブは読み飛ばされる。ファイルが終わると0を返す。 */ #include #include int yylex () { int c; /* 空白類を読み飛ばす */ while ((c = *(yyinStr++)) == ' ' || c == '\t') ; /* 数値を処理する */ if (c == '.' || isdigit (c)) { yyinStr--; sscanf (yyinStr, "%lf", &yylval); while ((c = *(++yyinStr)) == '.' || isdigit(c)) {} return NUM; } // 変数を処理する */ if (c == '$') { if (strncmp(yyinStr, "rand", 4) == 0) { yyinStr += 4; return RAND; } else if (strncmp(yyinStr, "rank", 4) == 0) { yyinStr += 4; return RANK; } else { std::istringstream iss(std::string(yyinStr).substr(0, 1)); iss >> paramId; yyinStr++; return PARAM; } } /* ファイルの終わりを処理する */ if (c == '\0') return 0; /* 1文字を返す */ return c; } int yyerror(char* s) { printf("yyerror: %s\n", s); return 0; } std::auto_ptr calc(const std::string& str) { std::string fml = str + '\n'; yyinStr = fml.c_str(); yyparse(); return std::auto_ptr(formula); } bulletml/src/tree.h0000644000076400007640000000346507726413362011547 0ustar /// Ic[BY #ifndef TREE_H_ #define TREE_H_ #include "bulletmlcommon.h" #include /// c[NX /** * c[ReiWvB * Am[hNXWReiB * C^[tFCXA * class YourNode : public TreeNode; * B * |C^OB * CX^XiA * setReleaseDuty m[hjA * qSjB */ template class TreeNode { public: // ev[gv typedef std::list Children; typedef typename Children::iterator ChildIterator; typedef typename Children::const_iterator ConstChildIterator; public: DECLSPEC TreeNode() { releaseDuty_ = false; } DECLSPEC virtual ~TreeNode(); DECLSPEC void addChild(C_* c) { c->setParent(dynamic_cast(this)); children_.push_back(c); } DECLSPEC void setReleaseDuty(bool bl) { releaseDuty_ = bl; } DECLSPEC void setParent(C_* c) { parent_ = c; } DECLSPEC ChildIterator childBegin() { return children_.begin(); } DECLSPEC ChildIterator childEnd() { return children_.end(); } DECLSPEC size_t childSize() { return children_.size(); } DECLSPEC ConstChildIterator childBegin() const { return children_.begin(); } DECLSPEC ConstChildIterator childEnd() const { return children_.end(); } DECLSPEC C_* getParent() { return parent_; } private: Children children_; C_* parent_; bool releaseDuty_; }; template TreeNode::~TreeNode() { if (releaseDuty_) { ChildIterator ite; for (ite = children_.begin(); ite != children_.end(); ite++) { (*ite)->setReleaseDuty(true); delete *ite; } } } #endif // ! TREE_H_ bulletml/src/bulletmlparser.h0000644000076400007640000000405107726413362013635 0ustar /// BulletML p[T /** * c++ p RELAX ゥ */ #ifndef BULLETMLPARSER_H_ #define BULLETMLPARSER_H_ #include "bulletmltree.h" #include "bulletmlcommon.h" #include #include #include class BulletMLParser { protected: typedef std::vector MyAttributes; typedef MyAttributes::const_iterator MyAttributeIte; public: DECLSPEC BulletMLParser(); DECLSPEC virtual ~BulletMLParser(); public: DECLSPEC void build(); DECLSPEC virtual void parse() =0; public: /** * BulletML dlc[\Kv * x */ //@{ DECLSPEC BulletMLNode* getBulletRef(int id); DECLSPEC BulletMLNode* getActionRef(int id); DECLSPEC BulletMLNode* getFireRef(int id); //@} DECLSPEC const std::vector& getTopActions() const { return topActions_; } DECLSPEC void setHorizontal() { isHorizontal_ = true; } DECLSPEC bool isHorizontal() const { return isHorizontal_; } protected: BulletMLNode* addContent(const std::string& name); void addAttribute(const MyAttributes& attr, BulletMLNode* elem); protected: /// gcco[W template std::string uc2string(Char_* src, size_t len = std::string::npos); protected: BulletMLNode* bulletml_; std::vector topActions_; typedef std::vector MyMap; typedef MyMap BulletMap; typedef MyMap ActionMap; typedef MyMap FireMap; BulletMap bulletMap_; ActionMap actionMap_; FireMap fireMap_; bool isHorizontal_; protected: /// I void setName(const std::string& name) { name_ = name; } std::string name_; public: DECLSPEC const std::string& getName() const { return name_; } }; template std::string BulletMLParser::uc2string(Char_* src, size_t len) { std::string dst; size_t i = 0; while (i != len && *src != '\0') { dst += *src; src++; i++; } return dst; } #endif // ! BULLETMLPARSER_H_ bulletml/src/bulletmlparser-tinyxml.h0000644000076400007640000000130010007600311015303 0ustar /// BulletML p[TEc[ by tinyxml /** * tinyxmlBulletMLp[T */ #ifndef BULLETMLPARSER_TINYXML_H_ #define BULLETMLPARSER_TINYXML_H_ #include #include "bulletmlcommon.h" #include "tinyxml/tinyxml.h" class BulletMLNode; class BulletMLParserTinyXML : public BulletMLParser { public: DECLSPEC BulletMLParserTinyXML(const std::string& filename); DECLSPEC virtual ~BulletMLParserTinyXML(); DECLSPEC virtual void parse(); protected: void parseImpl(TiXmlDocument& doc); protected: void getTree(TiXmlNode* node); void translateNode(TiXmlNode* node); private: std::string xmlFile_; BulletMLNode* curNode_; }; #endif // ! BULLETMLPARSER_TINYXML_H_ bulletml/src/calc.h0000644000076400007640000000032307726413362011500 0ustar #ifndef CALC_H_ #define CALC_H_ #include "formula.h" #include "bulletmlcommon.h" #include #include DECLSPEC std::auto_ptr > calc(const std::string& str); #endif // CALC_H_ bulletml/src/bulletmlrunnerimpl.cpp0000644000076400007640000003153310037422656015067 0ustar #include "bulletmlrunnerimpl.h" #include "bulletmlrunner.h" #include "bulletmlparser.h" #include "bulletmlerror.h" #include "formula-variables.h" #include "auto_ptr_fix.h" #include #include BulletMLRunnerImpl::Method BulletMLRunnerImpl::commandMap_[BulletMLNode::nameSize] = { &BulletMLRunnerImpl::runBullet, &BulletMLRunnerImpl::runAction, &BulletMLRunnerImpl::runFire, &BulletMLRunnerImpl::runChangeDirection, &BulletMLRunnerImpl::runChangeSpeed, &BulletMLRunnerImpl::runAccel, &BulletMLRunnerImpl::runWait, &BulletMLRunnerImpl::runRepeat, &BulletMLRunnerImpl::runBulletRef, &BulletMLRunnerImpl::runActionRef, &BulletMLRunnerImpl::runFireRef, &BulletMLRunnerImpl::runVanish }; double BulletMLRunnerImpl::getDirection(BulletMLNode* dirNode, bool prevChange) { double dir; bool isDefault = true; dir = getNumberContents(dirNode); if (dirNode->getType() != BulletMLNode::none) { BulletMLNode::Type type = dirNode->getType(); isDefault = false; if (type == BulletMLNode::absolute) { if (bulletml_->isHorizontal()) { dir -= 90; } } else if (type == BulletMLNode::relative) { dir += runner_->getBulletDirection(); } else if (type == BulletMLNode::sequence) { if (!prevDir_.isValidate()) { dir = 0; isDefault = true; } else dir += prevDir_; } else { isDefault = true; } } if (isDefault) { // dir += runner_->getAimDirection(); } while (dir > 360) dir -= 360; while (dir < 0) dir += 360; if (prevChange) prevDir_ = dir; return dir; } double BulletMLRunnerImpl::getSpeed(BulletMLNode* spdNode) { double spd; spd = getNumberContents(spdNode); if (spdNode->getType() != BulletMLNode::none) { BulletMLNode::Type type = spdNode->getType(); if (type == BulletMLNode::relative) { spd += runner_->getBulletSpeed(); } else if (type == BulletMLNode::sequence) { if (!prevSpd_.isValidate()) spd = 1; else spd += prevSpd_; } } // ftHg prevSpd_ = spd; return spd; } BulletMLRunnerImpl::BulletMLRunnerImpl(BulletMLState* state, BulletMLRunner* runner) : bulletml_(state->getBulletML()), node_(state->getNode().begin(), state->getNode().end()), actIte_(0), end_(false), runner_(runner) { if (state->getParameter().get() != 0) { parameters_ = state->getParameter(); } delete state; for (std::vector::iterator ite = node_.begin(); ite != node_.end(); ++ite) { (*ite)->setParent(0); } /* std::for_each(node_.begin(), node_.end(), std::bind2nd(std::mem_fun(&BulletMLNode::setParent), 0)); */ actTurn_ = -1; act_ = node_[0]; } BulletMLRunnerImpl::~BulletMLRunnerImpl() { while (!repeatStack_.empty()) { delete repeatStack_.top(); repeatStack_.pop(); } } double BulletMLRunnerImpl::getNumberContents(const BulletMLNode* node) { assert(node); Variables::rank = runner_->getRank(); Variables::parameters = parameters_.get(); Variables::runner = runner_; return node->getValue(); } void BulletMLRunnerImpl::setSpeed() { BulletMLNode* spd = act_->getChild(BulletMLNode::speed); if (spd == 0) return; spd_ = getSpeed(spd); } void BulletMLRunnerImpl::setDirection() { BulletMLNode* dir = act_->getChild(BulletMLNode::direction); if (dir == 0) return; dir_ = getDirection(dir); } bool BulletMLRunnerImpl::isTurnEnd() { return isEnd() || actTurn_ > endTurn_; } void BulletMLRunnerImpl::doWait(int frame) { if (frame <= 0) return; actTurn_ += frame; } void BulletMLRunnerImpl::changes() { int now = runner_->getTurn(); if (changeDir_.get() != 0) { if (changeDir_->isLast(now)) { runner_->doChangeDirection(changeDir_->getLast()); delete auto_ptr_release(changeDir_); } else { runner_->doChangeDirection(changeDir_->getValue(now)); } } if (changeSpeed_.get() != 0) { if (changeSpeed_->isLast(now)) { runner_->doChangeSpeed(changeSpeed_->getLast()); delete auto_ptr_release(changeSpeed_); } else { runner_->doChangeSpeed(changeSpeed_->getValue(now)); } } if (accelx_.get() != 0) { if (accelx_->isLast(now)) { runner_->doAccelX(accelx_->getLast()); delete auto_ptr_release(accelx_); } else { runner_->doAccelX(accelx_->getValue(now)); } } if (accely_.get() != 0) { if (accely_->isLast(now)) { runner_->doAccelY(accely_->getLast()); delete auto_ptr_release(accely_); } else { runner_->doAccelY(accely_->getValue(now)); } } } void BulletMLRunnerImpl::runSub() { // R[hB while (act_ != 0 && !isTurnEnd()) { BulletMLNode* prev = act_; Method fp = commandMap_[act_->getName()]; (this->*fp)(); // ref if (act_ == 0 && prev->getParent() != 0 && prev->getParent()->getName() == BulletMLNode::bulletml) { assert(!refStack_.empty()); prev = refStack_.top().first; parameters_ = refStack_.top().second; refStack_.pop(); } // node T if (act_ == 0) act_ = prev->next(); // k node T while (act_ == 0) { if (prev->getParent() != 0 && prev->getParent()->getName() == BulletMLNode::repeat) { RepeatElem* rep = repeatStack_.top(); rep->ite++; if (rep->ite < rep->end) { act_ = rep->act; break; } else { delete rep; repeatStack_.pop(); } } act_ = prev->getParent(); if (act_ == 0) break; prev = act_; if (prev->getParent() != 0 && prev->getParent()->getName() == BulletMLNode::bulletml) { assert(!refStack_.empty()); prev = act_ = refStack_.top().first; parameters_ = refStack_.top().second; refStack_.pop(); } act_ = act_->next(); } } } void BulletMLRunnerImpl::run() { if (isEnd()) return; changes(); endTurn_ = runner_->getTurn(); // wait, changen if (act_ == 0) { if (!isTurnEnd()) { if (changeDir_.get() == 0 && changeSpeed_.get() == 0 && accelx_.get() == 0 && accely_.get() == 0) { end_ = true; } } return; } act_ = node_[actIte_]; if (actTurn_ == -1) actTurn_ = runner_->getTurn(); runSub(); if (act_ == 0) { actIte_++; if (node_.size() != actIte_) act_ = node_[actIte_]; } else { node_[actIte_] = act_; } } void BulletMLRunnerImpl::runBullet() { setSpeed(); setDirection(); if (!spd_.isValidate()) { prevSpd_ = spd_ = runner_->getDefaultSpeed(); } if (!dir_.isValidate()) { prevDir_ = dir_ = runner_->getAimDirection(); } if (act_->getChild(BulletMLNode::action) == 0 && act_->getChild(BulletMLNode::actionRef) == 0) { runner_->createSimpleBullet(dir_, spd_); } else { std::vector acts; act_->getAllChildrenVec(BulletMLNode::action, acts); act_->getAllChildrenVec(BulletMLNode::actionRef, acts); /* act_->getAllChildren(BulletMLNode::action, std::back_inserter(acts)); act_->getAllChildren(BulletMLNode::actionRef, std::back_inserter(acts)); */ BulletMLState* state = new BulletMLState(bulletml_, acts, parameters_); runner_->createBullet(state, dir_, spd_); } act_ = 0; } void BulletMLRunnerImpl::runFire() { shotInit(); setSpeed(); setDirection(); BulletMLNode* bullet = act_->getChild(BulletMLNode::bullet); if (bullet == 0) bullet = act_->getChild(BulletMLNode::bulletRef); BulletMLError::doAssert(bullet != 0, " must have contents bullet or bulletRef"); act_ = bullet; } void BulletMLRunnerImpl::runAction() { if (act_->childSize() == 0) act_ = 0; else act_ = *act_->childBegin(); } void BulletMLRunnerImpl::runWait() { int frame = static_cast(getNumberContents(act_)); doWait(frame); act_ = 0; } void BulletMLRunnerImpl::runRepeat() { const BulletMLNode* times = act_->getChild(BulletMLNode::times); if (times == 0) return; int timesNum = static_cast(getNumberContents(times)); BulletMLNode* action = act_->getChild(BulletMLNode::action); if (action == 0) action = act_->getChild(BulletMLNode::actionRef); BulletMLError::doAssert( action != 0, "repeat elem must have contents action or actionRef"); repeatStack_.push(new RepeatElem(0, timesNum, action)); act_ = action; } void BulletMLRunnerImpl::runFireRef() { boost::shared_ptr prevPara = parameters_; parameters_.reset(getParameters()); refStack_.push(std::make_pair(act_, prevPara)); act_ = bulletml_->getFireRef(act_->getRefID()); } void BulletMLRunnerImpl::runActionRef() { boost::shared_ptr prevPara = parameters_; parameters_.reset(getParameters()); refStack_.push(std::make_pair(act_, prevPara)); act_ = bulletml_->getActionRef(act_->getRefID()); } void BulletMLRunnerImpl::runBulletRef() { boost::shared_ptr prevPara = parameters_; parameters_.reset(getParameters()); refStack_.push(std::make_pair(act_, prevPara)); act_ = bulletml_->getBulletRef(act_->getRefID()); } void BulletMLRunnerImpl::runChangeDirection() { int term = static_cast(getNumberContents( act_->getChild(BulletMLNode::term))); BulletMLNode* dirNode = act_->getChild(BulletMLNode::direction); BulletMLNode::Type type = dirNode->getType(); double dir; if (type != BulletMLNode::sequence) dir = getDirection(dirNode, false); else dir = getNumberContents(dirNode); calcChangeDirection(dir, term, type == BulletMLNode::sequence); act_ = 0; } void BulletMLRunnerImpl::runChangeSpeed() { int term = static_cast(getNumberContents( act_->getChild(BulletMLNode::term))); BulletMLNode* spdNode = act_->getChild(BulletMLNode::speed); BulletMLNode::Type type = spdNode->getType(); double spd; if (type != BulletMLNode::sequence) spd = getSpeed(spdNode); else { spd = getNumberContents(spdNode) * (double)term + runner_->getBulletSpeed(); } calcChangeSpeed(spd, term); act_ = 0; } void BulletMLRunnerImpl::runAccel() { int term = static_cast(getNumberContents( act_->getChild(BulletMLNode::term))); BulletMLNode* hnode = act_->getChild(BulletMLNode::horizontal); BulletMLNode* vnode = act_->getChild(BulletMLNode::vertical); if (bulletml_->isHorizontal()) { if (vnode != 0) calcAccelX(getNumberContents(vnode), term, vnode->getType()); if (hnode != 0) calcAccelY(-getNumberContents(hnode), term, hnode->getType()); } else { if (hnode != 0) calcAccelX(getNumberContents(hnode), term, hnode->getType()); if (vnode != 0) calcAccelY(getNumberContents(vnode), term, vnode->getType()); } act_ = 0; } void BulletMLRunnerImpl::calcChangeDirection(double direction, int term, bool seq) { int finalTurn = actTurn_ + term; double dirFirst = runner_->getBulletDirection(); if (seq) { auto_ptr_copy(changeDir_, new LinearFunc (actTurn_, finalTurn, dirFirst, dirFirst + direction * term)); } else { double dirSpace; // \ double dirSpace1 = direction - dirFirst; double dirSpace2; if (dirSpace1 > 0) dirSpace2 = dirSpace1 - 360; else dirSpace2 = dirSpace1 + 360; if (abs(dirSpace1) < abs(dirSpace2)) dirSpace = dirSpace1; else dirSpace = dirSpace2; auto_ptr_copy(changeDir_, new LinearFunc (actTurn_, finalTurn, dirFirst, dirFirst + dirSpace)); } } void BulletMLRunnerImpl::calcChangeSpeed(double speed, int term) { int finalTurn = actTurn_ + term; double spdFirst = runner_->getBulletSpeed(); auto_ptr_copy(changeSpeed_, new LinearFunc (actTurn_, finalTurn, spdFirst, speed)); } void BulletMLRunnerImpl::calcAccelY(double horizontal, int term, BulletMLNode::Type type) { int finalTurn = actTurn_ + term; double firstSpd = runner_->getBulletSpeedY(); double finalSpd; if (type == BulletMLNode::sequence) { finalSpd = firstSpd + horizontal * term; } else if (type == BulletMLNode::relative) { finalSpd = firstSpd + horizontal; } else { finalSpd = horizontal; } auto_ptr_copy(accely_, new LinearFunc (actTurn_, finalTurn, firstSpd, finalSpd)); } void BulletMLRunnerImpl::calcAccelX(double vertical, int term, BulletMLNode::Type type) { int finalTurn = actTurn_ + term; double firstSpd = runner_->getBulletSpeedX(); double finalSpd; if (type == BulletMLNode::sequence) { finalSpd = firstSpd + vertical * term; } else if (type == BulletMLNode::relative) { finalSpd = firstSpd + vertical; } else { finalSpd = vertical; } auto_ptr_copy(accelx_ ,new LinearFunc (actTurn_, finalTurn, firstSpd, finalSpd)); } void BulletMLRunnerImpl::runVanish() { runner_->doVanish(); act_ = 0; } BulletMLRunnerImpl::Parameters* BulletMLRunnerImpl::getParameters() { Parameters* para = 0; bool first = true; BulletMLNode::ChildIterator ite; for (ite = act_->childBegin(); ite != act_->childEnd(); ite++) { BulletMLNode* node = *ite; if (node->getName() != BulletMLNode::param) continue; if (first) { first = false; para = new Parameters; // 0vfg para->push_back(0); } para->push_back(getNumberContents(node)); } return para; } bulletml/src/auto_ptr_fix.h0000644000076400007640000000075410037422406013275 0ustar /** * */ #ifndef auto_ptr_fix_h_ #define auto_ptr_fix_h_ #include template inline void auto_ptr_copy (std::auto_ptr& lhs, std::auto_ptr rhs) { lhs = rhs; } template inline void auto_ptr_copy (std::auto_ptr& lhs, T_* rhs) { std::auto_ptr p(rhs); lhs = p; } template inline T_* auto_ptr_release(std::auto_ptr& p) { T_* ret = p.release(); auto_ptr_copy(p, std::auto_ptr()); return ret; } #endif // ! auto_ptr_fix_h_ bulletml/src/bulletmlrunnerimpl.h0000644000076400007640000001004310037423170014515 0ustar #ifndef BULLETRUNNER_IMPL_H_ #define BULLETRUNNER_IMPL_H_ #include "bulletmltree.h" #include #include #include #include class BulletMLRunner; class BulletMLState; class BulletMLParser; typedef std::vector BulletMLParameter; template class Validatable { public: Validatable() : isValidate_(false) {} bool isValidate() const { return isValidate_; } void enValidate() { isValidate_ = true; } void disValidate() { isValidate_ = false; } operator C_& () { return val_; } C_& operator = (const C_& rhs) { isValidate_ = true; val_ = rhs; return *this; } protected: C_ val_; bool isValidate_; }; /// xylEIlCxy`NX template class LinearFunc { public: LinearFunc(const X_& firstX, const X_& lastX, const Y_& firstY, const Y_& lastY) : firstX_(firstX), lastX_(lastX), firstY_(firstY), lastY_(lastY), gradient_((lastY-firstY)/(lastX-firstX)) {} Y_ getValue(const X_& x) { return firstY_ + gradient_ * (x-firstX_); } bool isLast(const X_& x) { return x >= lastX_; } Y_ getLast() { return lastY_; } protected: X_ firstX_, lastX_; Y_ firstY_, lastY_; Y_ gradient_; }; class BulletMLRunnerImpl { public: explicit BulletMLRunnerImpl(BulletMLState* state, BulletMLRunner* runner); virtual ~BulletMLRunnerImpl(); /// タs void run(); public: /// タsI bool isEnd() const { return end_; } public: /// eXo^AゥOe^[X virtual void calcChangeDirection(double direction, int term, bool seq); /// exXo^AゥOe^[X virtual void calcChangeSpeed(double speed, int term); /// eo^AゥOe^[X /** * @todo horizontal, vertical type タB */ virtual void calcAccelX(double vertical, int term, BulletMLNode::Type type); /// eo^AゥOe^[X /** * @todo horizontal, vertical type タB */ virtual void calcAccelY(double horizontal, int term, BulletMLNode::Type type); protected: /** * {CzA * I[o[ChlB */ //@{ void runBullet(); void runAction(); void runFire(); void runWait(); void runRepeat(); void runBulletRef(); void runActionRef(); void runFireRef(); void runChangeDirection(); void runChangeSpeed(); void runAccel(); void runVanish(); //@} private: void changes(); void runSub(); void init(); bool isTurnEnd(); void doWait(int frame); void setDirection(); void setSpeed(); void shotInit() { spd_.disValidate(); dir_.disValidate(); } double getNumberContents(const BulletMLNode* node); std::vector* getParameters(); double getSpeed(BulletMLNode* spdNode); double getDirection(BulletMLNode* dirNode, bool prevChange = true); private: private: std::auto_ptr > changeDir_; std::auto_ptr > changeSpeed_; std::auto_ptr > accelx_; std::auto_ptr > accely_; protected: Validatable spd_, dir_, prevSpd_, prevDir_; typedef BulletMLParameter Parameters; boost::shared_ptr parameters_; protected: BulletMLParser* bulletml_; BulletMLNode* act_; std::vector node_; int actTurn_; std::vector actTurns_; int endTurn_; size_t actIte_; bool end_; protected: struct RepeatElem { RepeatElem(int i, int e, BulletMLNode* a) : ite(i), end(e), act(a) {} int ite, end; BulletMLNode* act; }; typedef std::stack RepeatStack; RepeatStack repeatStack_; typedef std::stack > > RefStack; RefStack refStack_; typedef void (BulletMLRunnerImpl::*Method)(); static Method commandMap_[BulletMLNode::nameSize]; protected: BulletMLRunner* runner_; }; #endif // ! BULLETRUNNER_IMPL_H_ bulletml/src/bulletmltree.h0000644000076400007640000000426007726413362013302 0ustar /// BulletMLc[B /** * BulletML B */ #ifndef BULLETMLTREE_H_ #define BULLETMLTREE_H_ #include #include #include #include #include "tree.h" #include "formula.h" #include "bulletmlcommon.h" class BulletMLNode : public TreeNode { public: typedef Formula Number; typedef enum { none, aim, absolute, relative, sequence, typeSize } Type; typedef enum { bullet, action, fire, changeDirection, changeSpeed, accel, wait, repeat, bulletRef, actionRef, fireRef, vanish, horizontal, vertical, term, times, direction, speed, param, bulletml, nameSize } Name; private: static Type string2type(const std::string& str); static Name string2name(const std::string& str); static std::string name2string[nameSize]; public: typedef TreeNode::Children Children; typedef TreeNode::ChildIterator ChildIterator; public: DECLSPEC explicit BulletMLNode(const std::string& name); DECLSPEC virtual ~BulletMLNode(); DECLSPEC Name getName() const { return name_; } DECLSPEC void setValue(const std::string& val); DECLSPEC double getValue() const { return val_->value(); } DECLSPEC void setType(const std::string& type) { type_ = string2type(type); } DECLSPEC Type getType() const { return type_; } DECLSPEC void setRefID(int id) { refID_ = id; } DECLSPEC int getRefID() const { return refID_; } DECLSPEC BulletMLNode* getChild(Name name); /* template void getAllChildren(Name name, OutIte_ outIte); */ DECLSPEC void getAllChildrenVec(Name name, std::vector& outvec); /// qwOv DECLSPEC bool findNode(Name name) const; DECLSPEC BulletMLNode* next(); virtual void dump(); protected: Name name_; Type type_; int refID_; std::auto_ptr val_; }; /* template void BulletMLNode::getAllChildren(Name name, OutIte_ outIte) { ChildIterator ite; for (ite = childBegin(); ite != childEnd(); ite++) { if ((*ite)->getName() == name) *outIte = *ite; outIte++; } } */ #endif // ! BULLETMLTREE_H_ bulletml/src/formula-variables.h0000644000076400007640000000174007726413362014215 0ustar #ifndef FORMULA_VARIABLE_H_ #define FORMULA_VARIABLE_H_ #include "formula.h" #include "bulletmlrunner.h" #include "bulletmlcommon.h" #include #include namespace Variables { DECLSPEC extern double rank; DECLSPEC extern std::vector* parameters; DECLSPEC extern BulletMLRunner* runner; } template class Random : public AbstractNumber { public: DECLSPEC virtual Val_ value() const { return Variables::runner->getRand(); } }; template class Rank : public AbstractNumber { public: DECLSPEC virtual Val_ value() const { return Variables::rank; } }; template class Param : public AbstractNumber { public: DECLSPEC explicit Param(int id) : id_(id) {} DECLSPEC virtual Val_ value() const { if (Variables::parameters && id_ < Variables::parameters->size()) { return (*Variables::parameters)[id_]; } else { return 1; } } private: int id_; }; #endif // ! FORMULA_VARIABLE_H_ bulletml/src/bulletmlparser-ygg.h0000644000076400007640000000166007726413362014424 0ustar /// BulletML p[TEc[ by yggdrasil /** * Yggdrasil BulletML p[T */ #ifndef BULLETMLPARSER_YGG_H_ #define BULLETMLPARSER_YGG_H_ #include #include "bulletmlcommon.h" #include "ygg/ygg.h" class BulletMLParserYggdrasil : public BulletMLParser, public yggdrasil::sax_handler { public: void on_error(yggdrasil::ygg_error* parse_error); void start_document(yggdrasil::ygg_node root); void end_document(yggdrasil::ygg_node &root); void start_element(yggdrasil::ygg_node element); void end_element(yggdrasil::ygg_node element); void catch_text(yggdrasil::ygg_node text); public: DECLSPEC explicit BulletMLParserYggdrasil(const std::string& filename); DECLSPEC virtual ~BulletMLParserYggdrasil(); DECLSPEC virtual void parse(); protected: std::string trimString(const std::string& str); private: std::string xmlFile_; class BulletMLNode* curNode_; }; #endif // ! BULLETMLPARSER_YGG_H_ bulletml/src/bulletmlparser-xerces.cpp0000644000076400007640000000651307726413361015463 0ustar #ifdef USE_XERCES #include "bulletmlparser.h" #include "bulletmlparser-xerces.h" #include "bulletmlerror.h" #include "bulletmltree.h" #include #include #include #include #include #include #include class BulletMLParserXercesSAXHandler : public HandlerBase { public: BulletMLParserXercesSAXHandler(BulletMLParserXerces* parser); virtual void characters(const XMLCh* const chars, const unsigned int length); virtual void startElement(const XMLCh* const name, AttributeList& attributes); virtual void endElement(const XMLCh* const name); virtual void error(const SAXParseException& e) { handleError(e); } virtual void fatalError(const SAXParseException& e) { handleError(e); } virtual void warning(const SAXParseException& e) { handleError(e); } private: void handleError(const SAXParseException& e) { std::ostringstream oss; oss << "Error at file " << parser_->uc2string(e.getSystemId()) << ", line " << e.getLineNumber() << ", char " << e.getColumnNumber() << "\nMessage: " << parser_->uc2string(e.getMessage()) << endl; throw BulletMLError(oss.str()); } private: BulletMLParserXerces* parser_; BulletMLNode* curNode_; }; BulletMLParserXercesSAXHandler::BulletMLParserXercesSAXHandler( BulletMLParserXerces* parser) : parser_(parser), curNode_(0) {} void BulletMLParserXercesSAXHandler::characters(const XMLCh* const chars, const unsigned int length) { curNode_->setValue(parser_->uc2string(chars, length)); } void BulletMLParserXercesSAXHandler::startElement(const XMLCh* const name, AttributeList& attributes) { BulletMLNode* node = parser_->addContent(parser_->uc2string(name)); if (node->getName() == BulletMLNode::bulletml) { for (unsigned int i = 0; i < attributes.getLength(); i++) { if (parser_->uc2string(attributes.getName(i)) == "type" && parser_->uc2string(attributes.getValue(i)) == "horizontal") { parser_->setHorizontal(); } } } else { BulletMLParserXerces::MyAttributes mattr; for (unsigned int i = 0; i < attributes.getLength(); i++) { mattr.push_back(parser_->uc2string(attributes.getName(i))); mattr.push_back(parser_->uc2string(attributes.getValue(i))); } parser_->addAttribute(mattr, node); } if (curNode_ != 0) curNode_->addChild(node); curNode_ = node; } void BulletMLParserXercesSAXHandler::endElement(const XMLCh* const) { curNode_ = curNode_->getParent(); } BulletMLParserXerces::BulletMLParserXerces(const std::string& filename) : xmlFile_(filename) { setName(filename); } BulletMLParserXerces::~BulletMLParserXerces() {} void BulletMLParserXerces::parse() { try { XMLPlatformUtils::Initialize(); std::auto_ptr parser(new SAXParser); parser->setValidationScheme(SAXParser::Val_Always); parser->setDoNamespaces(false); parser->setDoSchema(false); parser->setValidationSchemaFullChecking(false); BulletMLParserXercesSAXHandler handler(this); parser->setDocumentHandler(&handler); parser->setErrorHandler(&handler); parser->parse(xmlFile_.c_str()); parser.reset(0); } catch (const XMLException& toCatch) { throw BulletMLError(uc2string(toCatch.getMessage())); } XMLPlatformUtils::Terminate(); } #endif // USE_XERCES bulletml/src/bulletmlparser.cpp0000644000076400007640000000762607726413361014202 0ustar #include "bulletmlparser.h" #include "bulletmlerror.h" #include namespace { /// gpNXB class IDPool { public: static int getID(BulletMLNode::Name domain, const std::string& key) { KeyToID& kti = map_[domain]; KeyToID::iterator ite = kti.find(key); if (ite == kti.end()) { int id = maxMap_[domain]++; map_[domain][key] = id; return id; } else { return ite->second; } } static void init() { map_.insert(std::make_pair(BulletMLNode::bullet, KeyToID())); map_.insert(std::make_pair(BulletMLNode::action, KeyToID())); map_.insert(std::make_pair(BulletMLNode::fire, KeyToID())); maxMap_.insert(std::make_pair(BulletMLNode::bullet, 0)); maxMap_.insert(std::make_pair(BulletMLNode::action, 0)); maxMap_.insert(std::make_pair(BulletMLNode::fire, 0)); } static void quit() { map_.clear(); maxMap_.clear(); } private: typedef std::map KeyToID; typedef std::map DomainToIDMap; typedef std::map DomainToMaxID; static DomainToIDMap map_; static DomainToMaxID maxMap_; }; } IDPool::DomainToIDMap IDPool::map_; IDPool::DomainToMaxID IDPool::maxMap_; BulletMLParser::BulletMLParser() : bulletml_(0), isHorizontal_(false) {} BulletMLParser::~BulletMLParser() { // BulletMLNode [gm[hj delete bulletml_; } void BulletMLParser::build() { IDPool::init(); parse(); IDPool::quit(); } BulletMLNode* BulletMLParser::getBulletRef(int id) { BulletMLError::doAssert((int)bulletMap_.size() > id && bulletMap_[id] != 0, "bulletRef key doesn't exist."); return bulletMap_[id]; } BulletMLNode* BulletMLParser::getActionRef(int id) { BulletMLError::doAssert((int)actionMap_.size() > id && actionMap_[id] != 0, "actionRef key doesn't exist."); return actionMap_[id]; } BulletMLNode* BulletMLParser::getFireRef(int id) { BulletMLError::doAssert((int)fireMap_.size() > id && fireMap_[id] != 0, "fireRef key doesn't exist."); return fireMap_[id]; } BulletMLNode* BulletMLParser::addContent(const std::string& name) { // [gm[h if (name == "bulletml") { bulletml_ = new BulletMLNode(name); return bulletml_; } BulletMLError::doAssert(bulletml_ != 0, " doesn't come."); return new BulletMLNode(name); } void BulletMLParser::addAttribute(const MyAttributes& attr, BulletMLNode* elem) { if (!attr.empty()) { MyAttributeIte ite = attr.begin(); while (ite != attr.end()) { const std::string key(*ite); ite++; const std::string val(*ite); ite++; if (key == "type") elem->setType(val); else if (key == "label") { BulletMLNode::Name name = elem->getName(); BulletMLNode::Name domain; if (name == BulletMLNode::bulletRef) { domain = BulletMLNode::bullet; } else if (name == BulletMLNode::actionRef) { domain = BulletMLNode::action; } else if (name == BulletMLNode::fireRef) { domain = BulletMLNode::fire; } else { domain = name; } int id = IDPool::getID(domain, val); if (name == BulletMLNode::bullet) { if ((int)bulletMap_.size() <= id){ bulletMap_.resize(id+1, 0);} bulletMap_[id] = elem; } else if (name == BulletMLNode::action) { if ((int)actionMap_.size() <= id){ actionMap_.resize(id+1, 0); } actionMap_[id] = elem; } else if (name == BulletMLNode::fire) { if ((int)fireMap_.size() <= id) fireMap_.resize(id+1, 0); fireMap_[id] = elem; } else if ( name == BulletMLNode::bulletRef || name == BulletMLNode::actionRef || name == BulletMLNode::fireRef) { elem->setRefID(id); } else { BulletMLError::doAssert( "he can't have attribute \"label\"."); } if (elem->getName() == BulletMLNode::action && val.length() >= 3 && val.substr(0, 3) == "top") { topActions_.push_back(elem); } } } } } bulletml/src/formula.h0000644000076400007640000000322007726413362012242 0ustar /// ョNX #ifndef FORMULA_H_ #define FORMULA_H_ #include "bulletmlcommon.h" template class AbstractNumber { public: DECLSPEC virtual Val_ value() const =0; DECLSPEC virtual ~AbstractNumber() {} }; template class Number : public AbstractNumber { public: DECLSPEC explicit Number(Val_ val) : val_(val) {} DECLSPEC virtual Val_ value() const { return val_; } private: Val_ val_; }; typedef enum { op_null =0, op_add, op_sub, op_mul, op_div } Operator; template class Formula : public AbstractNumber { private: typedef AbstractNumber ANumber; public: DECLSPEC virtual ~Formula() { delete lhs_; delete rhs_; } /// public B /** * @todo yacc gA private */ //@{ DECLSPEC explicit Formula(ANumber* val) : lhs_(val), rhs_(0), op_(op_null), headsub_(false) {} DECLSPEC Formula(ANumber* lhs, Operator op, ANumber* rhs) : lhs_(lhs), rhs_(rhs), op_(op), headsub_(false) {} DECLSPEC Formula* setHeadSub() { headsub_ = true; return this; } //@} DECLSPEC virtual Val_ value() const { if (headsub_) return -valueBeforeHeadSub(); else return valueBeforeHeadSub(); } private: Val_ valueBeforeHeadSub() const { switch (op_) { case op_null: return lhs_->value(); case op_add: return lhs_->value() + rhs_->value(); case op_sub: return lhs_->value() - rhs_->value(); case op_mul: return lhs_->value() * rhs_->value(); case op_div: return lhs_->value() / rhs_->value(); default: return 0; // avoid warning } } private: ANumber *lhs_, *rhs_; Operator op_; bool headsub_; }; #endif // ! FORMULA_H_ bulletml/src/bulletmlparser-xerces.h0000644000076400007640000000101407726413362015120 0ustar /// BulletML p[TEc[ by Xerces /** * Xerces BulletML p[T */ #ifndef BULLETMLPARSER_XERCES_H_ #define BULLETMLPARSER_XERCES_H_ #ifdef USE_XERCES #include class BulletMLParserXerces : public BulletMLParser { public: explicit BulletMLParserXerces(const std::string& filename); virtual ~BulletMLParserXerces(); virtual void parse(); private: std::string xmlFile_; friend class BulletMLParserXercesSAXHandler; }; #endif // USE_XERCES #endif // ! BULLETMLPARSER_XERCES_H_ bulletml/src/ygg/0000755000076400007640000000000007726415662011222 5ustar bulletml/src/ygg/ygg_test.cpp0000644000076400007640000002434007714245776013562 0ustar /****************************************************************************** E -yggdrasil- E`[gA\[Xt@C Coded by Wraith in July 14, 2002. ******************************************************************************/ //@TabS\ヲB /////////////////////////////////////////////////////////////////////////////// // // ygg_test.cpp // http://tricklib.com/cxx/ex/yggdrasil/ygg_test.cpp // // At@C // yggW[wb_t@C // http://tricklib.com/cxx/ex/yggdrasil/ygg.h // yggW[{ // http://tricklib.com/cxx/ex/yggdrasil/ygg.cpp // St@CpbN // http://tricklib.com/cxx/ex/yggdrasil/ygg.lzh // http://tricklib.com/cxx/ex/yggdrasil/ygg.zip // // t@XET|[gy[W // http://tricklib.com/cxx/ex/yggdrasil/ // // CZX // http://tricklib.com/license.htm // #include //#include // for debug //#define __USING_UTF8__ //#include "..\babel\babel.cpp" #include "ygg.cpp" #include #include // VC #if defined(_MSC_VER) # define std_for if(0) ; else for #else # define std_for for #endif // gcc(IuWFNgl) template T & vitalize(const T &X) { return (T&)X; } using namespace yggdrasil; // // SOX path term // // term/node comment text attribute element // node() // comment() ~ ~ ~ // text() ~ ~ ~ // attribute() ~ ~ ~ // @* ~ ~ ~ // element() ~ ~ ~ // * ~ ~ ~ // class error_print: public sax_handler { public: void on_error(ygg_error *parse_error); }; void error_print::on_error(ygg_error *parse_error) { if (parse_error->is_error()) { printf("On Error !!!\n" "\tlocation %d:%d\n" "\tcode %02x:%02x:%02x:%02x\n" "\tmessage %s\n", parse_error->get_line(), parse_error->get_row(), parse_error->get_genre(), parse_error->get_category(), parse_error->get_sequence(), parse_error->get_sequence_case(), parse_error->get_message().c_str()); } } void test_enum() { sox_file root("test.sox"); root.read(&vitalize(error_print())); ygg_node node_list = root["//node()"]; // std_for(int i = 0; node_list[i].is_valid(); ++i) { // printf("path:%s\n", node_list[i].get_path().c_str()); // } // std_for(ygg_iterator i = node_list.begin(); i != node_list.end(); ++i) { // printf("path:%s\n", i->get_path().c_str()); // } std_for(ygg_iterator i = node_list.begin(); i.is_not_end(); ++i) { printf("path:%s\n", i->get_path().c_str()); } } void test_enum_stream() { sox_stream root; std::ifstream fs("test.sox"); root.read(fs, &vitalize(error_print())); ygg_node node_list = root["//node()"]; std_for(int i = 0; node_list[i].is_valid(); ++i) { printf("path:%s\n", node_list[i].get_path().c_str()); } } void test_path() { sox_file root("test.sox"); root.read(&vitalize(error_print())); ygg_node length = root["/first/hige/@length"]; std_for(int i = 0; length[i].is_valid(); ++i) { printf("%s\n", length[i].get_path().c_str()); } ygg_node hige = root["/first/hige/p/b/c/d/..../.."]; std_for(int i = 0; hige[i].is_valid(); ++i) { printf("%s\n", hige[i].get_path().c_str()); } ygg_node p = root["/first/hige/p"]; std_for(int i = 0; p[i].is_valid(); ++i) { printf("%s\n", p[i].get_path().c_str()); } } void test_csv() { sox_file root("csv.sox"); ygg_node item = root.read(&vitalize(error_print()))["/csv/item"]; std_for(int i = 0; item[i].is_valid(); ++i) { printf("%s\n", ygg_utility::create_line(item[i]["node()"], ",").c_str()); } } void test_text() { printf("%s\n", sox_file("test.sox").read(&vitalize(error_print())).get_text().c_str()); } class sax_print: public error_print { public: void on_error(ygg_error* parse_error); void start_document(ygg_node root); void end_document(ygg_node &root); void start_element(ygg_node element); void end_element(ygg_node element); void catch_text(ygg_node text); void catch_comment(ygg_node comment); }; void sax_print::on_error(ygg_error *parse_error) { printf("sax_print::on_error\n"); error_print::on_error(parse_error); } void sax_print::start_document(ygg_node) { printf("sax_print::start_document\n"); } void sax_print::end_document(ygg_node&) { printf("sax_print::end_document\n"); } void sax_print::start_element(ygg_node element) { printf("sax_print::start_element[%s]\n", element.get_name().c_str()); // ygg_node attributes = element["@*"]; // std_for(int i = 0; attributes[i].is_valid(); ++i) { // printf("@%s=\"%s\"\n", attributes[i].get_name().c_str(), attributes[i].get_value().c_str()); // } std_for(ygg_iterator i = element["@*"].begin(); i.is_not_end(); ++i) { printf("@%s=\"%s\"\n", i->get_name().c_str(), i->get_value().c_str()); } } void sax_print::end_element(ygg_node element) { printf("sax_print::end_element[%s]\n", element.get_name().c_str()); } void sax_print::catch_text(ygg_node text) { printf("sax_print::catch_text\n%s\n", text.get_text().c_str()); } void sax_print::catch_comment(ygg_node) { printf("sax_print::catch_comment\n"); } void test_handler() { sax_print sax; sox_file("test.sox").read(&sax); } void test_const() { const ygg_node node_list = sox_file("test.sox").read(&vitalize(error_print()))["//node()"]; std_for(ygg_const_iterator i = node_list.begin(); i.is_not_end(); ++i) { printf("path:%s\n", i->get_path().c_str()); } } void test_locacl_enum() { sox_file root("test.sox"); root.read(&vitalize(error_print())); ygg_node node_list = root["/first/hige[0]/.//node()"]; std_for(ygg_iterator i = node_list.begin(); i.is_not_end(); ++i) { printf("path:%s\n", i->get_path().c_str()); } } void test_xml() { sax_print sax; xml_file root("test.xml"); root.read(&sax); ygg_node node_list = root["//node()"]; std_for(ygg_iterator i = node_list.begin(); i.is_not_end(); ++i) { printf("path:%s\n", i->get_path().c_str()); } printf("xml:\n%s\n", root.get_xml().c_str()); } void test_string() { ygg_node root = ygg_root::parse_sox( "sox>\n" "\traw>\n" "\t\ttext\n", &vitalize(error_print())); root["/sox"].adopt_sox("raw>\n\tadopt_sox\n"); root["/sox"].adopt_xml("adopt_xml"); printf("%s\n", root.get_xml().c_str()); } void test_error() { error_catcher error_holder; ygg_root::parse_sox( "sox>\n" // "\t&raw>\n" // (02:00:02:01) // "\traw*>\n" // (02:00:02:02) "\t\traw>\n" // (02:01:01:00) "\traw>\n" "\t\thage=true\n" // "\t\thage=true\n" // (02:00:03:00) // "\t\t-hage=true\n" // (02:00:02:01) // "\t\thage?=true\n" // (02:00:02:02) "\t\ttext\n", &error_holder); ygg_error &error = error_holder.parse_error; if (error.is_error()) { printf("On Error !!!\n" "\tlocation %d:%d\n" "\tcode %02x:%02x:%02x:%02x\n" "\tmessage %s\n", error.get_line(), error.get_row(), error.get_genre(), error.get_category(), error.get_sequence(), error.get_sequence_case(), error.get_message().c_str()); } else { printf("G[B\n"); } } int main() { // std::locale::global(std::locale("japanese")); #if defined(__WITH_BABEL__) babel::init_babel(); #endif // defined(__WITH_BABEL__) while(true) { int test; std::cout << std::endl; std::cout << " *** ygg_test menu ***" << std::endl; std::cout << std::endl; std::cout << " 0 ... version information" << std::endl; std::cout << std::endl; std::cout << " 1 ... enum test" << std::endl; std::cout << " 2 ... enum test with stream" << std::endl; std::cout << " 3 ... path test" << std::endl; std::cout << " 4 ... csv test" << std::endl; std::cout << " 5 ... text test" << std::endl; std::cout << " 6 ... sax handle test" << std::endl; std::cout << " 7 ... const test" << std::endl; std::cout << " 8 ... local enum test" << std::endl; std::cout << " 9 ... xml test" << std::endl; std::cout << " 10 ... string test" << std::endl; std::cout << " 11 ... parse error test" << std::endl; std::cout << std::endl; std::cout << " other number ... exit" << std::endl; std::cout << std::endl; std::cout << " Please, input number." << std::endl; std::cout << std::endl; std::cin >> test; std::cout << std::endl; switch(test) { case 0: std::cout << "Version Information(SOX)" << std::endl; std::cout << ygg_node::parse_sox(ygg_term::yggdrasil_version).get_sox().c_str() << std::endl; std::cout << "Version Information(XML)" << std::endl; std::cout << ygg_node::parse_sox(ygg_term::yggdrasil_version).get_xml().c_str() << std::endl; break; case 1: std::cout << "Execute enum test!" << std::endl; test_enum(); break; case 2: std::cout << "Execute enum test with stream!" << std::endl; test_enum_stream(); break; case 3: std::cout << "Execute path test!" << std::endl; test_path(); break; case 4: std::cout << "Execute csv test!" << std::endl; test_csv(); break; case 5: std::cout << "Execute text test!" << std::endl; test_text(); break; case 6: std::cout << "Execute sax handle test!" << std::endl; test_handler(); break; case 7: std::cout << "Execute const test!" << std::endl; test_const(); break; case 8: std::cout << "Execute local enum test!" << std::endl; test_locacl_enum(); break; case 9: std::cout << "Execute xml test!" << std::endl; test_xml(); break; case 10: std::cout << "Execute string test!" << std::endl; test_string(); break; case 11: std::cout << "Execute parse error test!" << std::endl; test_error(); break; default: std::cout << "Exit! Good-bye!" << std::endl; return 0; } } } /****************************************************************************** Wraith the Trickster `I'll go with heaven's advantage and fool's wisdom.` ******************************************************************************/ bulletml/src/ygg/ygg.cpp0000644000076400007640000016603607726413525012524 0ustar /****************************************************************************** E -yggdrasil- EW[\[Xt@C Coded by Wraith in July 14, 2002. ******************************************************************************/ //@TabS\ヲB /////////////////////////////////////////////////////////////////////////////// // // ygg.cpp // http://tricklib.com/cxx/ex/yggdrasil/ygg.cpp // // At@C // {W[wb_t@C // http://tricklib.com/cxx/ex/yggdrasil/ygg.h // {W[`[gA\[Xt@C // http://tricklib.com/cxx/ex/yggdrasil/ygg_test.cpp // St@CpbN // http://tricklib.com/cxx/ex/yggdrasil/ygg.lzh // http://tricklib.com/cxx/ex/yggdrasil/ygg.zip // // t@XET|[gy[W // http://tricklib.com/cxx/ex/yggdrasil/ // // CZX // http://tricklib.com/license.htm // #include "ygg.h" #include #include #ifdef __USING_STRINGSTREAM___ # include #else # include #endif /****************************************************************************** TrickPalace http://www.trickpalace.net/ ******************************************************************************/ #define ARRAY_SIZE(X) (sizeof(X)/sizeof(X[0])) #define ARRAY_END(X) (X +ARRAY_SIZE(X)) #define AD_LIBTIUM(XXX) if (!(XXX)) ; else (*(XXX)) #define PROMOTION(XXX) XXX = XXX #define init_stack \ char init_stack_dummy[1]; \ init_stack_dummy[0] = 0; #if defined(_MSC_VER) # define tricklib_alloca _alloca #else # define tricklib_alloca alloca #endif #define get_stack(type, volume) ((type*)tricklib_alloca(volume*sizeof(type))) //#define AD_LIB(XXX) if (!(XXX)) ; else //#define AD_LIBTIUM_WHILE(XXX) while(XXX) (XXX) //#define AD_LIB_WHILE_PROMOTION(XXX) while(XXX) XXX = XXX /****************************************************************************** cppll ML http://www.trickpalace.net/cppll/ ******************************************************************************/ namespace yggdrasil { namespace ygg_utility { ygg_string ygg_utility::make_indent(int indent) { if (0 <= indent) { return make_indent(indent -1) + ygg_term::indent; // return } else { return ygg_term::empty; // return } } ygg_string ygg_utility::encode_xml(const ygg_string &X) { ygg_string X_text = X; ygg_string_replace(X_text, "&", "&"); ygg_string_replace(X_text, "<", "<"); ygg_string_replace(X_text, ">", ">"); ygg_string_replace(X_text, "=", "="); // ygg_string_replace(X_text, "\t", " "); return X_text; // return } ygg_string ygg_utility::encode_attribute(const ygg_string &X) { ygg_string X_text = X; ygg_string_replace(X_text, "&", "&"); ygg_string_replace(X_text, "<", "<"); ygg_string_replace(X_text, ">", ">"); ygg_string_replace(X_text, "\"", """); ygg_string_replace(X_text, "\'", "'"); // ' ygg_string_replace(X_text, "=", "="); ygg_string_replace(X_text, "\t", " "); return X_text; // return } ygg_string ygg_utility::encode_sox(const ygg_string &X) { ygg_string X_text = X; ygg_string_replace(X_text, "&", "&"); ygg_string_replace(X_text, "<", "<"); ygg_string_replace(X_text, ">", ">"); ygg_string_replace(X_text, "=", "="); ygg_string_replace(X_text, "\t", " "); return X_text; // return } ygg_string ygg_utility::encode_sox(int indent, const ygg_string &X) { return ygg_utility::encode_sox(make_indent(indent), X); // return } ygg_string ygg_utility::encode_sox(const ygg_string &indent, const ygg_string &X) { ygg_string X_text; ygg_string buffer = X; ygg_string::size_type p; const int return_code_length = ygg_term::return_code.length(); while(ygg_string::npos != (p = buffer.find(ygg_term::return_code))) { X_text += indent +encode_sox(buffer.substr(0, p)) +ygg_term::return_code; buffer = buffer.substr(p +return_code_length); } X_text += indent +encode_sox(buffer); return X_text; // return // return indent +encode_sox(X); } #if defined(__BORLANDC__) # pragma warn -8026 # pragma warn -8027 #endif ygg_string decode_xml(const ygg_string &X) { //#define __SIMPLE_XML_CODING__ #ifdef __SIMPLE_XML_CODING__ ygg_string X_text = X; ygg_string_replace(X_text, "<", "<"), ygg_string_replace(X_text, ">", ">"), ygg_string_replace(X_text, """, "\""), ygg_string_replace(X_text, "'", "\'"), ygg_string_replace(X_text, "'", "\'"), ygg_string_replace(X_text, "=", "="), ygg_string_replace(X_text, " ", "\t"), ygg_string_replace(X_text, "&", "&"); return X_text; // return #else class decodex { public: ygg_string replace; decodex(const ygg_string source) { if (0 == source.find("&#")) { unsigned int code; if (0 == source.find("&#x")) { code = strtol(source.substr(3).c_str(), NULL, 16); } else { code = strtol(source.substr(2).c_str(), NULL, 10); } #ifdef __USING_UTF8__ char utf8[8] = {0}; // wvf[B if (code < 0x80) { utf8[0] = (unsigned char)code; } else if (code < 0x800) { utf8[0] = 0xC0 | (code >> 6); utf8[1] = 0x80 | 0x3F & code; } else { // } else if (code < 0x10000) { utf8[0] = 0xE0 | (code >> 12); utf8[1] = 0x80 | 0x3F & (code >> 6); utf8[2] = 0x80 | 0x3F & code; // } else if (code < 0x200000) { // utf8[0] = 0xF0 | (code >> 18); // utf8[1] = 0x80 | 0x3F & (code >> 12); // utf8[2] = 0x80 | 0x3F & (code >> 6); // utf8[3] = 0x80 | 0x3F & code; // } else if (code < 0x400000) { // utf8[0] = 0xF8 | (code >> 24); // utf8[1] = 0x80 | 0x3F & (code >> 18); // utf8[2] = 0x80 | 0x3F & (code >> 12); // utf8[3] = 0x80 | 0x3F & (code >> 6); // utf8[4] = 0x80 | 0x3F & code; // } else { // utf8[0] = 0xFC | (code >> 30); // utf8[1] = 0x80 | 0x3F & (code >> 24); // utf8[2] = 0x80 | 0x3F & (code >> 18); // utf8[3] = 0x80 | 0x3F & (code >> 12); // utf8[4] = 0x80 | 0x3F & (code >> 6); // utf8[5] = 0x80 | 0x3F & code; } replace = utf8; #else // __USING_UTF8__ replace = ""; # ifdef __ACCEPT_NULLCODE__ do { replace += (char)(code % 0x100); code /= 0x100; } while(code); # else // __ACCEPT_NULLCODE__ while(code) { replace += (char)(code % 0x100); code /= 0x100; } # endif // __ACCEPT_NULLCODE__ #endif // __USING_UTF8__ } else { assert(false); replace = source; } assert(0 < source.find(";")); } operator const char * () { return replace.c_str(); // return } }; ygg_string X_text = X; ygg_string X_search_begin = "&"; ygg_string X_search_end = ";"; ygg_string X_replace; ygg_string::size_type inc; ygg_string::size_type p_end; for(ygg_string::size_type p = 0; ygg_string::npos != (p = X_text.find(X_search_begin, p)); p += inc) { if (ygg_string::npos == (p_end = X_text.find(X_search_end, p))) { break; // break } p == X_text.find("<", p) && (X_replace = "<", true) || p == X_text.find(">", p) && (X_replace = ">", true) || p == X_text.find(""", p) && (X_replace = "\"", true) || p == X_text.find("'", p) && (X_replace = "\'", true) || p == X_text.find("&", p) && (X_replace = "&", true) || p == X_text.find("&#", p) && (X_replace = decodex(X_text.substr(p, p_end)), true) || (X_replace = X_text.substr(p, p_end +1), true); // AoOH X_text.replace(p, (p_end -p) +1, X_replace); inc = X_replace.length(); } return X_text; // break #endif } #if defined(__BORLANDC__) # pragma warn .8026 # pragma warn .8027 #endif ygg_string ygg_utility::decode_attribute(const ygg_string &X) { return ygg_utility::decode_xml(X); // return } ygg_string ygg_utility::decode_sox(int , const ygg_string &X) { // indent; return decode_xml(X); // return } ygg_node & ygg_utility::format_tree(ygg_node &node, unsigned int max_row_length) { ygg_string type; bool is_text_node = ygg_node_type::root == node.get_type(); bool is_simple_element = true; ygg_node list = ygg_list::create(); for(ygg_iterator i = node[ygg_term::node].begin(); i.is_not_end(); ++i) { type = i->get_type(); if (ygg_node_type::attribute != type) { is_simple_element = false; if (ygg_node_type::text == type) { is_text_node = true; } else { if (!is_text_node) { list.adopt_node(ygg_text::create().set_value(" ")); } if (ygg_node_type::element == type && max_row_length < i->get_xml().length()) { format_tree(*i); } is_text_node = false; } } list.adopt_node(*i); } if (!is_simple_element && !is_text_node) { list.adopt_node(ygg_text::create().set_value(" ")); } node[ygg_term::node].vanish(); node.adopt_node(list); return node; } ygg_string ygg_utility::xml_trim(const ygg_string &X) { ygg_string X_text = X; for(ygg_string::size_type p = 0, p_end; ygg_string::npos != (p = X_text.find_first_of(ygg_term::white_space, p)); p += 1) { p_end = X_text.find_first_not_of(ygg_term::white_space, p); X_text.replace(p, (ygg_string::npos != p_end) ? p_end -p: ygg_string::npos, " "); } return X_text; } ygg_string ygg_utility::both_trim(const ygg_string &X) { ygg_string X_text = X; ygg_string::size_type start_pos = X_text.find_first_not_of(ygg_term::white_space); if (ygg_string::npos == start_pos) { return ""; } X_text = X_text.substr(start_pos); ygg_string::size_type end_pos = X_text.find_last_not_of(ygg_term::white_space); if (ygg_string::npos != end_pos && end_pos +1 < X_text.length()) { X_text = X_text.substr(0, end_pos +1); } return X_text; } ygg_error_code ygg_utility::check_name(const ygg_string &X) { using namespace ygg_term; using namespace ygg_error_term; // `FbN if (ygg_string::npos != ygg_invalid_name_chars_a.find(X.substr(0, 1))) { return ygg_invalid_name_a; } // ~`FbN #if defined(__USING_UNKNOWN__) if (base_encoding::sjis == get_base_encoding()) { #endif #if defined(__USING_UNKNOWN__) || defined(__USING_SJIS__) for(ygg_string::const_iterator i = X.begin(); i != X.end(); ++i) { if (0x81 <= (unsigned char)*i && (unsigned char)*i <= 0xFC) { // QoCgR[hPoCg... ++i; if (i == X.end() || 0x40 <= (unsigned char)*i && (unsigned char)*i <= 0xFC) { // QoCgR[hQoCgAQoCgR[hOl... return ygg_broken_char; } } else { if (ygg_string::npos != ygg_invalid_name_chars_b.find(*i)) { return ygg_invalid_name_b; } } } #endif #if defined(__USING_UNKNOWN__) } else { #endif #if defined(__USING_UNKNOWN__) || !defined(__USING_SJIS__) if (ygg_string::npos != ygg_invalid_name_chars_b.find_first_of(X.substr(1))) { return ygg_invalid_name_b; } #endif #if defined(__USING_UNKNOWN__) } #endif return no_error; } // u [ Y ] ygg_string & ygg_utility::ygg_string_replace( ygg_string &body, const ygg_string &X_search, const ygg_string &X_replace) { for(ygg_string::size_type p = ygg_string::npos, search_length = X_search.length(); ygg_string::npos != (p = body.rfind(X_search, p)); p -= search_length) { body.replace(p, search_length, X_replace); } return body; // return } ygg_string ygg_utility::create_line(ygg_node X_list, const ygg_string &separator) { ygg_string line_string; for(int i = 0; X_list[i].is_valid(); ++i) { line_string += separator + X_list[i].get_value().get_string(); } if (separator.length() <= line_string.length()) { return line_string.substr(separator.length()); // return } else { return line_string; // return } } } // namespace ygg_utility ygg_value & ygg_value::set_int(int X) { #ifdef __USING_STRINGSTREAM___ std::ostringstream strstr; strstr << X; value = strstr.str(); #else using namespace std; char buffer[32]; sprintf(buffer, "%d",X); value = buffer; #endif return *this; // return } ygg_value & ygg_value::set_double(double X) { #ifdef __USING_STRINGSTREAM___ std::ostringstream strstr; strstr << X; value = strstr.str(); #else using namespace std; char buffer[32]; sprintf(buffer, "%f",X); value = buffer; #endif return *this; // return } /****************************************************************************** cuppa http://www.unittest.org/ ******************************************************************************/ using namespace ygg_utility; // // yggm[hz_ // ygg_node & ygg_node::self_exile() { for(ygg_iterator i = begin(); i.is_not_end(); ++i) { ygg_node parent = i->get_parent(); assert(ygg_node_type::empty != parent.get_type()); if (ygg_node_type::empty != parent.get_type()) { parent.exile_node(*i); } } return *this; } ygg_node & ygg_node::vanish() { if (body.is_not_null()) { // m[h... for(ygg_iterator i = begin(); i.is_not_end(); ++i) { if (i->is_live()) { // S[Xg... ygg_node parent = i->get_parent(); if (ygg_node_type::empty != parent.get_type()) { // em[h... // em[h parent.exile_node(*i); } } } // nh(K^C~Om[h) this->operator=(NULL); } return *this; // return } ygg_string ygg_node::get_path() const { if (body.is_null()) { // m[h... return "/null()"; // return } ygg_string path; ygg_string this_path_name = get_path_name(); ygg_string index; ygg_node parent = body->get_parent(); if (ygg_node_type::empty != parent.get_type()) { // em[h... // em[hpX path = parent.get_path(); if (ygg_term::path_root != path){ path += ygg_term::path_dir; } // CfbNX ygg_node X_list = parent[this_path_name]; int size = X_list.get_size(); assert(0 < size); if (1 < size) { for(int i = 0; i < size; ++i) { if (this->body == X_list[i].body) { char number[2]; number[0] = '0' +i, number[1] = '\x0'; index = ygg_term::path_parenthesis_begin +number +ygg_term::path_parenthesis_end; break; // break } assert(i < size -1); } assert(0 < index.length()); } } else { // em[h... path = ygg_term::path_root; } path += this_path_name +index; return path; // return } ygg_node & ygg_node::purge() { // if (!is_live()) { return vanish(); // return } // m[h ygg_string type = get_type(); if (type == ygg_node_type::empty || type == ygg_node_type::comment || type == ygg_node_type::attribute) { // Rgm[hEm[h(Mu) return *this; // return } if (ygg_node_type::text == type) { // eLXgm[h... if (ygg_term::empty != get_value().get_string()) { return *this; // return } else { // eojbV return vanish(); // return } } if (type == ygg_node_type::root || type == ygg_node_type::element) { // vfm[h... ygg_node pre_node; ygg_node children = operator[](ygg_term::node); for(int i = 0; children[i].is_valid(); children[i++].purge()) { if (ygg_node_type::text == pre_node.get_type() && ygg_node_type::text == children[i].get_type()) { pre_node.set_value(pre_node.get_value().get_string() +children[i].get_value().get_string()); children[i].set_value(ygg_term::empty); } pre_node = children[i]; } return *this; // return } if (ygg_node_type::list == type) { // m[hXg... ygg_node children = operator[](ygg_term::node); for(int i = 0; children[i].is_valid(); children[i++].purge()); switch(get_size()) { case 0: return vanish(); // return case 1: return *this = operator[](0); // return } return *this; // return } assert(false); return *this; // return } ygg_node ygg_node::enum_node(const ygg_string &path_where) { ygg_node node_list = ygg_list::create(); if (match_path(path_where)) { node_list.adopt_node(*this); } ygg_node children = (*this)[ygg_term::node]; for(int i = 0; children[i].is_valid(); ++i) { node_list.adopt_node(children[i].enum_node(path_where)); } return node_list.purge(); // return } // // yggm[hNX // ygg_node ygg_node_body::operator[](const ygg_string &path) { if ("." == path) { return this; // return } else { return NULL; // return } } ygg_node ygg_node_body::operator[](const unsigned index) { if (0 == index) { return this; // return } else { return NULL; // return } } const int ygg_node_body::get_size() const { return 1; } ygg_iterator ygg_node_body::begin() { assert(false); return *(ygg_iterator*)(void*)NULL; // return } ygg_iterator ygg_node_body::end() { assert(false); return *(ygg_iterator*)(void*)NULL; // return } ygg_reverse_iterator ygg_node_body::rbegin() { assert(false); return *(ygg_reverse_iterator*)(void*)NULL; // return } ygg_reverse_iterator ygg_node_body::rend() { assert(false); return *(ygg_reverse_iterator*)(void*)NULL; // return } ygg_const_iterator ygg_node_body::begin() const { assert(false); return *(ygg_const_iterator*)(void*)NULL; // return } ygg_const_iterator ygg_node_body::end() const { assert(false); return *(ygg_const_iterator*)(void*)NULL; // return } ygg_const_reverse_iterator ygg_node_body::rbegin() const { assert(false); return *(ygg_const_reverse_iterator*)(void*)NULL; // return } ygg_const_reverse_iterator ygg_node_body::rend() const { assert(false); return *(ygg_const_reverse_iterator*)(void*)NULL; // return } bool ygg_node_body::match_path(const ygg_string &) const { return false; // return } void ygg_node_body::set_name(const ygg_string &) { assert(false); } void ygg_node_body::set_value(const ygg_string &) { assert(false); } void ygg_node_body::adopt_node(ygg_node) { assert(false); } void ygg_node_body::exile_node(ygg_node) { assert(false); } #ifdef _DEBUG bool ygg_node_body::assert_other(const ygg_node &) const { return true; // return } #endif // // yggS[XgNX // ygg_node ygg_ghost::get_life() const { ygg_node life = parent->operator[](path); if (life.is_live()) { return life; // return } else { return NULL; // return } } ygg_node ygg_ghost::realize() const { ygg_node life = get_life(); if (life.is_live()) { return life; // return } ygg_string::size_type p; ygg_string parent_path = path; while (0 < parent_path.length() && ygg_term::path_dir == parent_path.substr(p = parent_path.length() -1, 1)) { PROMOTION(parent_path).substr(0, p); } ygg_string::size_type px = 0; ygg_string::size_type this_p = 0; ygg_string this_path = parent_path; ygg_string xi[] = { ygg_term::path_dir, ygg_term::attribute_prefix, ygg_term::path_parenthesis_begin, ygg_term::path_parenthesis_end}; for(ygg_string *i = xi; i < ARRAY_END(xi); ++i) { while(ygg_string::npos != (p = parent_path.find(*i, this_p))) { px = p; this_p = px +1; this_path = parent_path.substr(this_p); } } if (ygg_term::empty == this_path) { assert(false); // return return parent; } if (ygg_term::attribute_prefix == parent_path.substr(px, 1)) { life = ygg_attribute::create().set_name(this_path); } else if (ygg_term::comment_node == this_path) { life = ygg_comment::create(); } else { life = ygg_element::create().set_name(this_path); } parent_path = parent_path.substr(0, px); while (0 < parent_path.length() && ygg_term::path_dir == parent_path.substr(p = parent_path.length() -1, 1)) { PROMOTION(parent_path).substr(0, p); } (*parent)[parent_path].adopt_node(life);// parent->operator[](parent_path).adopt_node(life); return life; // return } bool ygg_ghost::is_live() const { return false; // return } ygg_string ygg_ghost::get_type() const { return get_life().get_type(); // return } ygg_string ygg_ghost::get_name() const { return get_life().get_name(); // return } ygg_string ygg_ghost::get_value() const { return get_life().get_value().get_string(); // return } ygg_string ygg_ghost::get_text() const { return get_life().get_text(); // return } ygg_string ygg_ghost::get_xml(const ygg_string &indent) const { return get_life().get_xml(indent); // return } ygg_string ygg_ghost::get_xml_attribute() const { return get_life().get_xml_attribute(); // return } ygg_string ygg_ghost::get_sox(const ygg_string &indent) const { return get_life().get_sox(indent); // return } ygg_node ygg_ghost::operator[](const ygg_string &X_path) { ygg_string child_path = path; if (ygg_term::path_dir != path.substr(path.length() -1)) { child_path += ygg_term::path_dir; } child_path += X_path; return ygg_ghost::create(parent, child_path); // return } ygg_node ygg_ghost::operator[](const unsigned index) { return get_life().operator[](index); // return } const int ygg_ghost::get_size() const { return get_life().get_size(); // return } bool ygg_ghost::match_path(const ygg_string &path) const { return get_life().match_path(path); // return } void ygg_ghost::set_name(const ygg_string &X) { realize().set_name(X); } void ygg_ghost::set_value(const ygg_string &X) { realize().set_value(X); } void ygg_ghost::adopt_node(ygg_node X) { realize().adopt_node(X); } void ygg_ghost::exile_node(ygg_node X) { get_life().exile_node(X); } ygg_node ygg_ghost::clone() const { return create(NULL, path); // return } #ifdef _DEBUG bool ygg_ghost::assert_other(const ygg_node &X) const { return get_life().assert_other(X); // return } #endif // // yggRgNX // bool ygg_comment::is_live() const { return true; // return } ygg_string ygg_comment::get_type() const { return ygg_node_type::comment; // return } ygg_string ygg_comment::get_name() const { return ygg_term::comment_node; // return } ygg_string ygg_comment::get_value() const { return value; // return } ygg_string ygg_comment::get_text() const { return ygg_term::empty; // return } ygg_string ygg_comment::get_xml(const ygg_string &) const { ygg_string X_text = value; ygg_utility::ygg_string_replace(X_text, "-->", "-->"); return ygg_term::comment_lead +X_text +ygg_term::comment_trail; // return } ygg_string ygg_comment::get_xml_attribute() const { return ygg_term::empty; // return } ygg_string ygg_comment::get_sox(const ygg_string & indent) const { ygg_string X_text; ygg_string buffer = value; ygg_string::size_type p; int return_code_length = ygg_term::return_code.length(); if (ygg_string::npos != (p = buffer.find(ygg_term::return_code))) { X_text += indent +buffer.substr(0, p) +ygg_term::comment_trail +ygg_term::return_code; buffer = buffer.substr(p +return_code_length); while(ygg_string::npos != (p = buffer.find(ygg_term::return_code))) { X_text += indent +buffer.substr(0, p) +ygg_term::return_code; buffer = buffer.substr(p +return_code_length); } X_text += indent +buffer +ygg_term::return_code; } else { X_text = indent +buffer +ygg_term::comment_trail +ygg_term::return_code; } return X_text; // return // return indent +value +ygg_term::comment_trail +ygg_term::return_code; } bool ygg_comment::match_path(const ygg_string &path) const { return path == ygg_term::node || path == ygg_term::comment_node; // return } void ygg_comment::set_value(const ygg_string &X) { value = X; } ygg_node ygg_comment::clone() const { return create().set_value(value); // return } // // yggeLXgNX // bool ygg_text::is_live() const { return true; // return } ygg_string ygg_text::get_type() const { return ygg_node_type::text; // return } ygg_string ygg_text::get_name() const { return ygg_term::text_node; // return } ygg_string ygg_text::get_value() const { return value; // return } ygg_string ygg_text::get_text() const { return value; // return } ygg_string ygg_text::get_xml(const ygg_string &) const { return encode_xml(xml_trim(value)); // return } ygg_string ygg_text::get_xml_attribute() const { return ygg_term::empty; // return } ygg_string ygg_text::get_sox(const ygg_string & indent) const { return encode_sox(indent, value) +ygg_term::return_code; // return } bool ygg_text::match_path(const ygg_string &path) const { return path == ygg_term::node || path == ygg_term::text_node; // return } void ygg_text::set_value(const ygg_string &X) { value = X; } ygg_node ygg_text::clone() const { return create().set_value(value); // return } // // yggNX // bool ygg_attribute::is_live() const { return true; // return } ygg_string ygg_attribute::get_type() const { return ygg_node_type::attribute; // return } ygg_string ygg_attribute::get_name() const { assert(name == encode_xml(name)); assert(name == encode_attribute(name)); return name; // return } ygg_string ygg_attribute::get_value() const { return value; // return } ygg_string ygg_attribute::get_text() const { return ygg_term::empty; // return } ygg_string ygg_attribute::get_xml(const ygg_string &) const { assert(name == encode_xml(name)); assert(name == encode_attribute(name)); return ygg_term::empty; // return } ygg_string ygg_attribute::get_xml_attribute() const { assert(name == encode_xml(name)); assert(name == encode_attribute(name)); return " " +name +"=\"" +encode_attribute(value) +"\""; // return } ygg_string ygg_attribute::get_sox(const ygg_string & indent) const { return indent +name + "=" +encode_attribute(value) +ygg_term::return_code; // return } bool ygg_attribute::match_path(const ygg_string &path) const { return path == ygg_term::node || path == ygg_term::attribute_node || path == ygg_term::attribute_prefix +ygg_term::wildcard || path == ygg_term::attribute_prefix +name; // return } void ygg_attribute::set_name(const ygg_string &X) { name = X; } void ygg_attribute::set_value(const ygg_string &X) { value = X; } ygg_node ygg_attribute::clone() const { return create().set_name(name).set_value(value); // return } // // yggvgXgNX // bool ygg_proto_list::is_live() const { return true; // return } ygg_string ygg_proto_list::get_value() const { return get_text(); // return } // [ Y ] ygg_string ygg_proto_list::get_text() const { ygg_string X_text; for(ygg_list_type::const_iterator i = body.begin(); i != body.end(); ++i) { X_text += i->get_text(); } return X_text; // return } // [ Y ] ygg_string ygg_proto_list::get_xml(const ygg_string & indent) const { ygg_string X_text, X_part, X_core; bool gap = false; for(ygg_list_type::const_iterator i = body.begin(); i != body.end(); ++i) { X_part = i->get_xml(indent); if (0 < X_part.length()) { X_core = both_trim(X_part); if (0 < X_core.length()) { if (!gap && 0 < X_part.find_first_not_of(ygg_term::white_space)) { X_core = ygg_term::return_code +indent +X_core; } ygg_string::size_type end_pos = X_part.find_last_not_of(ygg_term::white_space); if (ygg_string::npos != end_pos && end_pos +1 < X_part.length()) { gap = true; X_core += ygg_term::return_code +indent; } else { gap = false; } } else { if (!gap) { gap = true; X_core += ygg_term::return_code +indent; } } X_text += X_core; } } return X_text; // return } // [ Y ] ygg_string ygg_proto_list::get_xml_attribute() const { ygg_string X_text; for(ygg_list_type::const_iterator i = body.begin(); i != body.end(); ++i) { X_text += i->get_xml_attribute(); } return X_text; // return } // [ Y ] ygg_string ygg_proto_list::get_sox(const ygg_string & indent) const { ygg_string X_text; for(ygg_list_type::const_iterator i = body.begin(); i != body.end(); ++i) { X_text += i->get_sox(indent); } return X_text; // return } void ygg_proto_list::adopt_node(ygg_node X) { adopt_child(X); } void ygg_proto_list::exile_node(ygg_node X) { exile_child(X); } // Xgm[h [ Y ] ygg_proto_list * ygg_proto_list::adopt_child(ygg_node X_node) { for(int i = 0; X_node[i].is_valid(); ++i) { #ifdef _DEBUG assert_other(X_node); #endif body.insert(body.end(), X_node[i]); } return this; // return } // Xgm[h [ Y ] ygg_proto_list * ygg_proto_list::exile_child(ygg_node X_node) { for(int i = 0; X_node[i].is_valid(); ++i) { body.remove(X_node[i]); } return this; // return } #ifdef _DEBUG bool ygg_proto_list::assert_other(const ygg_node &X) const { for(ygg_list_type::const_iterator i = body.begin(); i != body.end(); ++i) { if (!i->assert_other(X)) { return false; // return } } return (const ygg_node_body*)this != (const ygg_node_body*)X.body; // return } #endif // // yggXgNX // ygg_string ygg_list::get_type() const { return ygg_node_type::list; // return } ygg_string ygg_list::get_name() const { // return ygg_term::list_node; return ygg_term::empty; // return } // [ Y ] ygg_node ygg_list::operator[](const ygg_string &path) { if (ygg_term::path_last_index == path) { return *body.rbegin(); } ygg_node X_list = ygg_list::create(); for(ygg_list_type::iterator i = body.begin(); i != body.end(); ++i) { X_list.adopt_node(i->operator[](path)); } switch(X_list.get_size()) { case 0: return NULL; // return case 1: return X_list[0]; // return default: return X_list; // return } } // [ Y ] ygg_node ygg_list::operator[](const unsigned index) { if (index < body.size()) { ygg_list_type::iterator i = body.begin(); std::advance(i, index); return *i; // return } else { return NULL; // return } } const int ygg_list::get_size() const { return body.size(); // return } ygg_iterator ygg_list::begin() { return ygg_iterator(this, body.begin()); // return } ygg_iterator ygg_list::end() { return ygg_iterator(this, body.end()); // return } ygg_reverse_iterator ygg_list::rbegin() { return ygg_reverse_iterator(get_shell(), body.rbegin()); // return } ygg_reverse_iterator ygg_list::rend() { return ygg_reverse_iterator(get_shell(), body.rend()); // return } ygg_const_iterator ygg_list::begin() const { return ygg_const_iterator(get_shell(), body.begin()); // return } ygg_const_iterator ygg_list::end() const { return ygg_const_iterator(get_shell(), body.end()); // return } ygg_const_reverse_iterator ygg_list::rbegin() const { return ygg_const_reverse_iterator(get_shell(), body.rbegin()); // return } ygg_const_reverse_iterator ygg_list::rend() const { return ygg_const_reverse_iterator(get_shell(), body.rend()); // return } bool ygg_list::match_path(const ygg_string &path) const { assert(false); //assert(("ygg_list::match_path BoOvB", false)); return path == ygg_term::node || path == ygg_term::list_node; // return } ygg_node ygg_list::clone() const { ygg_node X_clone = create(); for(ygg_list_type::const_iterator i = body.begin(); i != body.end(); ++i) { X_clone.adopt_node(i->clone()); } return X_clone; // return } // // yggNX // ygg_string ygg_root::get_type() const { return ygg_node_type::root; // return } ygg_string ygg_root::get_name() const { return ygg_term::empty; // return } // [ Y ] ygg_node ygg_root::operator[](const ygg_string &path) { assert(1 == ygg_term::path_dir.length()); assert(1 == ygg_term::attribute_prefix.length()); assert(1 == ygg_term::path_parenthesis_begin.length()); assert(1 == ygg_term::path_parenthesis_end.length()); if (ygg_term::empty == path || ygg_term::path_this == path) { return this; // return } if (ygg_term::node == path) { ygg_node X_list = ygg_list::create(); for(ygg_list_type::iterator i = body.begin(); i != body.end(); ++i) { X_list.adopt_node(*i); } return X_list; // return } if (0 == path.find(ygg_term::path_wherever)) { return operator[](ygg_term::path_root).enum_node(path.substr(ygg_term::path_wherever.length())); // return } if (0 == path.find(ygg_term::path_parent)) { ygg_node &X_parent = get_parent(); if (ygg_node(NULL) != X_parent) { return X_parent.operator[](path.substr(1)); // return } else { return NULL; // return } } if (0 == path.find(ygg_term::path_this)) { if (0 == path.find(ygg_term::path_this__wherever)) { return get_shell().enum_node(path.substr(ygg_term::path_this__wherever.length())); // return } else if (0 == path.find(ygg_term::path_this_element)) { return operator[](path.substr(ygg_term::path_this_element.length())); // return } else { return operator[](path.substr(ygg_term::path_this.length())); // return } } if (0 == path.find(ygg_term::path_dir)) { ygg_node &X_parent = get_parent(); if (ygg_node(NULL) != X_parent) { return X_parent.operator[](path); // return } else { return operator[](path.substr(ygg_term::path_dir.length())); // return } } ygg_string current_path = path; ygg_string next_term = ygg_term::empty; if (0 != current_path.find(ygg_term::attribute_prefix)) { ygg_string::size_type p; ygg_string xi[] = { ygg_term::path_dir, ygg_term::attribute_prefix, ygg_term::path_parenthesis_begin, ygg_term::path_parenthesis_end}; for(ygg_string *i = xi; i < ARRAY_END(xi); ++i) { if (ygg_string::npos != (p = current_path.find(*i))) { next_term = *i; current_path = current_path.substr(0, p); } } } ygg_node X_list = ygg_list::create(); for(ygg_list_type::iterator i = body.begin(); i != body.end(); ++i) { if (i->match_path(current_path)) { X_list.adopt_node(*i); } } if (ygg_term::path_parenthesis_begin == next_term) { assert(ygg_string::npos != path.find(next_term)); ygg_string index_string = path.substr(path.find(next_term) +1); if (0 == index_string.find(ygg_term::path_last_index)) { X_list = *X_list.rbegin(); } else { int index = atoi(index_string.c_str()); X_list = X_list[index]; } assert(ygg_string::npos != path.find(ygg_term::path_parenthesis_end)); current_path = path.substr(path.find(ygg_term::path_parenthesis_end) +1); next_term = ygg_term::empty; ygg_string::size_type p; ygg_string xi[] = { ygg_term::path_dir, ygg_term::attribute_prefix}; for(ygg_string *i = xi; i < ARRAY_END(xi); ++i) { if (ygg_string::npos != (p = current_path.find(*i))) { next_term = *i; current_path = current_path.substr(0, p); } } } if (ygg_term::empty != next_term) { ygg_string next_path = path; if (ygg_term::path_dir != next_term) { next_path = next_path.substr(next_path.find(next_term)); } else { next_path = next_path.substr(next_path.find(next_term) +1); } ygg_node X_list_temp = ygg_list::create(); for(int i = 0; X_list[i].is_valid(); ++i) { X_list_temp.adopt_node(X_list[i][next_path]); } X_list = X_list_temp; } switch(X_list.get_size()) { case 0: return ygg_ghost::create(this, path); // return case 1: return X_list[0]; // return default: return X_list; // return } } void ygg_root::adopt_node(ygg_node X_node) { for(ygg_iterator i = X_node.begin(); i.is_not_end(); ++i) { i->regist_parent(this); } // for(int i = 0; X_node[i].is_valid(); ++i) { // X_node[i].regist_parent(this); // } } void ygg_root::exile_node(ygg_node X_node) { for(ygg_iterator i = X_node.begin(); i.is_not_end(); ++i) { i->unregist_parent(this); } // for(int i = 0; X_node[i].is_valid(); ++i) { // X_node[i].unregist_parent(this); // } } bool ygg_root::match_path(const ygg_string &path) const { return path == ygg_term::node || path == ygg_term::element_node || path == ygg_term::wildcard; // return } ygg_node ygg_root::clone() const { ygg_node X_clone = create(); for(ygg_list_type::const_iterator i = body.begin(); i != body.end(); ++i) { X_clone.adopt_node(i->clone()); } return X_clone; // return } // // yggvfNX // ygg_string ygg_element::get_type() const { return ygg_node_type::element; // return } ygg_string ygg_element::get_name() const { assert(name == encode_xml(name)); assert(name == encode_attribute(name)); return name; // return } ygg_string ygg_element::get_xml(const ygg_string & indent) const { const ygg_string inner_indent = indent +ygg_term::indent; ygg_string X_text = ygg_proto_list::get_xml(inner_indent); ygg_string X_attribute = ygg_proto_list::get_xml_attribute(); if (0 == name.find("?")) { X_text = "<" +name +X_attribute +" ?>"; } else if (ygg_term::empty == X_text) { X_text = "<" +name +X_attribute +" />"; } else { ygg_string X_core = both_trim(X_text); if (0 < X_text.find_first_not_of(ygg_term::white_space)) { X_core = ygg_term::return_code +inner_indent +X_core; } ygg_string::size_type end_pos = X_text.find_last_not_of(ygg_term::white_space); if (ygg_string::npos != end_pos && end_pos +1 < X_text.length()) { X_core += ygg_term::return_code +indent; } X_text = "<" +name +X_attribute +">" +X_core +""; } return X_text; // return } ygg_string ygg_element::get_xml_attribute() const { return ygg_term::empty; // return } ygg_string ygg_element::get_sox(const ygg_string & indent) const { const ygg_string child_indent = indent +ygg_term::indent; const ygg_list_type &X_list = body; ygg_string X_attribute; ygg_string X_text; for(ygg_list_type::const_iterator i = X_list.begin(); i != X_list.end(); ++i) { if (ygg_node_type::attribute == i->get_type()) { X_attribute += i->get_sox(child_indent); } else { X_text += i->get_sox(child_indent); } } X_text = indent +name +">" +ygg_term::return_code +X_attribute +X_text; return X_text; // return } bool ygg_element::match_path(const ygg_string &path) const { #ifdef __REJECT_PROCESSING_INSTRUCTION__ return path == ygg_term::node || path == ygg_term::element_node || path == ygg_term::wildcard || path == name; // return #else return path == ygg_term::node || (ygg_string::npos != name.find("!") ? path == ygg_term::element_node || path == ygg_term::wildcard: path == ygg_term::processing_instruction_node) || path == name; // return #endif } void ygg_element::set_name(const ygg_string &X) { name = X; } void ygg_element::set_value(const ygg_string &X) { ygg_list_type::iterator i = body.begin(); while(i != body.end()) { if (ygg_node_type::attribute != i->get_type()) { i++->vanish(); } else { ++i; } } adopt_node(ygg_text::create().set_value(X)); } ygg_node ygg_element::clone() const { ygg_node X_clone = create().set_name(name); for(ygg_list_type::const_iterator i = body.begin(); i != body.end(); ++i) { X_clone.adopt_node(i->clone()); } return X_clone; // return } /****************************************************************************** Trick Library 'dagger' http://tricklib.com/cxx/dagger/ ******************************************************************************/ // // ygg_position // ygg_position & ygg_position::operator+=(const ygg_string &X) { ygg_string X_text = X; ygg_string::size_type p; const ygg_string::size_type return_code_length = ygg_term::return_code.length(); while(ygg_string::npos != (p = X_text.find(ygg_term::return_code))) { next_line(); PROMOTION(X_text).substr(p +return_code_length); } row += X_text.length(); return *this; } // // SAXnh[{NX // void sax_handler::on_error(ygg_error*) {} void sax_handler::start_document(ygg_node) {} void sax_handler::end_document(ygg_node&) {} void sax_handler::start_element(ygg_node) {} void sax_handler::end_element(ygg_node) {} void sax_handler::catch_text(ygg_node) {} void sax_handler::catch_comment(ygg_node) {} // // yggp[UNX // ygg_parser * ygg_parser::set_sax_handler(sax_handler *X_sax) { sax = X_sax; AD_LIBTIUM(sax).set_parser(this); return this; // return } const ygg_error_code ygg_parser::check_name(const ygg_string &type, const ygg_string &X) { using namespace ygg_error_term; ygg_error_code name_error = ygg_utility::check_name(X); const int error_code = name_error.get_code(); const int sequence_case = name_error.get_sequence_case(); if (error_code == ygg_broken_char.get_code()) { // sR[h... raise_error(name_error, "sR[hB"); } else if (error_code == ygg_invalid_name.get_code()) { // sKO... if (sequence_case == ygg_invalid_name_a.get_sequence_case()) { raise_error(name_error, "sK" +type +"(" +X +")B(" +type +"gp '" +ygg_term::ygg_invalid_name_chars_a +"')"); } else if (sequence_case == ygg_invalid_name_b.get_sequence_case()) { raise_error(name_error, "sK" +type +"(" +X +")B(" +type +"gp '" +ygg_term::ygg_invalid_name_chars_b +"')"); } else { raise_error(name_error, "sK" +type +"(" +X +")B"); } } else if (error_code != no_error.get_code()) { // G[... raise_error(name_error); } // sax->on_error G[NAs return parse_error; } // // SOXp[UNX // sox_parser & sox_parser::init_root() { root = ygg_root::create(); hot_element = root; last_node = root; indent_node_list = ygg_list::create(); indent_node_list.adopt_node(root); anchor_indent = -1; anchor_position.clear(); hot_position.clear(); parse_error.clear(); AD_LIBTIUM(sax).start_document(root); return *this; // return } sox_parser & sox_parser::parse_line(const ygg_string &X_line) { // obt@c flush(); // parse(X_line); // sJEg anchor_position.next_line(); return *this; // return } sox_parser & sox_parser::parse_string(const ygg_string &X_text) { // obt@ unparsed_buffer += X_text; // sP int return_code_length = ygg_term::return_code.length(); ygg_string::size_type p; while(ygg_string::npos != (p = unparsed_buffer.find(ygg_term::return_code))) { parse(unparsed_buffer.substr(0, p)); if (parse_error.is_error()) { break; // break } // sJEg anchor_position.next_line(); unparsed_buffer = unparsed_buffer.substr(p +return_code_length); } return *this; // return } sox_parser & sox_parser::flush() { // obt@c if (ygg_term::empty != unparsed_buffer) { parse(unparsed_buffer); unparsed_buffer = ygg_term::empty; } return *this; // return } sox_parser & sox_parser::end_stream() { flush(); if (sax) { catch_event(last_node); if (ygg_node_type::element == hot_element.get_type()) { for(ygg_node node = hot_element; node.is_valid() && node != root; PROMOTION(node).get_parent()) { sax->end_element(node); } } sax->end_document(root); } return *this; // return } void sox_parser::parse(const ygg_string &X_text) { ygg_string X_parse = X_text; ygg_string::size_type p; ygg_string name; ygg_string value; // G[ if (parse_error.is_error()) { return; // return } // sR[hc const char *xi[] = {"\x0a", "\x0d"}; for(const char **i = xi; i < ARRAY_END(xi); ++i) { if (ygg_string::npos != (p = X_parse.find(*i))) { PROMOTION(X_parse).substr(0, p); } } // Cfg int indent_count = 0; int indent_length = ygg_term::indent.length(); while(ygg_term::indent == X_parse.substr(0, indent_length)) { PROMOTION(X_parse).substr(indent_length); ++indent_count; anchor_position.row += indent_length; } if (0 == X_parse.length()) { // s... return; // return } // // AJ[Cfgs // while(indent_count <= anchor_indent) { // eGg~ --anchor_indent; assert(root != hot_element); assert(ygg_node_type::empty != hot_element.get_type()); assert(1 < indent_node_list.get_size()); indent_node_list.exile_node(indent_node_list[indent_node_list.get_size() -1]); assert(0 < indent_node_list.get_size()); ygg_node indent_node = indent_node_list[indent_node_list.get_size() -1]; if (sax) { catch_event(last_node); if (ygg_node_type::element == hot_element.get_type()) { for(ygg_node node = hot_element; node.is_valid() && node != indent_node; PROMOTION(node).get_parent()) { sax->end_element(node); } } } hot_element = indent_node; // last_node = hot_element; last_node = NULL; // hot_element = hot_element.get_parent(); assert(ygg_node_type::empty != hot_element.get_type()); } // // m[ho // if (ygg_node_type::comment == last_node.get_type()) { // Rg... last_node.set_value( last_node.get_value().get_string() +ygg_term::return_code +make_indent(indent_count -(anchor_indent +1)) +X_parse); return; // return } // [CfgG[o if (anchor_indent +1 < indent_count) { raise_error(ygg_error_term::sox_deep_indent, "Cfg[B"); return; // return } if (ygg_string::npos != (p = X_parse.rfind(ygg_term::comment_trail))) { // Rg catch_event(last_node); value = X_parse.substr(0, p); last_node = ygg_comment::create().set_value(value); hot_element.adopt_node(last_node); hot_element = last_node; indent_node_list.adopt_node(last_node); assert(anchor_indent +1 == indent_count); anchor_indent = indent_count; X_parse = X_parse.substr(p +ygg_term::comment_trail.length()); while(ygg_term::indent == X_parse.substr(0, indent_length)) { PROMOTION(X_parse).substr(indent_length); } if (0 < X_parse.length()) { last_node.set_value( value +ygg_term::return_code +ygg_term::indent +X_parse); } return; // return } while(ygg_string::npos != (p = X_parse.find(ygg_term::element_trail))) { // Gg catch_event(last_node); name = X_parse.substr(0, p); if (ygg_parser::check_element_name(name).is_error()) { return; } last_node = ygg_element::create().set_name(name); hot_element.adopt_node(last_node); hot_element = last_node; if (anchor_indent < indent_count) { assert(anchor_indent +1 == indent_count); anchor_indent = indent_count; indent_node_list.adopt_node(last_node); } X_parse = X_parse.substr(p +ygg_term::element_trail.length()); while(ygg_term::indent == X_parse.substr(0, indent_length)) { PROMOTION(X_parse).substr(indent_length); } } if (0 == X_parse.length()) { return; // return } if (ygg_string::npos != (p = X_parse.find(ygg_term::equal))) { // Agr[g name = X_parse.substr(0, p); if (ygg_parser::check_attribute_name(name).is_error()) { return; } else if (hot_element["@"+name].is_valid()) { raise_error(ygg_error_term::duplication_attribute, name +"dB"); // sax->on_error G[NAs... if (parse_error.is_error()) { return; } } value = decode_attribute(X_parse.substr(p +ygg_term::equal.length())); // last_node = ygg_attribute::create().set_name(name).set_value(value); // hot_element.adopt_node(last_node); hot_element.adopt_node(ygg_attribute::create().set_name(name).set_value(value)); } else { // eLXg if (ygg_node_type::text != last_node.get_type()) { // VK catch_event(last_node); value = decode_xml(X_parse); last_node = ygg_text::create().set_value(value); hot_element.adopt_node(last_node); } else { // ... last_node.set_value( last_node.get_value().get_string() +ygg_term::return_code +make_indent(indent_count -(anchor_indent +2)) +X_parse); } } } void sox_parser::catch_event(ygg_node node) { if (sax) { ygg_string type = node.get_type(); if (ygg_node_type::text == type) { sax->catch_text(node); } else if (ygg_node_type::comment == type) { sax->catch_comment(node); } else if (ygg_node_type::element == type) { sax->start_element(node); } } } // // XMLp[UNX // xml_parser & xml_parser::init_root() { root = ygg_root::create(); hot_element = root; last_node = root; anchor_position.clear(); hot_position.clear(); parse_error.clear(); AD_LIBTIUM(sax).start_document(root); return *this; // return } xml_parser & xml_parser::parse_line(const ygg_string &X_line) { if (ygg_string::npos != X_line.find(ygg_term::return_code)) { parse_string(X_line); } else { parse_string(X_line +ygg_term::return_code); } return *this; // return } xml_parser & xml_parser::parse_string(const ygg_string &X_text) { // obt@ unparsed_buffer += X_text; // G[ if (parse_error.is_error()) { return *this; // return } ygg_string::size_type p, p_end; ygg_string value; while (ygg_string::npos != (p = unparsed_buffer.find(ygg_term::element_lead))) { if (0 != p) { // eLXg... ygg_string source_text = unparsed_buffer.substr(0, p); value = decode_xml(ygg_utility::xml_trim(source_text)); if (ygg_node_type::text == last_node.get_type()) { // eLXg... last_node.set_value(last_node.get_value().get_string() +value); } else { // VKeLXg... anchor_position = hot_position; last_node = ygg_text::create().set_value(value); hot_element.adopt_node(last_node); } // \iKCxgB // AD_LIBTIUM(sax).catch_text(last_node); hot_position += source_text; PROMOTION(unparsed_buffer).substr(p), p = 0; } if (p == unparsed_buffer.find(ygg_term::comment_lead)) { // Rg... p_end = unparsed_buffer.find(ygg_term::comment_trail, p); if (ygg_string::npos != p_end) { // Rg""... // Om[heLXgm[heLXgCxgB if (ygg_node_type::text == last_node.get_type()) { AD_LIBTIUM(sax).catch_text(last_node); } value = unparsed_buffer.substr(0, p_end).substr(p +ygg_term::comment_lead.length()); last_node = ygg_comment::create().set_value(value); hot_element.adopt_node(last_node); AD_LIBTIUM(sax).catch_comment(last_node); hot_position += unparsed_buffer.substr(0, p_end +ygg_term::comment_trail.length()); PROMOTION(unparsed_buffer).substr(p_end +ygg_term::comment_trail.length()); } else { break; // break } } else if (p == unparsed_buffer.find(ygg_term::cdata_lead)) { // CDATAeLXg... p_end = unparsed_buffer.find(ygg_term::cdata_trail, p); if (ygg_string::npos != p_end) { // CDATA""... value = unparsed_buffer.substr(0, p_end).substr(p +ygg_term::cdata_lead.length()); if (ygg_node_type::text == last_node.get_type()) { last_node.set_value(last_node.get_value().get_string() +value); } else { last_node = ygg_text::create().set_value(value); hot_element.adopt_node(last_node); } // \iKCxgB // AD_LIBTIUM(sax).catch_text(last_node); hot_position += unparsed_buffer.substr(0, p_end +ygg_term::cdata_trail.length()); PROMOTION(unparsed_buffer).substr(p_end +ygg_term::cdata_trail.length()); } else { break; // break } } else { // Gg... p_end = unparsed_buffer.find(ygg_term::element_trail, p); if (ygg_string::npos != p_end) { // Gg""... // Om[heLXgm[heLXgCxgB if (ygg_node_type::text == last_node.get_type()) { AD_LIBTIUM(sax).catch_text(last_node); } // ^OeLXg ygg_string element_string = unparsed_buffer.substr(0, p_end).substr(p +ygg_term::element_lead.length()); // anchor_position = hot_position; hot_position += unparsed_buffer.substr(0, p_end +ygg_term::element_trail.length()); PROMOTION(unparsed_buffer).substr(p_end +ygg_term::element_trail.length()); // "/" `FbN ygg_string::size_type p_lead_sign = 0; ygg_string::size_type p_trail_sign = element_string.length() -ygg_term::element_sign.length(); bool lead_sign = p_lead_sign == element_string.find(ygg_term::element_sign, p_lead_sign); bool trail_sign = p_trail_sign == element_string.find(ygg_term::element_sign, p_trail_sign); if (trail_sign) PROMOTION(element_string).substr(0, p_trail_sign); if (lead_sign) PROMOTION(element_string).substr(ygg_term::element_sign.length()); # ifdef __REJECT_PROCESSING_INSTRUCTION__ # else bool is_pi_node = false; # endif if (!lead_sign && !trail_sign && p_lead_sign == element_string.find("?", p_lead_sign) && p_trail_sign == element_string.find("?", p_trail_sign)) { // ... # ifdef __REJECT_PROCESSING_INSTRUCTION__ // continue; // continue # else // Gg PROMOTION(element_string).substr(0, p_trail_sign); trail_sign = true; is_pi_node = true; # endif } // vf ygg_string::size_type p_name_end = element_string.find_first_of(ygg_term::white_space); ygg_string element_name = element_string.substr(0, p_name_end); if (ygg_string::npos != p_name_end) { PROMOTION(element_string).substr(p_name_end); } else { PROMOTION(element_string) = ygg_term::empty; } // "/" if (!lead_sign) { # ifdef __REJECT_PROCESSING_INSTRUCTION__ if (ygg_parser::check_element_name(element_name).is_error()) { # else if (ygg_parser::check_element_name((is_pi_node) ? element_name.substr(1): element_name).is_error()) { # endif return *this; // return } last_node = ygg_element::create().set_name(element_name); hot_element.adopt_node(last_node); hot_element = last_node; // ... while(true) { ygg_string::size_type p_anchor = element_string.find_first_not_of(ygg_term::white_space); if (ygg_string::npos == p_anchor) { break; // break } PROMOTION(element_string).substr(p_anchor); ygg_string::size_type p_name_end = element_string.find_first_of("=" +ygg_term::white_space); ygg_string attribute_name = element_string.substr(0, p_name_end); if (ygg_parser::check_attribute_name(attribute_name).is_error()) { return *this; // return } else if (hot_element["@"+attribute_name].is_valid()) { raise_error(ygg_error_term::duplication_attribute, attribute_name +"dB"); // sax->on_error G[NAs... if (parse_error.is_error()) { return *this; // return } } ygg_string hedge_symbol; ygg_string::size_type p_value; ygg_string::size_type p_value_a = element_string.find("\"", p_name_end); ygg_string::size_type p_value_b = element_string.find("\'", p_name_end); if (ygg_string::npos == p_value_b || (ygg_string::npos != p_value_a && p_value_a <= p_value_b)) { hedge_symbol = "\""; p_value = p_value_a; } else { hedge_symbol = "\'"; p_value = p_value_b; } ygg_string::size_type p_value_end = element_string.find(hedge_symbol, p_value +1); value = element_string.substr(0, p_value_end).substr(p_value +1); hot_element.adopt_node(ygg_attribute::create().set_name(attribute_name).set_value(value)); PROMOTION(element_string).substr(p_value_end +1); } // GgJnCxgB AD_LIBTIUM(sax).start_element(hot_element); } // "/"L if (lead_sign || trail_sign) { if (element_name != hot_element.get_name()) { if (root != hot_element) { raise_error(ygg_error_term::unmatch_tags_a, "Jn^O<" +hot_element.get_name() +">I^O}b`B"); } else { raise_error(ygg_error_term::unmatch_tags_b, "I^O<" +element_name +">nB"); } if (parse_error.is_error()) { return *this; // return } } // end_element vanish eB ygg_node parent = hot_element.get_parent(); // GgICxgB AD_LIBTIUM(sax).end_element(hot_element); hot_element = parent; last_node = NULL; } } else { break; // break } } } return *this; // return } xml_parser & xml_parser::flush() { // xmlB return *this; // return } xml_parser & xml_parser::end_stream() { flush(); if (sax) { if (ygg_node_type::text == last_node.get_type()) { sax->catch_text(last_node); } sax->end_document(root); } return *this; // return } } // namespace yggdrasil /****************************************************************************** Wraith the Trickster `I'll go with heaven's advantage and fool's wisdom.` ******************************************************************************/ bulletml/src/ygg/ygg.h0000644000076400007640000016641307726413525012170 0ustar /****************************************************************************** E -yggdrasil- EW[wb_t@C Coded by Wraith in July 14, 2002. ******************************************************************************/ //@TabS\ヲB /////////////////////////////////////////////////////////////////////////////// // // ygg.h // http://tricklib.com/cxx/ex/yggdrasil/ygg.h // // At@C // {W[{ // http://tricklib.com/cxx/ex/yggdrasil/ygg.cpp // {W[`[gA\[Xt@C // http://tricklib.com/cxx/ex/yggdrasil/ygg_test.cpp // St@CpbN // http://tricklib.com/cxx/ex/yggdrasil/ygg.lzh // http://tricklib.com/cxx/ex/yggdrasil/ygg.zip // // t@XET|[gy[W // http://tricklib.com/cxx/ex/yggdrasil/ // // CZX // http://tricklib.com/license.htm // #ifndef __YGGDRASIL_YGG_H__ #define __YGGDRASIL_YGG_H__ #if !defined(__WITH_YGGDRASIL__) # define __WITH_YGGDRASIL__ #endif #if !defined(__BABEL_BABEL_H__) && defined(__WITH_BABEL__) #include "babel.h" #endif #if defined(__WITH_BABEL__) && defined(__BBL_USE_SELECTORS__) #define __YGGDRASIL_WITH_BABEL__ #endif #include #include #include #include #ifndef NDEBUG #ifndef _DEBUG #define _DEBUG #endif #endif // // x[XGR[fBOw}N // // RpCw|RgsKw // (Rg)LBw // ゥAmf(])R[h // \B // //#define __USING_ANSI__ //#define __USING_SJIS__ //#define __USING_EUC__ //#define __USING_UTF8__ #if !(defined(__USING_ANSI__) || defined(__USING_SJIS__) || defined(__USING_EUC__) || defined(__USING_UTF8__) || defined(__USING_UNKNOWN__)) #define __USING_UNKNOWN__ #endif #if defined(__BORLANDC__) # pragma warn -8022 # pragma warn -8026 # pragma warn -8027 #endif /****************************************************************************** TrickPalace http://www.trickpalace.net/ ******************************************************************************/ // // yggdrasil // namespace yggdrasil { // // gpNX [ Y ] // } #include namespace yggdrasil { typedef std::string ygg_string; // typedef std::wstring ygg_wstring; // // m[h^ [ Y ] // namespace ygg_node_type { const ygg_string empty = "empty"; //const ygg_string node = "node"; const ygg_string text = "text"; const ygg_string comment = "comment"; const ygg_string attribute = "attribute"; const ygg_string list = "list"; const ygg_string root = "root"; const ygg_string element = "element"; } // // ^[ [ Y ] // namespace ygg_term { const ygg_string broken_char = "?"; // QAANSIOsB const ygg_string empty = ""; const ygg_string element_lead = "<"; const ygg_string element_sign = "/"; const ygg_string element_trail = ">"; const ygg_string comment_lead = ""; const ygg_string cdata_lead = ""; const ygg_string equal = "="; const ygg_string attribute_prefix = "@"; const ygg_string indent = "\t"; const ygg_string return_code = "\n"; const ygg_string white_space = "\n\r\t\v "; const ygg_string node = "node()"; const ygg_string wildcard = "*"; const ygg_string comment_node = "comment()"; const ygg_string text_node = "text()"; const ygg_string attribute_node = "attribute()"; const ygg_string element_node = "element()"; #ifndef __REJECT_PROCESSING_INSTRUCTION__ const ygg_string processing_instruction_node = "processing-instruction()"; #endif // const ygg_string doctype_node = "doctype()"; // const ygg_string cdata_section_node = "cdata-section()"; const ygg_string list_node = "list()"; // const ygg_string root_node = "root()"; const ygg_string path_dir = "/"; const ygg_string path_root = path_dir; const ygg_string path_wherever = "//"; const ygg_string path_this = "."; const ygg_string path_this_element = "./"; const ygg_string path_this__wherever = ".//"; const ygg_string path_parent = ".."; const ygg_string path_parenthesis_begin = "["; const ygg_string path_parenthesis_end = "]"; const ygg_string path_last_index = "last()"; const ygg_string ygg_invalid_name_chars_a = " !\"#$%&'()*+,-./;<=>?@[\\]^`{|}~"; const ygg_string ygg_invalid_name_chars_b = " !\"#$%&'()*+,/;<=>?@[\\]^`{|}~"; const ygg_string yggdrasil_version = "information>\n" "\tmodule>\tid=yggdrasil\n" "\t\tname=E -yggdrasil- \n" "\t\turl=http://tricklib.com/cxx/ex/yggdrasil/\n" "\t\tversion=x[^IIII-I\n" "\tauthor>\tid=wraith\n" "\t\tname=t_n" "\t\turl=http://www.trickpalace.net/\n" "\t\tmail=wraith@trickpalace.net\n"; } // // SOX path term // // term/node comment text attribute element // node() // comment() ~ ~ ~ // text() ~ ~ ~ // attribute() ~ ~ ~ // @* ~ ~ ~ // element() ~ ~ ~ // * ~ ~ ~ // /****************************************************************************** cppll ML http://www.trickpalace.net/cppll/ ******************************************************************************/ // // s // class ygg_node; class ygg_node_body; class ygg_ghost; class ygg_list; class ygg_root; class ygg_element; class ygg_iterator; class ygg_reverse_iterator; class ygg_const_iterator; class ygg_const_reverse_iterator; class sax_parser; class sax_handler; class ygg_error_code; class ygg_smart_base { public: typedef ygg_smart_base this_type; private: volatile int ref_count; protected: ygg_smart_base() :ref_count(0) {} virtual ~ygg_smart_base() { assert(0 == ref_count); } public: void inc_ref() volatile { if (NULL != this) { ++ref_count; } } void dec_ref() volatile { if (NULL != this) { if (--ref_count <= 0) { assert(0 == ref_count); delete this; } } } }; template class ygg_smart_shell { public: typedef ygg_smart_shell this_type; typedef target_object target_type; private: target_type *value; public: ygg_smart_shell(target_type *X_value = NULL) :value(X_value) { value->inc_ref(); } ygg_smart_shell(const this_type &X) :value(X.value) { value->inc_ref(); } ~ygg_smart_shell() { value->dec_ref(); } this_type & operator = (target_type *X_value) { if (value != X_value) { value->dec_ref(); value = X_value; value->inc_ref(); } return *this; } this_type & operator = (const this_type &X) { if (value != X.value) { value->dec_ref(); value = X.value; value->inc_ref(); } return *this; } bool operator == (const this_type &X) const { return value == X.value; } bool operator != (const this_type &X) const { return value != X.value; } bool operator == (const target_type *X_value) const { return value == X_value; } bool operator != (const target_type *X_value) const { return value != X_value; } bool operator ! () const { return !value; } operator target_type* () { return value; } operator const target_type* () const { return value; } target_type& operator*() { return *value; } const target_type& operator*() const { return *value; } target_type* operator->() { return value; } const target_type* operator->() const { return value; } bool is_null() const { return NULL == value; } bool is_not_null() const { return NULL != value; } }; // // utilities // namespace ygg_utility { ygg_string make_indent(int indent); ygg_string encode_xml(const ygg_string &X); ygg_string encode_attribute(const ygg_string &X); ygg_string encode_sox(const ygg_string &X); ygg_string encode_sox(int indent, const ygg_string &X); ygg_string encode_sox(const ygg_string &indent, const ygg_string &X); ygg_string decode_xml(const ygg_string &X); ygg_string decode_attribute(const ygg_string &X); ygg_string decode_sox(int indent, const ygg_string &X); ygg_node & format_tree(ygg_node &node, unsigned int max_row_length = 40); ygg_string xml_trim(const ygg_string &X); ygg_string both_trim(const ygg_string &X); ygg_error_code check_name(const ygg_string &X); ygg_string & ygg_string_replace( ygg_string &body, const ygg_string &search, const ygg_string &replace); ygg_string create_line(ygg_node X_list, const ygg_string &separator); namespace base_encoding { enum { ansi, sjis, jis, euc, utf8 }; }; inline const int get_base_encoding() { using namespace base_encoding; #ifdef __USING_ANSI__ return ansi; #endif #ifdef __USING_SJIS__ return sjis; #endif #ifdef __USING_EUC__ return euc; #endif #ifdef __USING_UTF8__ return utf8; #endif #ifdef __USING_UNKNOWN__ const int fingerprint = ((unsigned char*)(""))[0]; if (0x8A == fingerprint) { return sjis; } if (0x84 == fingerprint) { return euc; } if (0xE6 == fingerprint) { return utf8; } return ansi; #endif } } // // yggo[NX // class ygg_value { ygg_string value; public: ygg_value() {} ygg_value(const ygg_string &X_value) :value(X_value) {} ygg_value(const char *X_value) :value(X_value) {} ygg_value(int X) { operator=(X); } ygg_value(double X) { operator=(X); } ygg_value(const ygg_value &X) :value(X.value) {} ygg_value & operator=(const ygg_string &X_value) { return set_string(X_value); } ygg_value & operator=(const char *X_value) { return set_string(X_value); } ygg_value & operator=(int X) { return set_int(X); } ygg_value & operator=(double X) { return set_double(X); } ygg_value & operator=(const ygg_value &X) { return set_string(X.value); } operator const ygg_string & () const { return value; } operator const char * () const { return value.c_str(); } operator const int () const { return atol(value.c_str()); } operator const double () const { return atof(value.c_str()); } const ygg_string & get_string() const { return value; } const char * get_primary() const { return value.c_str(); } const char * c_str() const { return value.c_str(); } const int get_int() const { return atol(value.c_str()); } const double get_double() const { return atof(value.c_str()); } ygg_value & set_string(const ygg_string &X_value) { value = X_value; return *this; } ygg_value & set_int(int X); ygg_value & set_double(double X); }; /****************************************************************************** cuppa http://www.unittest.org/ ******************************************************************************/ // // yggm[hz_ // class ygg_node { friend class ygg_ghost; friend class ygg_proto_list; friend class ygg_root; typedef ygg_iterator iterator; typedef ygg_reverse_iterator reverse_iterator; ygg_smart_shell body; // ygg_node_body *body; public: inline ygg_node(ygg_node_body *X_body = NULL); inline ygg_node(const ygg_node &X); inline ygg_node & operator = (ygg_node_body *X_body); inline ygg_node & operator = (const ygg_node &X); bool operator == (const ygg_node &X) const { return body == X.body; } bool operator != (const ygg_node &X) const { return body != X.body; } inline ygg_node get_parent() const; inline bool is_live() const; // I // is_valid()/is_empty() gpB inline ygg_string get_type() const; inline ygg_string get_name() const; ygg_string get_path_name() const { if (ygg_node_type::attribute == get_type()) { return ygg_term::attribute_prefix +get_name(); } else { return get_name(); } } inline ygg_value get_value() const; inline ygg_string get_text() const; inline ygg_string get_xml(const ygg_string &indent = ygg_term::empty) const; inline ygg_string get_xml_attribute() const; inline ygg_string get_sox(const ygg_string &inden = ygg_term::empty) const; inline ygg_node operator[](const ygg_string &path); inline ygg_node operator[](const unsigned index); const ygg_node operator[](const ygg_string &path) const { return ((ygg_node*)this)->operator[](path); } const ygg_node operator[](const unsigned index) const { return ((ygg_node*)this)->operator[](index); } inline const int get_size() const; inline ygg_iterator begin(); inline ygg_iterator end(); inline ygg_reverse_iterator rbegin(); inline ygg_reverse_iterator rend(); inline ygg_const_iterator begin() const; inline ygg_const_iterator end() const; inline ygg_const_reverse_iterator rbegin() const; inline ygg_const_reverse_iterator rend() const; inline bool match_path(const ygg_string &path) const; inline ygg_node & set_name(const ygg_string &X); inline ygg_node & set_value(const ygg_value &X); inline ygg_node & adopt_node(ygg_node X); inline ygg_node & adopt_sox(const ygg_string &sox, sax_handler *sax = NULL) { return adopt_node(parse_sox(sox,sax)); } inline ygg_node & adopt_xml(const ygg_string &xml, sax_handler *sax = NULL) { return adopt_node(parse_xml(xml,sax)); } inline ygg_node & exile_node(ygg_node X); inline ygg_node & exile_path(const ygg_string &path) { return exile_node(operator[](path)); } ygg_node & self_exile(); inline ygg_node clone() const; inline const bool operator !() const { return !is_valid(); } //inline operator const bool() const { // return is_valid(); // } // alias functions bool is_valid() const { return is_live(); } bool is_empty() const { return !is_live(); } inline ygg_node & add_node(ygg_node X); inline ygg_node & sub_node(ygg_node X); #ifdef _DEBUG inline bool assert_other(const ygg_node &X) const; #endif ygg_node & vanish(); // em[h exile yAthis(ygg_node)m[h ygg_string get_path() const; ygg_node & purge(); // \eLXgm[hAAm[h exileAXgm[h ygg_node enum_node(const ygg_string &path_where); static inline ygg_node parse_sox(const ygg_string &sox, sax_handler *sax = NULL); static inline ygg_node parse_xml(const ygg_string &xml, sax_handler *sax = NULL); protected: inline ygg_node & regist_parent(ygg_root *X); inline ygg_node & unregist_parent(ygg_root *X); }; // // yggm[hNX // class ygg_node_body :public ygg_smart_base { friend class ygg_node; protected: ygg_root *parent; ygg_node_body() :parent(NULL) {} virtual ~ygg_node_body() { } ygg_node & get_parent() { return *((ygg_node *)&parent); } const ygg_node & get_parent() const { return *((ygg_node *)&parent); } virtual bool is_live() const = 0; virtual ygg_string get_type() const = 0; virtual ygg_string get_name() const = 0; virtual ygg_string get_value() const = 0; virtual ygg_string get_text() const = 0; virtual ygg_string get_xml(const ygg_string &indent) const = 0; virtual ygg_string get_xml_attribute() const = 0; virtual ygg_string get_sox(const ygg_string &indent) const = 0; virtual ygg_node operator[](const ygg_string &path); virtual ygg_node operator[](const unsigned index); virtual const int get_size() const; virtual ygg_iterator begin(); virtual ygg_iterator end(); virtual ygg_reverse_iterator rbegin(); virtual ygg_reverse_iterator rend(); virtual ygg_const_iterator begin() const; virtual ygg_const_iterator end() const; virtual ygg_const_reverse_iterator rbegin() const; virtual ygg_const_reverse_iterator rend() const; virtual bool match_path(const ygg_string &path) const; virtual void set_name(const ygg_string &X); virtual void set_value(const ygg_string &X); virtual void adopt_node(ygg_node X); virtual void exile_node(ygg_node X); virtual ygg_node clone() const = 0; ygg_node get_shell() { return this; } const ygg_node get_shell() const { return (ygg_node_body*)this; } #ifdef _DEBUG virtual bool assert_other(const ygg_node &X) const; #endif inline void regist_parent(ygg_root *X); void unregist_parent(ygg_root *X); }; inline ygg_node::ygg_node(ygg_node_body *X_body) :body(X_body) {} inline ygg_node::ygg_node(const ygg_node &X) :body(X.body) {} inline ygg_node & ygg_node::operator = (ygg_node_body *X_body) { body = X_body; return *this; } inline ygg_node & ygg_node::operator = (const ygg_node &X) { body = X.body; return *this; } inline ygg_node ygg_node::get_parent() const { assert(body.is_not_null()); if (body.is_null()) { return NULL; } else { return body->get_parent(); } } inline bool ygg_node::is_live() const { // assert(body.is_not_null()); if (body.is_null()) { return false; } else { return body->is_live(); } } inline ygg_string ygg_node::get_type() const { if (body.is_null()) { return ygg_node_type::empty; } else { return body->get_type(); } } inline ygg_string ygg_node::get_name() const { assert(body.is_not_null()); if (body.is_null()) { return ygg_term::empty; } else { return body->get_name(); } } inline ygg_string ygg_node::get_text() const { assert(body.is_not_null()); if (body.is_null()) { return ygg_term::empty; } else { return body->get_text(); } } inline ygg_string ygg_node::get_xml(const ygg_string &indent) const { assert(body.is_not_null()); if (body.is_null()) { return ygg_term::empty; } else { return body->get_xml(indent); } } inline ygg_string ygg_node::get_xml_attribute() const { assert(body.is_not_null()); if (body.is_null()) { return ygg_term::empty; } else { return body->get_xml_attribute(); } } inline ygg_string ygg_node::get_sox(const ygg_string &indent) const { assert(body.is_not_null()); if (body.is_null()) { return ygg_term::empty; } else { return body->get_sox(indent); } } inline ygg_value ygg_node::get_value() const { if (body.is_null()) { return ygg_term::empty; } else { return body->get_value(); } } inline ygg_node ygg_node::operator[](const ygg_string &path) { // assert(body.is_not_null()); if (body.is_null()) { return NULL; } else { return body->operator[](path); } } inline ygg_node ygg_node::operator[](const unsigned index) { // assert(body.is_not_null()); if (body.is_null()) { return NULL; } else { return body->operator[](index); } } inline const int ygg_node::get_size() const { // assert(body.is_not_null()); if (body.is_null()) { return 0; } else { return body->get_size(); } } inline bool ygg_node::match_path(const ygg_string &path) const { if (body.is_null()) { return false; } else { return body->match_path(path); } } inline ygg_node & ygg_node::set_name(const ygg_string &X) { assert(body.is_not_null()); if (body.is_not_null()) { body->set_name(X); } return *this; } inline ygg_node & ygg_node::set_value(const ygg_value &X) { assert(body.is_not_null()); if (body.is_not_null()) { body->set_value(X.get_string()); } return *this; } inline ygg_node & ygg_node::adopt_node(ygg_node X) { assert(body.is_not_null()); if (body.is_not_null()) { body->adopt_node(X); } return *this; } inline ygg_node & ygg_node::exile_node(ygg_node X) { assert(body.is_not_null()); if (body.is_not_null()) { body->exile_node(X); } return *this; } inline ygg_node ygg_node::clone() const { if (body.is_null()) { return NULL; } else { return body->clone(); } } inline ygg_node & ygg_node::add_node(ygg_node X) { return adopt_node(X); } inline ygg_node & ygg_node::sub_node(ygg_node X) { return exile_node(X); } #ifdef _DEBUG inline bool ygg_node::assert_other(const ygg_node &X) const { assert(body.is_not_null()); return body->assert_other(X); } #endif inline ygg_node & ygg_node::regist_parent(ygg_root *X) { assert(body.is_not_null()); if (body.is_not_null()) { body->regist_parent(X); } return *this; } inline ygg_node & ygg_node::unregist_parent(ygg_root *X) { assert(body.is_not_null()); if (body.is_not_null()) { body->unregist_parent(X); } return *this; } // // yggS[XgNX // class ygg_ghost :public ygg_node_body { ygg_string path; protected: ygg_ghost(ygg_root *X_parent, const ygg_string &X_path) { parent = X_parent; path = X_path; } ygg_node get_life() const; ygg_node realize() const; bool is_live() const; ygg_string get_type() const; ygg_string get_name() const; ygg_string get_value() const; ygg_string get_text() const; ygg_string get_xml(const ygg_string &indent = ygg_term::empty) const; ygg_string get_xml_attribute() const; ygg_string get_sox(const ygg_string &indent) const; ygg_node operator[](const ygg_string &path); ygg_node operator[](const unsigned index); const int get_size() const; bool match_path(const ygg_string &path) const; void set_name(const ygg_string &X); void set_value(const ygg_string &X); void adopt_node(ygg_node X); void exile_node(ygg_node X); ygg_node clone() const; #ifdef _DEBUG bool assert_other(const ygg_node &X) const; #endif public: static ygg_node create(ygg_root *X_parent, const ygg_string &X_path) { return new ygg_ghost(X_parent, X_path); } }; // // yggRgNX // class ygg_comment :public ygg_node_body { ygg_string value; protected: ygg_comment() {} bool is_live() const; ygg_string get_type() const; ygg_string get_name() const; ygg_string get_value() const; ygg_string get_text() const; ygg_string get_xml(const ygg_string &indent = ygg_term::empty) const; ygg_string get_xml_attribute() const; ygg_string get_sox(const ygg_string &indent) const; bool match_path(const ygg_string &path) const; void set_value(const ygg_string &X); ygg_node clone() const; public: static ygg_node create() { return new ygg_comment(); } }; // // yggeLXgNX // class ygg_text :public ygg_node_body { ygg_string value; protected: ygg_text() {} bool is_live() const; ygg_string get_type() const; ygg_string get_name() const; ygg_string get_value() const; ygg_string get_text() const; ygg_string get_xml(const ygg_string &indent = ygg_term::empty) const; ygg_string get_xml_attribute() const; ygg_string get_sox(const ygg_string &indent) const; bool match_path(const ygg_string &path) const; void set_value(const ygg_string &X); ygg_node clone() const; public: static ygg_node create() { return new ygg_text(); } }; // // yggNX // class ygg_attribute :public ygg_node_body { ygg_string name; ygg_string value; protected: ygg_attribute() {} bool is_live() const; ygg_string get_type() const; ygg_string get_name() const; ygg_string get_value() const; ygg_string get_text() const; ygg_string get_xml(const ygg_string &indent = ygg_term::empty) const; ygg_string get_xml_attribute() const; ygg_string get_sox(const ygg_string &indent) const; bool match_path(const ygg_string &path) const; void set_name(const ygg_string &X); void set_value(const ygg_string &X); ygg_node clone() const; public: static ygg_node create() { return new ygg_attribute(); } }; // // gpReiNX [ Y ] // typedef std::list ygg_list_type; //typedef std::iterator ygg_iterator_base; //typedef std::bidirectional_iterator ygg_iterator_base; struct ygg_iterator_base { typedef std::bidirectional_iterator_tag iterator_category; typedef ygg_node value_type; typedef ptrdiff_t difference_type; typedef ygg_node* pointer; typedef ygg_node& reference; }; class ygg_iterator :public ygg_iterator_base { friend class ygg_const_iterator; ygg_node list; ygg_list_type::iterator iterator; public: ygg_iterator(ygg_node X_list, ygg_list_type::iterator X_iterator) :list(X_list), iterator(X_iterator) {} ygg_iterator(const ygg_iterator &X) :list(X.list), iterator(X.iterator) {} const ygg_node & get_list() const { return list; } inline bool is_begin() const; inline bool is_not_begin() const; inline bool is_end() const; inline bool is_not_end() const; ygg_iterator & operator++() { ++iterator; return *this; } const ygg_iterator operator++(int) { return ygg_iterator(list, iterator++); } ygg_iterator & operator -- () { --iterator; return *this; } const ygg_iterator operator -- (int) { return ygg_iterator(list, iterator--); } ygg_node & operator*() { return *iterator; } ygg_node * operator->() { return iterator.operator->(); } bool operator==(const ygg_iterator &X) const { assert(list == X.list); return iterator == X.iterator; } bool operator!=(const ygg_iterator &X) const { assert(list == X.list); return iterator != X.iterator; } }; class ygg_reverse_iterator :public ygg_iterator_base { friend class ygg_const_reverse_iterator; ygg_node list; ygg_list_type::reverse_iterator iterator; public: ygg_reverse_iterator(ygg_node X_list, ygg_list_type::reverse_iterator X_iterator) :list(X_list), iterator(X_iterator) {} ygg_reverse_iterator(const ygg_reverse_iterator &X) :list(X.list), iterator(X.iterator) {} const ygg_node & get_list() const { return list; } inline bool is_rbegin() const; inline bool is_not_rbegin() const; inline bool is_rend() const; inline bool is_not_rend() const; ygg_reverse_iterator & operator++() { ++iterator; return *this; } const ygg_reverse_iterator operator++(int) { return ygg_reverse_iterator(list, iterator++); } ygg_reverse_iterator & operator--() { --iterator; return *this; } const ygg_reverse_iterator operator--(int) { return ygg_reverse_iterator(list, iterator--); } ygg_node & operator*() { return *iterator; } ygg_node * operator->() { return iterator.operator->(); } bool operator==(const ygg_reverse_iterator &X) const { assert(list == X.list); return iterator == X.iterator; } bool operator!=(const ygg_reverse_iterator &X) const { assert(list == X.list); return iterator != X.iterator; } }; class ygg_const_iterator :public ygg_iterator_base { friend class ygg_iterator; const ygg_node list; ygg_list_type::const_iterator iterator; public: ygg_const_iterator(const ygg_node X_list, ygg_list_type::const_iterator X_iterator) :list(X_list), iterator(X_iterator) {} ygg_const_iterator(const ygg_iterator &X) :list(X.list), iterator(X.iterator) {} ygg_const_iterator(const ygg_const_iterator &X) :list(X.list), iterator(X.iterator) {} const ygg_node & get_list() const { return list; } bool is_begin() const { return iterator == list.begin().iterator; } bool is_not_begin() const { return iterator != list.begin().iterator; } bool is_end() const { return iterator == list.end().iterator; } bool is_not_end() const { return iterator != list.end().iterator; } ygg_const_iterator & operator++() { ++iterator; return *this; } const ygg_const_iterator operator++(int) { return ygg_const_iterator(list, iterator++); } ygg_const_iterator & operator--() { --iterator; return *this; } const ygg_const_iterator operator--(int) { return ygg_const_iterator(list, iterator--); } const ygg_node & operator*() const { return *iterator; } const ygg_node * operator->() const { return iterator.operator->(); } bool operator==(const ygg_const_iterator &X) const { assert(list == X.list); return iterator == X.iterator; } bool operator!=(const ygg_const_iterator &X) const { assert(list == X.list); return iterator != X.iterator; } }; class ygg_const_reverse_iterator :public ygg_iterator_base { friend class ygg_reverse_iterator; const ygg_node list; ygg_list_type::const_reverse_iterator iterator; public: ygg_const_reverse_iterator(ygg_node X_list, ygg_list_type::const_reverse_iterator X_iterator) :list(X_list), iterator(X_iterator) {} ygg_const_reverse_iterator(const ygg_reverse_iterator &X) #if defined(_MSC_VER) && (_MSC_VER < 1300) :list(X.list), iterator((ygg_list_type::const_reverse_iterator&)(X.iterator)) {} #else :list(X.list), iterator(X.iterator) {} #endif ygg_const_reverse_iterator(const ygg_const_reverse_iterator &X) :list(X.list), iterator(X.iterator) {} const ygg_node & get_list() const { return list; } bool is_rbegin() const { return iterator == list.rbegin().iterator; } bool is_not_rbegin() const { return iterator != list.rbegin().iterator; } bool is_rend() const { return iterator == list.rend().iterator; } bool is_not_rend() const { return iterator != list.rend().iterator; } ygg_const_reverse_iterator & operator++() { ++iterator; return *this; } const ygg_const_reverse_iterator operator++(int) { return ygg_const_reverse_iterator(list, iterator++); } ygg_const_reverse_iterator & operator--() { --iterator; return *this; } const ygg_const_reverse_iterator operator--(int) { return ygg_const_reverse_iterator(list, iterator--); } const ygg_node & operator*() const { return *iterator; } const ygg_node * operator->() const { return iterator.operator->(); } bool operator==(const ygg_const_reverse_iterator &X) const { assert(list == X.list); return iterator == X.iterator; } bool operator!=(const ygg_const_reverse_iterator &X) const { assert(list == X.list); return iterator != X.iterator; } }; inline bool ygg_iterator::is_begin() const { return *((ygg_const_iterator*)(this)) == list.begin(); } inline bool ygg_iterator::is_not_begin() const { return *((ygg_const_iterator*)(this)) != list.begin(); } inline bool ygg_iterator::is_end() const { return *((ygg_const_iterator*)(this)) == list.end(); } inline bool ygg_iterator::is_not_end() const { return *((ygg_const_iterator*)(this)) != list.end(); } inline bool ygg_reverse_iterator::is_rbegin() const { return *((ygg_const_reverse_iterator*)(this)) == list.rbegin(); } inline bool ygg_reverse_iterator::is_not_rbegin() const { return *((ygg_const_reverse_iterator*)(this)) != list.rbegin(); } inline bool ygg_reverse_iterator::is_rend() const { return *((ygg_const_reverse_iterator*)(this)) == list.rend(); } inline bool ygg_reverse_iterator::is_not_rend() const { return *((ygg_const_reverse_iterator*)(this)) != list.rend(); } // // yggXgNX // class ygg_proto_list :public ygg_node_body { friend class ygg_node_body; protected: ygg_list_type body; ygg_proto_list() {} bool is_live() const; ygg_string get_value() const; ygg_string get_text() const; ygg_string get_attribute() const; ygg_string get_xml(const ygg_string &indent = ygg_term::empty) const; ygg_string get_xml_attribute() const; ygg_string get_sox(const ygg_string &indent) const; void adopt_node(ygg_node X); void exile_node(ygg_node X); ygg_proto_list * adopt_child(ygg_node X_node); ygg_proto_list * exile_child(ygg_node X_node); #ifdef _DEBUG bool assert_other(const ygg_node &X) const; #endif inline ygg_node get_single() { return operator[](0); } }; class ygg_list :public ygg_proto_list { protected: ygg_list() {} ygg_string get_type() const; ygg_string get_name() const; ygg_node operator[](const ygg_string &path); ygg_node operator[](const unsigned index); const int get_size() const; ygg_iterator begin(); ygg_iterator end(); ygg_reverse_iterator rbegin(); ygg_reverse_iterator rend(); ygg_const_iterator begin() const; ygg_const_iterator end() const; ygg_const_reverse_iterator rbegin() const; ygg_const_reverse_iterator rend() const; bool match_path(const ygg_string &path) const; ygg_node clone() const; public: static ygg_node create() { return new ygg_list(); } }; inline ygg_iterator ygg_node::begin() { if (ygg_node_type::list == get_type()) { return body->begin(); } else { return ygg_list::create().adopt_node(*this).begin(); } } inline ygg_iterator ygg_node::end() { if (ygg_node_type::list == get_type()) { return body->end(); } else { return ygg_list::create().adopt_node(*this).end(); } } inline ygg_reverse_iterator ygg_node::rbegin() { if (ygg_node_type::list == get_type()) { return body->rbegin(); } else { return ygg_list::create().adopt_node(*this).rbegin(); } } inline ygg_reverse_iterator ygg_node::rend() { if (ygg_node_type::list == get_type()) { return body->rend(); } else { return ygg_list::create().adopt_node(*this).rend(); } } inline ygg_const_iterator ygg_node::begin() const { if (ygg_node_type::list == get_type()) { return body->begin(); } else { return ygg_list::create().adopt_node(*this).begin(); } } inline ygg_const_iterator ygg_node::end() const { if (ygg_node_type::list == get_type()) { return body->end(); } else { return ygg_list::create().adopt_node(*this).end(); } } inline ygg_const_reverse_iterator ygg_node::rbegin() const { if (ygg_node_type::list == get_type()) { return body->rbegin(); } else { return ygg_list::create().adopt_node(*this).rbegin(); } } inline ygg_const_reverse_iterator ygg_node::rend() const { if (ygg_node_type::list == get_type()) { return body->rend(); } else { return ygg_list::create().adopt_node(*this).rend(); } } // // yggNX // class ygg_root :public ygg_proto_list { friend class ygg_ghost; protected: ygg_root() {} ~ygg_root() { exile_node(operator[](ygg_term::node)); } ygg_string get_type() const; ygg_string get_name() const; ygg_node operator[](const ygg_string &path); bool match_path(const ygg_string &path) const; void adopt_node(ygg_node X); void exile_node(ygg_node X); ygg_node clone() const; public: static ygg_node create() { return new ygg_root; } static inline ygg_node parse_sox(const ygg_string &sox, sax_handler *sax = NULL); static inline ygg_node parse_xml(const ygg_string &xml, sax_handler *sax = NULL); }; inline ygg_node ygg_node::parse_sox(const ygg_string &sox, sax_handler *sax) { ygg_node node = ygg_root::parse_sox(sox, sax)[ygg_term::node]; // node.self_exile(); return node; } inline ygg_node ygg_node::parse_xml(const ygg_string &xml, sax_handler *sax) { return ygg_root::parse_xml(xml, sax)[ygg_term::node]; } // // yggvfNX // class ygg_element :public ygg_root { ygg_string name; protected: ygg_element() {} ygg_string get_type() const; ygg_string get_name() const; // ygg_string get_value() const; use ygg_list::get_value() // ygg_string get_text() const; use ygg_list::get_text() ygg_string get_xml(const ygg_string &indent = ygg_term::empty) const; ygg_string get_xml_attribute() const; ygg_string get_sox(const ygg_string &indent) const; bool match_path(const ygg_string &path) const; void set_name(const ygg_string &X); void set_value(const ygg_string &X); ygg_node clone() const; public: static ygg_node create() { return new ygg_element; } }; inline void ygg_node_body::regist_parent(ygg_root *X) { assert(NULL == parent); //assert(("m[heB 'em[h.exile_node(m[h)' A'm[h.close()' N[B", NULL == parent)); if (NULL != this && ygg_node_type::empty != get_type()) { parent = X; X->adopt_child(this); } } inline void ygg_node_body::unregist_parent(ygg_root *X) { if (NULL != this && ygg_node_type::empty != get_type()) { parent = NULL; X->exile_child(this); } } /****************************************************************************** Trick Library 'dagger' http://tricklib.com/cxx/dagger/ ******************************************************************************/ // // ygg_position // class ygg_position { public: //struct ygg_position { int line; int row; ygg_position(int X_line = 1, int X_row = 1) :line(X_line), row(X_row) {} ygg_position(const ygg_position &X) :line(X.line), row(X.row) {} ygg_position & set_line(int X_line = 1) { line = X_line; return *this; } ygg_position & set_row(int X_row = 1) { row = X_row; return *this; } ygg_position & set_position(int X_line = 1, int X_row = 1) { line = X_line; row = X_row; return *this; } ygg_position & set_position(const ygg_position &X) { line = X.line; row = X.row; return *this; } ygg_position & clear() { return set_position(); } const int get_line() const { return line; } const int get_row() const { return row; } ygg_position & next_line() { ++line; return set_row(); } const ygg_position operator+(const ygg_string &X) const { return ygg_position() += X; } ygg_position & operator+=(const ygg_string &X); }; // // ygg_error_term(1/2) // namespace ygg_error_term { const int genre = 0x01000000; const int category = 0x00010000; const int sequence = 0x00000100; const int sequence_case = 0x00000001; const ygg_string default_message = "G[B"; }; class ygg_error_code { protected: int value; public: ygg_error_code(int X_value = 0) :value(X_value) {} ygg_error_code(const ygg_error_code &X, int X_case = 0) :value(X.value +X_case) { assert(0 == X.get_sequence_case() || 0 == X_case); } bool is_error() const { return 0 != get_code(); } const int get_strict_code() const { return value; } const int get_code() const { return get_strict_code() & -0x100; } const int get_spectrum(int spectrum) const { return (get_strict_code() / spectrum) & 0xFF; } const int get_genre() const { return get_spectrum(ygg_error_term::genre); } const int get_category() const { return get_spectrum(ygg_error_term::category); } const int get_sequence() const { return get_spectrum(ygg_error_term::sequence); } const int get_sequence_case() const { return get_spectrum(ygg_error_term::sequence_case); } ygg_error_code & set_code(int X_value) { value = X_value; return *this; } ygg_error_code & set_code(const ygg_error_code &X) { value = X.value; return *this; } }; // // ygg_error_term(2/2) // namespace ygg_error_term { inline const ygg_error_code make_genre(int X_genre) { return X_genre *genre; } inline const ygg_error_code make_category(const ygg_error_code &X_genre, int X_category) { return X_genre.get_code() +X_category *category; } inline const ygg_error_code make_code(const ygg_error_code &X_category, int X_sequence, int X_sequence_case = 0) { return X_category.get_code() +X_sequence *sequence +X_sequence_case *sequence_case; } inline const ygg_error_code make_strict_code(const ygg_error_code &X_sequence, int X_sequence_case) { assert(0 == X_sequence.get_sequence_case()); return X_sequence.get_code() +X_sequence_case *sequence_case; } const ygg_error_code default_genre = make_genre(0x00); const ygg_error_code default_category = make_category(default_genre, 0x00); const ygg_error_code no_error = make_code(default_category, 0x00); const ygg_error_code default_error = make_code(default_category, 0x01); const ygg_error_code device = make_genre(0x01); const ygg_error_code file = make_category(device, 0x01); const ygg_error_code cannot_open_file = make_code(file, 0x01); const ygg_error_code stream = make_category(device, 0x02); const ygg_error_code invalid_stream = make_code(stream, 0x01); const ygg_error_code syntax = make_genre(0x02); const ygg_error_code ygg_syntax = make_category(syntax, 0x00); const ygg_error_code ygg_broken_char = make_code(ygg_syntax, 0x01); const ygg_error_code ygg_invalid_name = make_code(ygg_syntax, 0x02); const ygg_error_code ygg_invalid_name_a = make_strict_code(ygg_invalid_name, 0x01); const ygg_error_code ygg_invalid_name_b = make_strict_code(ygg_invalid_name, 0x02); const ygg_error_code duplication_attribute = make_code(ygg_syntax, 0x03); const ygg_error_code many_roots = make_code(ygg_syntax, 0x04); const ygg_error_code sox_syntax = make_category(syntax, 0x01); const ygg_error_code sox_deep_indent = make_code(sox_syntax, 0x01); const ygg_error_code xml_syntax = make_category(syntax, 0x02); const ygg_error_code unmatch_tags = make_code(xml_syntax, 0x01); const ygg_error_code unmatch_tags_a = make_strict_code(unmatch_tags, 0x01); const ygg_error_code unmatch_tags_b = make_strict_code(unmatch_tags, 0x02); const ygg_error_code csv_syntax = make_category(syntax, 0x03); const ygg_error_code memory = make_genre(0x03); const ygg_error_code user = make_genre(0x04); }; // // yggG[NX // class ygg_error :public ygg_error_code, public ygg_position { ygg_string message; public: ygg_error(const ygg_error &X) :ygg_error_code(X), ygg_position(X), message(X.message) {} ygg_error(const ygg_error_code &X = ygg_error_term::no_error, const ygg_position &X_position = ygg_position(0,0), const ygg_string &X_message = ygg_term::empty) :ygg_error_code(X), ygg_position(X_position), message(X_message) {} ygg_error & set_error(const ygg_error_code &X = ygg_error_term::no_error, const ygg_position &X_position = ygg_position(0,0), const ygg_string &X_message = ygg_term::empty) { set_code(X); set_position(X_position); message = X_message; return *this; } ygg_error & clear() { return set_error(); } const ygg_string & get_message() const { return message; } ygg_error & set_message(const ygg_string & X_message) { message = X_message; return *this; } }; // // SAXnh{NX // class sax_handler { friend class ygg_parser; ygg_parser *parser; void set_parser(ygg_parser *X_parser) { parser = X_parser; } protected: ygg_parser * get_parser(); public: virtual void on_error(ygg_error* parse_error); // parse_error->clear() virtual void start_document(ygg_node root); // Rgm[ht virtual void end_document(ygg_node &root); // root.vanish() AS virtual void start_element(ygg_node element); // S virtual void end_element(ygg_node element); // element.vanish() AelementS virtual void catch_text(ygg_node text); // text.set_value(...) virtual void catch_comment(ygg_node comment); // comment.set_value(...) }; // // // class error_catcher :public sax_handler { public: ygg_error parse_error; virtual ~error_catcher() {} void on_error(ygg_error* X_parse_error) { this->parse_error = *X_parse_error; } }; // // yggp[UNX // class ygg_parser { protected: ygg_position anchor_position, hot_position; sax_handler *sax; ygg_parser (sax_handler *X_sax = NULL) :anchor_position(), hot_position(), sax(X_sax) { if (sax) { sax->set_parser(this); } } const ygg_error_code check_name(const ygg_string &type, const ygg_string &X); const ygg_error_code check_element_name(const ygg_string &X) { return check_name("vf", X); } const ygg_error_code check_attribute_name(const ygg_string &X) { return check_name("", X); } public: ygg_error parse_error; ygg_parser * set_sax_handler(sax_handler *X_sax); const int get_line() const { return anchor_position.get_line(); } const int get_row() const { return anchor_position.get_row(); } void raise_error(const ygg_error_code &X_code = ygg_error_term::default_error, const ygg_string &X_message = ygg_error_term::default_message) { raise_error(X_code, anchor_position, X_message); } void raise_error(const ygg_error_code &X_code, const ygg_position &X_position, const ygg_string &X_message = ygg_error_term::default_message) { parse_error.set_error(X_code, X_position, X_message); if (sax) { sax->on_error(&parse_error); } } }; // // SOXp[UNX // class sox_parser :public ygg_parser { ygg_node &root; ygg_node hot_element; ygg_node last_node; ygg_node indent_node_list; int anchor_indent; ygg_string unparsed_buffer; public: sox_parser(ygg_node &X_root, sax_handler *X_sax = NULL) :ygg_parser(X_sax), root(X_root) {} sox_parser & set_sax_handler(sax_handler *X_sax) { set_sax_handler(X_sax); return *this; } #if defined(__YGGDRASIL_WITH_BABEL__) sox_parser & read(std::istream &stream, int encoding = babel::base_encoding::unknown); sox_parser & write(std::ostream &stream, int encoding = babel::base_encoding::unknown); sox_parser & load(const ygg_string &X_filename, int encoding = babel::base_encoding::unknown); sox_parser & save(const ygg_string &X_filename, int encoding = babel::base_encoding::unknown); #else // defined(__YGGDRASIL_WITH_BABEL__) sox_parser & read(std::istream &stream); sox_parser & write(std::ostream &stream); sox_parser & load(const ygg_string &X_filename); sox_parser & save(const ygg_string &X_filename); #endif // defined(__YGGDRASIL_WITH_BABEL__) sox_parser & init_root(); sox_parser & parse_line(const ygg_string &X_line); sox_parser & parse_string(const ygg_string &X_text); sox_parser & flush(); sox_parser & end_stream(); protected: void parse(const ygg_string &X_line); void catch_event(ygg_node node); }; #if defined(__YGGDRASIL_WITH_BABEL__) inline sox_parser & sox_parser::read(std::istream &stream, int encoding) { #else // defined(__YGGDRASIL_WITH_BABEL__) inline sox_parser & sox_parser::read(std::istream &stream) { #endif // defined(__YGGDRASIL_WITH_BABEL__) init_root(); if (!stream) { raise_error(ygg_error_term::invalid_stream, "Xg[wB"); } else { #if defined(__YGGDRASIL_WITH_BABEL__) using namespace babel; ygg_string::value_type first_buffer[4096]; ygg_string second_buffer, third_buffer; if (!stream.eof()) { stream.read(first_buffer, 4096); second_buffer.assign(first_buffer, stream.gcount()); const int determine_encoding = (babel::base_encoding::unknown == encoding) ? analyze_base_encoding(second_buffer): encoding; bbl_translater translater = manual_translate_engine::order(determine_encoding); while(true) { translater << second_buffer; translater >> third_buffer; parse_string(third_buffer); if (stream.eof() || parse_error.is_error()) { break; } stream.read(first_buffer, 1024); second_buffer.assign(first_buffer, stream.gcount()); } } #else // defined(__YGGDRASIL_WITH_BABEL__) ygg_string buffer; while(!stream.eof() && !parse_error.is_error()) { std::getline(stream, buffer); parse_line(buffer); } #endif // defined(__YGGDRASIL_WITH_BABEL__) } end_stream(); return *this; } #if defined(__YGGDRASIL_WITH_BABEL__) inline sox_parser & sox_parser::write(std::ostream &stream, int encoding) { using namespace babel; #else // defined(__YGGDRASIL_WITH_BABEL__) inline sox_parser & sox_parser::write(std::ostream &stream) { #endif // defined(__YGGDRASIL_WITH_BABEL__) if (!stream) { raise_error(ygg_error_term::invalid_stream, "Xg[wB"); return *this; // return } #if defined(__YGGDRASIL_WITH_BABEL__) stream << translate_to_binary(root.get_sox(), encoding); #else // defined(__YGGDRASIL_WITH_BABEL__) stream << root.get_sox(); #endif // defined(__YGGDRASIL_WITH_BABEL__) return *this; // return } #if defined(__YGGDRASIL_WITH_BABEL__) inline sox_parser & sox_parser::load(const ygg_string &X_filename, int encoding) { std::ifstream file(X_filename.c_str(), std::ios::binary); #else // defined(__YGGDRASIL_WITH_BABEL__) inline sox_parser & sox_parser::load(const ygg_string &X_filename) { std::ifstream file(X_filename.c_str()); #endif // defined(__YGGDRASIL_WITH_BABEL__) if (!file) { raise_error(ygg_error_term::cannot_open_file, "t@C " +X_filename +" JB"); return *this; // return } #if defined(__YGGDRASIL_WITH_BABEL__) return read(file, encoding); // return #else // defined(__YGGDRASIL_WITH_BABEL__) return read(file); // return #endif // defined(__YGGDRASIL_WITH_BABEL__) } #if defined(__YGGDRASIL_WITH_BABEL__) inline sox_parser & sox_parser::save(const ygg_string &X_filename, int encoding) { std::ofstream file(X_filename.c_str(), std::ios::binary); #else // defined(__YGGDRASIL_WITH_BABEL__) inline sox_parser & sox_parser::save(const ygg_string &X_filename) { std::ofstream file(X_filename.c_str()); #endif // defined(__YGGDRASIL_WITH_BABEL__) if (!file) { raise_error(ygg_error_term::cannot_open_file, "t@C " +X_filename +" JB"); return *this; // return } #if defined(__YGGDRASIL_WITH_BABEL__) return write(file, encoding); // return #else // defined(__YGGDRASIL_WITH_BABEL__) return write(file); // return #endif // defined(__YGGDRASIL_WITH_BABEL__) } // // // class sox_file :public ygg_node { ygg_string filename; public: ygg_error parse_error; sox_file(const ygg_string &X_filename) :filename(X_filename) {} ~sox_file() {} #if defined(__YGGDRASIL_WITH_BABEL__) sox_file & read(sax_handler *sax = NULL, int encoding = babel::base_encoding::unknown) { parse_error = sox_parser(*this, sax).load(filename, encoding).parse_error; #else // defined(__YGGDRASIL_WITH_BABEL__) sox_file & read(sax_handler *sax = NULL) { parse_error = sox_parser(*this, sax).load(filename).parse_error; #endif // defined(__YGGDRASIL_WITH_BABEL__) return *this; } #if defined(__YGGDRASIL_WITH_BABEL__) sox_file & write(int encoding = babel::base_encoding::unknown) { sox_parser(*this).save(filename, encoding); #else // defined(__YGGDRASIL_WITH_BABEL__) sox_file & write() { sox_parser(*this).save(filename); #endif // defined(__YGGDRASIL_WITH_BABEL__) return *this; } sox_file & set_filename(const ygg_string &X_filename) { filename = X_filename; return *this; } ygg_string get_filename() { return filename; } }; class sox_autofile :public sox_file { public: sox_autofile(const ygg_string &X_filename) :sox_file(X_filename) { read(); } ~sox_autofile() { write(); } }; class sox_stream :public ygg_node { public: ygg_error parse_error; #if defined(__YGGDRASIL_WITH_BABEL__) sox_stream & read(std::istream &stream, sax_handler *sax = NULL, int encoding = babel::base_encoding::unknown) { parse_error = sox_parser(*this, sax).read(stream, encoding).parse_error; #else // defined(__YGGDRASIL_WITH_BABEL__) sox_stream & read(std::istream &stream, sax_handler *sax = NULL) { parse_error = sox_parser(*this, sax).read(stream).parse_error; #endif // defined(__YGGDRASIL_WITH_BABEL__) return *this; } #if defined(__YGGDRASIL_WITH_BABEL__) sox_stream & write(std::ostream &stream, int encoding = babel::base_encoding::unknown) { parse_error = sox_parser(*this).write(stream, encoding).parse_error; #else // defined(__YGGDRASIL_WITH_BABEL__) sox_stream & write(std::ostream &stream) { parse_error = sox_parser(*this).write(stream).parse_error; #endif // defined(__YGGDRASIL_WITH_BABEL__) return *this; } }; #if defined(__YGGDRASIL_WITH_BABEL__) inline int get_encoding_from_label(const char *label) { using namespace babel::base_encoding; if (0 == stricmp(label, "shift-jis") || 0 == stricmp(label, "shift_jis") || 0 == stricmp(label, "x-sjis") || 0 == stricmp(label, "sjis") || 0 == stricmp(label, "shiftjis")) { return sjis; } if (0 == stricmp(label, "jis")) { return jis; } if (0 == stricmp(label, "iso-2022-jp")) { return iso2022jp; } if (0 == stricmp(label, "euc") || 0 == stricmp(label, "euc-jp") || 0 == stricmp(label, "x-euc")) { return euc; } if (0 == stricmp(label, "utf-8") || 0 == stricmp(label, "utf8")) { return utf8; } if (0 == stricmp(label, "utf-16") || 0 == stricmp(label, "utf16")) { return utf16; } if (0 == stricmp(label, "utf-16le") || 0 == stricmp(label, "utf16le")) { return utf16le; } if (0 == stricmp(label, "utf-16be") || 0 == stricmp(label, "utf16be")) { return utf16be; } if (0 == stricmp(label, "utf-32") || 0 == stricmp(label, "utf32")) { return utf32; } if (0 == stricmp(label, "utf-32le") || 0 == stricmp(label, "utf32le")) { return utf32le; } if (0 == stricmp(label, "utf-32be") || 0 == stricmp(label, "utf32be")) { return utf32be; } return unknown; } inline babel::bbl_translater get_translater(const ygg_string &header) { // zgev[gnY(mDM) ... bcc R(MDL)mI using namespace babel; using namespace babel::base_encoding; const ygg_string utf8_FEFF = "\xEF\xBB\xBF"; const int analyze_encoding = analyze_base_encoding(header); bbl_translater translater = manual_translate_engine::order(analyze_encoding); switch(analyze_encoding) { case utf8: if (0 != header.find(utf8_FEFF)) break; case utf16be: case utf16le: case utf32be: case utf32le: case jis: return translater; } const ygg_string encoding_label = ygg_root::parse_xml(translater(header))["/?xml/@encoding"].get_value().get_string(); const int label_encoding = get_encoding_from_label(encoding_label.c_str()); // encoding_label D if (unknown != label_encoding && analyze_encoding != label_encoding) { return manual_translate_engine::order(label_encoding); } else { return translater.clear(); } } #endif // defined(__YGGDRASIL_WITH_BABEL__) // // XMLp[UNX // class xml_parser :public ygg_parser { ygg_node &root; ygg_node hot_element; ygg_node last_node; ygg_node indent_node_list; int anchor_indent; ygg_string unparsed_buffer; public: xml_parser(ygg_node &X_root, sax_handler *X_sax = NULL) :ygg_parser(X_sax), root(X_root) {} xml_parser & set_sax_handler(sax_handler *X_sax) { set_sax_handler(X_sax); return *this; } xml_parser & read(std::istream &stream); xml_parser & write(std::ostream &stream); xml_parser & load(const ygg_string &X_filename); xml_parser & save(const ygg_string &X_filename); xml_parser & init_root(); xml_parser & parse_line(const ygg_string &X_line); xml_parser & parse_string(const ygg_string &X_text); xml_parser & flush(); xml_parser & end_stream(); }; inline xml_parser & xml_parser::read(std::istream &stream) { init_root(); if (!stream) { raise_error(ygg_error_term::invalid_stream, "Xg[wB"); } else { #if defined(__YGGDRASIL_WITH_BABEL__) using namespace babel; ygg_string::value_type first_buffer[1024]; ygg_string second_buffer, third_buffer; if (!stream.eof()) { stream.read(first_buffer, 1024); second_buffer.assign(first_buffer, stream.gcount()); bbl_translater translater = get_translater(second_buffer); while(true) { translater << second_buffer; translater >> third_buffer; parse_string(third_buffer); if (stream.eof() || parse_error.is_error()) { break; } stream.read(first_buffer, 1024); second_buffer.assign(first_buffer, stream.gcount()); } } #else // defined(__YGGDRASIL_WITH_BABEL__) ygg_string buffer; while(!stream.eof() && !parse_error.is_error()) { std::getline(stream, buffer); parse_line(buffer); } #endif // defined(__YGGDRASIL_WITH_BABEL__) } end_stream(); return *this; } inline xml_parser & xml_parser::write(std::ostream &stream) { #if defined(__YGGDRASIL_WITH_BABEL__) using namespace babel; #endif // defined(__YGGDRASIL_WITH_BABEL__) if (!stream) { raise_error(ygg_error_term::invalid_stream, "Xg[wB"); return *this; } #if defined(__YGGDRASIL_WITH_BABEL__) const ygg_string encoding_label = root["/?xml/@encoding"].get_value().get_string(); const int label_encoding = get_encoding_from_label(encoding_label.c_str()); stream << translate_to_binary(root.get_xml(), label_encoding); #else // defined(__YGGDRASIL_WITH_BABEL__) stream << root.get_xml(); #endif // defined(__YGGDRASIL_WITH_BABEL__) return *this; } inline xml_parser & xml_parser::load(const ygg_string &X_filename) { #if defined(__YGGDRASIL_WITH_BABEL__) std::ifstream file(X_filename.c_str(), std::ios::binary); #else // defined(__YGGDRASIL_WITH_BABEL__) std::ifstream file(X_filename.c_str()); #endif // defined(__YGGDRASIL_WITH_BABEL__) if (!file) { raise_error(ygg_error_term::cannot_open_file, "t@C " +X_filename +" JB"); return *this; } return read(file); } inline xml_parser & xml_parser::save(const ygg_string &X_filename) { #if defined(__YGGDRASIL_WITH_BABEL__) std::ofstream file(X_filename.c_str(), std::ios::binary); #else // defined(__YGGDRASIL_WITH_BABEL__) std::ofstream file(X_filename.c_str()); #endif // defined(__YGGDRASIL_WITH_BABEL__) if (!file) { raise_error(ygg_error_term::cannot_open_file, "t@C " +X_filename +" JB"); return *this; } return write(file); } // // // class xml_file :public ygg_node { ygg_string filename; public: ygg_error parse_error; xml_file(const ygg_string &X_filename) :filename(X_filename) {} ~xml_file() {} xml_file & read(sax_handler *sax = NULL) { parse_error = xml_parser(*this, sax).load(filename).parse_error; return *this; } xml_file & write() { xml_parser(*this).save(filename); return *this; } xml_file & set_filename(const ygg_string &X_filename) { filename = X_filename; return *this; } ygg_string get_filename() { return filename; } }; class xml_autofile :public xml_file { public: xml_autofile(const ygg_string &X_filename) :xml_file(X_filename) { read(); } ~xml_autofile() { write(); } }; class xml_stream :public ygg_node { public: ygg_error parse_error; xml_stream & read(std::istream &stream, sax_handler *sax = NULL) { parse_error = xml_parser(*this, sax).read(stream).parse_error; return *this; } xml_stream & write(std::ostream &stream) { parse_error = xml_parser(*this).write(stream).parse_error; return *this; } }; inline ygg_node ygg_root::parse_sox(const ygg_string &sox, sax_handler *sax) { ygg_node root; sox_parser(root, sax).init_root().parse_string(sox).end_stream(); return root; } inline ygg_node ygg_root::parse_xml(const ygg_string &xml, sax_handler *sax) { ygg_node root; xml_parser(root, sax).init_root().parse_string(xml).end_stream(); return root; } } // namespace yggdrasil #if defined(__BORLANDC__) # pragma warn .8022 # pragma warn .8026 # pragma warn .8027 #endif #endif // __YGGDRASIL_YGG_H__ /****************************************************************************** Wraith the Trickster `I'll go with heaven's advantage and fool's wisdom.` ******************************************************************************/ bulletml/src/ygg/.zhistory0000600000076400007640000000343107714245776013113 0ustar : 1049526665:0;d : 1049526678:0;cp ../Makefile . : 1049526680:0;vi Makefile : 1049526685:0;d : 1049526692:0;vi Makefile : 1049526754:0;d : 1049526757:0;make clean : 1049526757:0;d : 1049526759:0;s : 1049526790:20;./makedist : 1049526822:0;cd src/bulletml/ygg : 1049526822:0;d : 1049526822:0;la : 1049526830:0;rm csv.sox test.sox test.xml : 1049526830:0;d : 1049526834:0;rm ygg_test : 1049526834:0;d : 1049526835:0;la : 1049526837:0;s : 1049675700:0;cd src/bulletml/ygg : 1049675701:0;vi ygg.h : 1049675712:0;s : 1049675717:0;d : 1049675721:0;cvs add ygg.cc : 1049675722:0;cvs add ygg.cpp : 1049675724:0;cvs add ygg.h : 1049675727:0;cvs add Makefile : 1049675731:0;vi ygg.h : 1049675748:0;nkf -Lu ygg.h R ygg.h : 1049675771:0;vi ygg.cpp +1122 : 1049675793:0;emacs ygg.cpp +1122 : 1049675846:0;bfg : 1049675847:0;bg : 1049675852:0;nkf -Lu ygg.cpp R ygg.cpp : 1049675864:0;vi ygg.cpp +1122 : 1049675895:0;vi ygg.h +1712 : 1049675949:0;vi ygg.h +1849 : 1049675993:0;vi ygg.h +1852 : 1049676021:0;make : 1049676031:0;vi ygg.h +1400 : 1049676049:0;make : 1049675571:0;./bpo.exe : 1049675572:0;d : 1049675577:0;swgcc : 1049675580:0;make clean : 1049675922:1;cmake : 1049675986:0;make : 1049676065:0;cd src/bulletml/ygg : 1049676069:0;vi ygg.h +451 : 1049676092:0;make : 1049676103:0;vi ygg.h +1650 : 1049676134:0;make : 1049676146:0;vi ygg.cpp +1464 : 1049676159:0;nkf -e ygg.cpp R ygg.cpp : 1049676173:0;vi ygg.cpp +1855 : 1049676179:0;vi ygg.h +1855 : 1049676209:0;emacs ygg.h +1855 : 1049676226:0;vi ygg.h +1855 : 1049676310:0;vi ygg.cpp +263 : 1049676351:0;vi ygg.h : 1049676358:0;make L : 1049676359:0;d : 1049676361:0;rm ygg.o : 1049676363:0;make L : 1049676443:0;vi Makefile : 1049676458:0;make : 1049676461:0;rm ygg.o : 1049676461:0;make : 1049676467:0;s : 1049676532:0;s : 1049703714:0;vi Makefile : 1049703717:0;s bulletml/src/ygg/Makefile0000644000076400007640000000036207714245776012667 0ustar INCLUDES = -I../std -I.. LIBS = #CXXFLAGS = -g -W -Wall #CXXFLAGS = -pg -g -W -Wall CXXFLAGS = -O2 -W -Wall CFLAGS = -O2 OBJS = ygg.o all: $(OBJS) clean: rm -f *.o *.a $(OBJS): %.o: %.cpp $(CXX) -c $(CXXFLAGS) $(INCLUDES) $< distdir: bulletml/src/tinyxml/0000755000076400007640000000000007726413750012134 5ustar bulletml/src/tinyxml/readme.txt0000644000076400007640000001742307714246010014127 0ustar /** @mainpage TinyXml TinyXml is a simple, small, C++ XML parser that can be easily integrating into other programs. What it does. In brief, TinyXml parses an XML document, and builds from that a Document Object Model that can be read, modified, and saved. XML stands for "eXtensible Markup Language." It allows you to create your own document markups. Where HTML does a very good job of marking documents for browsers, XML allows you to define any kind of document markup, for example a document that describes a "to do" list for an organizer application. XML is a very structured and convenient format. All those random file formats created to store application data can all be replaced with XML. One parser for everything. There are different ways to access and interact with XML data. TinyXml uses a Document Object Model, meaning the XML data is parsed into a tree objects that can be browsed and manipulated, and then written back to disk. You can also construct an XML document from scratch with C++ objects and write this to disk. TinyXml is designed to be easy and fast. It is one header and three cpp files. Simply add these to your project and off you go. There is an example to get you started. It is released under the ZLib license, so you can use it in open source or commercial code. It attempts to be a flexible parser, but with truly correct and compliant XML output (with the exception of the character set, below.) TinyXml should compile on any reasonably C++ system. It does not rely on exceptions or RTTI, and only uses the STL string class. What it doesn't do. It doesnt parse or use DTDs (Document Type Definitions) or XSLs (eXtensible Stylesheet Language.) It is limited to the ASCII character set. There are other parsers out there (check out www.sourceforge.org, search for XML) that are much more fully featured. But they are also much bigger, take longer to set up in your project, have a higher learning curve, and have a more restrictive license. If you are working with browsers or have more complete XML needs, TinyXml is not the parser for you. Code Status. Currently in use, TinyXml is looking pretty stable. If you find bugs, send them in and we'll get them straightened out as soon as possible. It currently does not recognize "entity references", meaning special characters. This is a missing feature that will hopefully be included soon. Namely: @verbatim & & < < > > " " ' @endverbatim Using and Installing To Compile and Run xmltest: A Linux Makefile and a Windows Visual C++ .dsp file is provided. Simply compile and run. It will write the file demotest.xml to your disk and generate output on the screen. It also tests walking the DOM by printing out the number of nodes found using different techniques. The Linux makefile is very generic and will probably run on other systems, but is only tested on Linux. Make sure to run 'make depend' before you make, so you don't pick up incorrect dependencies. To Use in an Application: Add tinyxml.cpp, tinyxml.h, tinyxmlerror.cpp, and tinyxmlparser.cpp to your project or make file. That's it! It should compile on any reasonably compliant C++ system. You do not need to enable exceptions or RTTI for TinyXml. Where it may go. At this point, I'm focusing on tightening up remaining issues. Bug fixes (though comfortably rare) and minor interface corrections. On the "it would be nice if..." list is: - More intelligent (and consistent) parsing would be worthwhile; the parser is somewhat "organic" in its current form. - Entities. I'm not currently working on either; but would ethusiastically welcome a patch! In the future, I think it would be great if XSL and DTDs were added in some scalable way. So TinyXml would become a stand-alone core component of say MedXml (adding DTDs) and LargeXml( adding XSL.) :-) How TinyXml works. An example is probably the best way to go. Take: @verbatim Go to the Toy store! Do bills @endverbatim Its not much of a To Do list, but it will do. To read this file (say "demo.xml") you would create a document, and parse it in: @verbatim TiXmlDocument doc( "demo.xml" ); doc.LoadFile(); @endverbatim And its ready to go. Now lets look at some lines and how they relate to the DOM. The first line is a declaration, and gets turned into the TiXmlDeclaration class. It will be the first child of the document node. This is the only directive/special tag parsed by by TinyXml. Generally directive targs are stored in TiXmlUnknown so the commands wont be lost when it is saved back to disk. A comment. Will become a TiXmlComment object. The ToDo tag defines a TiXmlElement object. This one does not have any attributes, but will contain 2 other elements, both of which are items. Creates another TiXmlElement which is a child of the "ToDo" element. This element has 1 attribute, with the name priority and the value 1. Go to the A TiXmlText. This is a leaf node and cannot contain other nodes. It is a child of the Item" Element. Another TiXmlElement, this one a child of the "Item" element. Etc. Looking at the entire object tree, you end up with: @verbatim TiXmlDocument "demo.xml" TiXmlDeclaration "version='1.0'" "standalone=no" TiXmlComment " Our to do list data" TiXmlElement "ToDo" TiXmlElement "Item" Attribtutes: priority = 1 TiXmlText "Go to the " TiXmlElement "bold" TiXmlText "Toy store!" TiXmlElement "Item" Attributes: priority=2 TiXmlText "bills" @endverbatim Contributors Thanks very much to everyone who sends suggestions, bugs, ideas, and encouragement. It all helps. Major contributors to the project:
  • Lee Thomason wrote the original code and maintains the project.
  • Ayende Rahien presented code, ideas, and changes that became the 1.1.0 version of TinyXml.
  • Ville Nurmi provided ideas, bugs, and feedback.
Documentation The documentation is build with Doxygen, using the 'dox' configuration file. License TinyXml is released under the zlib license: This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages arising from the use of this software. Permission is granted to anyone to use this software for any purpose, including commercial applications, and to alter it and redistribute it freely, subject to the following restrictions: 1. The origin of this software must not be misrepresented; you must not claim that you wrote the original software. If you use this software in a product, an acknowledgment in the product documentation would be appreciated but is not required. 2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software. 3. This notice may not be removed or altered from any source distribution. References The World Wide Web Consortium is the definitive standard body for XML, and there web pages contain huge amounts of information. I also recommend "XML Pocket Reference" by Robert Eckstein and published by OReilly. Contact Me: Id appreciates your suggestions, and would love to know if you use TinyXml. I hope you enjoy it and find it useful. Lee Thomason leethomason@mindspring.com */ bulletml/src/tinyxml/xmltest.cpp0000644000076400007640000001353707714246010014337 0ustar #include "tinyxml.h" // // This file demonstrates some basic functionality of TinyXml. // Note that the example is very contrived. It presumes you know // what is in the XML file. But it does test the basic operations, // and show how to add and remove nodes. // int main() { // // We start with the 'demoStart' todo list. Process it. And // should hopefully end up with the todo list as illustrated. // const char* demoStart = "\n" "" "\n" " Go to the Toy store!" "" " Look for Evil Dinosaurs! " ""; /* What the todo list should look like after processing. Go to the Toy store! Talk to: Do bills */ // The example parses from the character string (above): { // Write to a file and read it back, to check file I/O. TiXmlDocument doc( "demotest.xml" ); doc.Parse( demoStart ); if ( doc.Error() ) { printf( "Error in %s: %s\n", doc.Value().c_str(), doc.ErrorDesc().c_str() ); exit( 1 ); } doc.SaveFile(); } TiXmlDocument doc( "demotest.xml" ); doc.LoadFile(); printf( "** Demo doc read from disk: ** \n\n" ); doc.Print( stdout ); TiXmlNode* node = 0; TiXmlElement* todoElement = 0; TiXmlElement* itemElement = 0; // -------------------------------------------------------- // An example of changing existing attributes, and removing // an element from the document. // -------------------------------------------------------- // Get the "ToDo" element. // It is a child of the document, and can be selected by name. node = doc.FirstChild( "ToDo" ); assert( node ); todoElement = node->ToElement(); assert( todoElement ); // Going to the toy store is now our second priority... // So set the "priority" attribute of the first item in the list. node = todoElement->FirstChild(); assert( node ); itemElement = node->ToElement(); assert( itemElement ); itemElement->SetAttribute( "priority", 2 ); // Change the distance to "doing bills" from // "none" to "here". It's the next sibling element. itemElement = itemElement->NextSiblingElement(); itemElement->SetAttribute( "distance", "here" ); // Remove the "Look for Evil Dinosours!" item. // It is 1 more sibling away. We ask the parent to remove // a particular child. itemElement = itemElement->NextSiblingElement(); todoElement->RemoveChild( itemElement ); itemElement = 0; // -------------------------------------------------------- // What follows is an example of created elements and text // nodes and adding them to the document. // -------------------------------------------------------- // Add some meetings. TiXmlElement item( "Item" ); item.SetAttribute( "priority", "1" ); item.SetAttribute( "distance", "far" ); TiXmlText text; text.SetValue( "Talk to:" ); TiXmlElement meeting1( "Meeting" ); meeting1.SetAttribute( "where", "School" ); TiXmlElement meeting2( "Meeting" ); meeting2.SetAttribute( "where", "Lunch" ); TiXmlElement attendee1( "Attendee" ); attendee1.SetAttribute( "name", "Marple" ); attendee1.SetAttribute( "position", "teacher" ); TiXmlElement attendee2( "Attendee" ); attendee2.SetAttribute( "name", "Voo" ); attendee2.SetAttribute( "position", "counselor" ); // Assemble the nodes we've created: meeting1.InsertEndChild( attendee1 ); meeting1.InsertEndChild( attendee2 ); item.InsertEndChild( text ); item.InsertEndChild( meeting1 ); item.InsertEndChild( meeting2 ); // And add the node to the existing list after the first child. node = todoElement->FirstChild( "Item" ); assert( node ); itemElement = node->ToElement(); assert( itemElement ); todoElement->InsertAfterChild( itemElement, item ); printf( "\n** Demo doc processed: ** \n\n" ); doc.Print( stdout ); // -------------------------------------------------------- // Different ways to walk the XML document. // -------------------------------------------------------- int count = 0; TiXmlElement* element; // Walk all the top level nodes of the document. count = 0; for( node = doc.FirstChild(); node; node = node->NextSibling() ) { count++; } printf( "The document contains %d top level nodes. (3)\n", count ); // Walk all the top level nodes of the document, // using a different sytax. count = 0; for( node = doc.IterateChildren( 0 ); node; node = doc.IterateChildren( node ) ) { count++; } printf( "The document contains %d top level nodes. (3)\n", count ); // Walk all the elements in a node. count = 0; for( element = todoElement->FirstChildElement(); element; element = element->NextSiblingElement() ) { count++; } printf( "The 'ToDo' element contains %d elements. (3)\n", count ); // Walk all the elements in a node by value. count = 0; for( node = todoElement->FirstChild( "Item" ); node; node = node->NextSibling( "Item" ) ) { count++; } printf( "The 'ToDo' element contains %d nodes with the value of 'Item'. (3)\n", count ); /* for( int i=0; i<1000; i++ ) doc.LoadFile( "SmallRuleset1.xml" ); doc.SaveFile( "smalltest.xml" ); */ return 0; } bulletml/src/tinyxml/tinyxml.h0000644000076400007640000005104407714246010014003 0ustar /* Copyright (c) 2000 Lee Thomason (www.grinninglizard.com) This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages arising from the use of this software. Permission is granted to anyone to use this software for any purpose, including commercial applications, and to alter it and redistribute it freely, subject to the following restrictions: 1. The origin of this software must not be misrepresented; you must not claim that you wrote the original software. If you use this software in a product, an acknowledgment in the product documentation would be appreciated but is not required. 2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software. 3. This notice may not be removed or altered from any source distribution. */ #ifndef TINYXML_INCLUDED #define TINYXML_INCLUDED #include #include #include class TiXmlDocument; class TiXmlElement; class TiXmlComment; class TiXmlUnknown; class TiXmlAttribute; class TiXmlText; class TiXmlDeclaration; /** TiXmlBase is a base class for every class in TinyXml. It does little except to establist that TinyXml classes can be printed and provide some utility functions. In XML, the document and elements can contain other elements and other types of nodes. @verbatim A Document can contain: Element (container or leaf) Comment (leaf) Unknown (leaf) Declaration( leaf ) An Element can contain: Element (container or leaf) Text (leaf) Attributes (not on tree) Comment (leaf) Unknown (leaf) A Decleration contains: Attributes (not on tree) @endverbatim */ class TiXmlBase { friend class TiXmlNode; friend class TiXmlElement; friend class TiXmlDocument; public: TiXmlBase() {} virtual ~TiXmlBase() {} /* All TinyXml classes can print themselves to a filestream. */ virtual void Print( FILE* fp, int depth ) = 0; protected: /* General parsing helper method. Takes a pointer in, skips all the white space it finds, and returns a pointer to the first non-whitespace data. */ static const char* SkipWhiteSpace( const char* p ); /* Reads an XML name into the string provided. Returns a pointer just past the last character of the name, or 0 if the function has an error. */ static const char* ReadName( const char* p, std::string* name ); /* Reads text. Returns a pointer past the given end tag. Wickedly complex options, but it keeps the (sensitive) code in one place. */ static const char* ReadText( const char* in, // where to start std::string* text, // the string read bool ignoreWhiteSpace, // whether to keep the white space const char* endTag, // what ends this text bool ignoreCase ); // whether to ignore case in the end tag enum { TIXML_NO_ERROR = 0, TIXML_ERROR_OPENING_FILE, TIXML_ERROR_OUT_OF_MEMORY, TIXML_ERROR_PARSING_ELEMENT, TIXML_ERROR_FAILED_TO_READ_ELEMENT_NAME, TIXML_ERROR_READING_ELEMENT_VALUE, TIXML_ERROR_READING_ATTRIBUTES, TIXML_ERROR_PARSING_EMPTY, TIXML_ERROR_READING_END_TAG, TIXML_ERROR_PARSING_UNKNOWN, TIXML_ERROR_PARSING_COMMENT, TIXML_ERROR_PARSING_DECLARATION, TIXML_ERROR_STRING_COUNT }; static const char* errorString[ TIXML_ERROR_STRING_COUNT ]; }; /** The parent class for everything in the Document Object Model. (Except for attributes, which are contained in elements.) Nodes have siblings, a parent, and children. A node can be in a document, or stand on its own. The type of a TyXmlNode can be queried, and it can be cast to its more defined type. */ class TiXmlNode : public TiXmlBase { public: /** The types of XML nodes supported by TinyXml. (All the unsupported types are picked up by UNKNOWN.) */ enum NodeType { DOCUMENT, ELEMENT, COMMENT, UNKNOWN, TEXT, DECLARATION, TYPECOUNT }; virtual ~TiXmlNode(); /** The meaning of 'value' changes for the specific type of TiXmlNode. @verbatim Document: filename of the xml file Element: name of the element Comment: the comment text Unknown: the tag contents Text: the text string @endverbatim The subclasses will wrap this function. */ const std::string& Value() const { return value; } /** Changes the value of the node. Defined as: @verbatim Document: filename of the xml file Element: name of the element Comment: the comment text Unknown: the tag contents Text: the text string @endverbatim */ void SetValue( const std::string& _value ) { value = _value; } /// Delete all the children of this node. Does not affect 'this'. void Clear(); /// One step up the DOM. TiXmlNode* Parent() const { return parent; } TiXmlNode* FirstChild() const { return firstChild; } ///< The first child of this node. Will be null if there are no children. TiXmlNode* FirstChild( const std::string& value ) const; ///< The first child of this node with the matching 'value'. Will be null if none found. TiXmlNode* LastChild() const { return lastChild; } /// The last child of this node. Will be null if there are no children. TiXmlNode* LastChild( const std::string& value ) const; /// The last child of this node matching 'value'. Will be null if there are no children. /** An alternate way to walk the children of a node. One way to iterate over nodes is: @verbatim for( child = parent->FirstChild(); child; child = child->NextSibling() ) @endverbatim IterateChildren does the same thing with the syntax: @verbatim child = 0; while( child = parent->IterateChildren( child ) ) @endverbatim IterateChildren takes the previous child as input and finds the next one. If the previous child is null, it returns the first. IterateChildren will return null when done. */ TiXmlNode* IterateChildren( TiXmlNode* previous ); /// This flavor of IterateChildren searches for children with a particular 'value' TiXmlNode* IterateChildren( const std::string& value, TiXmlNode* previous ); /** Add a new node related to this. Adds a child past the LastChild. Returns a pointer to the new object or NULL if an error occured. */ TiXmlNode* InsertEndChild( const TiXmlNode& addThis ); /** Add a new node related to this. Adds a child before the specified child. Returns a pointer to the new object or NULL if an error occured. */ TiXmlNode* InsertBeforeChild( TiXmlNode* beforeThis, const TiXmlNode& addThis ); /** Add a new node related to this. Adds a child after the specified child. Returns a pointer to the new object or NULL if an error occured. */ TiXmlNode* InsertAfterChild( TiXmlNode* afterThis, const TiXmlNode& addThis ); /** Replace a child of this node. Returns a pointer to the new object or NULL if an error occured. */ TiXmlNode* ReplaceChild( TiXmlNode* replaceThis, const TiXmlNode& withThis ); /// Delete a child of this node. bool RemoveChild( TiXmlNode* removeThis ); /// Navigate to a sibling node. TiXmlNode* PreviousSibling() const { return prev; } /// Navigate to a sibling node. TiXmlNode* PreviousSibling( const std::string& ) const; /// Navigate to a sibling node. TiXmlNode* NextSibling() const { return next; } /// Navigate to a sibling node with the given 'value'. TiXmlNode* NextSibling( const std::string& ) const; /** Convenience function to get through elements. Calls NextSibling and ToElement. Will skip all non-Element nodes. Returns 0 if there is not another element. */ TiXmlElement* NextSiblingElement() const; /** Convenience function to get through elements. Calls NextSibling and ToElement. Will skip all non-Element nodes. Returns 0 if there is not another element. */ TiXmlElement* NextSiblingElement( const std::string& ) const; /// Convenience function to get through elements. TiXmlElement* FirstChildElement() const; /// Convenience function to get through elements. TiXmlElement* FirstChildElement( const std::string& value ) const; /// Query the type (as an enumerated value, above) of this node. virtual int Type() { return type; } /** Return a pointer to the Document this node lives in. Returns null if not in a document. */ TiXmlDocument* GetDocument() const; TiXmlDocument* ToDocument() const { return ( type == DOCUMENT ) ? (TiXmlDocument*) this : 0; } ///< Cast to a more defined type. Will return null not of the requested type. TiXmlElement* ToElement() const { return ( type == ELEMENT ) ? (TiXmlElement*) this : 0; } ///< Cast to a more defined type. Will return null not of the requested type. TiXmlComment* ToComment() const { return ( type == COMMENT ) ? (TiXmlComment*) this : 0; } ///< Cast to a more defined type. Will return null not of the requested type. TiXmlUnknown* ToUnknown() const { return ( type == UNKNOWN ) ? (TiXmlUnknown*) this : 0; } ///< Cast to a more defined type. Will return null not of the requested type. TiXmlText* ToText() const { return ( type == TEXT ) ? (TiXmlText*) this : 0; } ///< Cast to a more defined type. Will return null not of the requested type. TiXmlDeclaration* ToDeclaration() const { return ( type == DECLARATION ) ? (TiXmlDeclaration*) this : 0; } ///< Cast to a more defined type. Will return null not of the requested type. virtual TiXmlNode* Clone() const = 0; protected: TiXmlNode( NodeType type ); virtual const char* Parse( const char* ) = 0; // The node is passed in by ownership. This object will delete it. TiXmlNode* LinkEndChild( TiXmlNode* addThis ); // Figure out what is at *p, and parse it. Return a node if // successful, and update p. TiXmlNode* IdentifyAndParse( const char** p ); void CopyToClone( TiXmlNode* target ) const { target->value = value; } TiXmlNode* parent; NodeType type; TiXmlNode* firstChild; TiXmlNode* lastChild; std::string value; TiXmlNode* prev; TiXmlNode* next; }; /** An attribute is a name-value pair. Elements have an arbitrary number of attributes, each with a unique name. @note The attributes are not TiXmlNodes, since they are not part of the tinyXML document object model. There are other suggested ways to look at this problem. @note Attributes have a parent */ class TiXmlAttribute : public TiXmlBase { friend class TiXmlAttributeSet; public: /// Construct an empty attribute. TiXmlAttribute() : prev( 0 ), next( 0 ) {} /// Construct an attribute with a name and value. TiXmlAttribute( const std::string& _name, const std::string& _value ) : name( _name ), value( _value ), prev( 0 ), next( 0 ) {} const std::string& Name() const { return name; } ///< Return the name of this attribute. const std::string& Value() const { return value; } ///< Return the value of this attribute. void SetName( const std::string& _name ) { name = _name; } ///< Set the name of this attribute. void SetValue( const std::string& _value ) { value = _value; } ///< Set the value. /// Get the next sibling attribute in the DOM. Returns null at end. TiXmlAttribute* Next(); /// Get the previous sibling attribute in the DOM. Returns null at beginning. TiXmlAttribute* Previous(); bool operator==( const TiXmlAttribute& rhs ) const { return rhs.name == name; } bool operator<( const TiXmlAttribute& rhs ) const { return name < rhs.name; } bool operator>( const TiXmlAttribute& rhs ) const { return name > rhs.name; } /* [internal use] Attribtue parsing starts: first letter of the name returns: the next char after the value end quote */ const char* Parse( const char* ); // [internal use] virtual void Print( FILE* fp, int depth ); // [internal use] // Set the document pointer so the attribute can report errors. void SetDocument( TiXmlDocument* doc ) { document = doc; } private: TiXmlDocument* document; // A pointer back to a document, for error reporting. std::string name; std::string value; TiXmlAttribute* prev; TiXmlAttribute* next; }; /* A class used to manage a group of attributes. It is only used internally, both by the ELEMENT and the DECLARATION. The set can be changed transparent to the Element and Declaration classes that use it, but NOT transparent to the Attribute which has to implement a next() and previous() method. Which makes it a bit problematic and prevents the use of STL. This version is implemented with circular lists because: - I like circular lists - it demonstrates some independence from the (typical) doubly linked list. */ class TiXmlAttributeSet { public: TiXmlAttributeSet(); ~TiXmlAttributeSet(); void Add( TiXmlAttribute* attribute ); void Remove( TiXmlAttribute* attribute ); TiXmlAttribute* First() const { return ( sentinel.next == &sentinel ) ? 0 : sentinel.next; } TiXmlAttribute* Last() const { return ( sentinel.prev == &sentinel ) ? 0 : sentinel.prev; } TiXmlAttribute* Find( const std::string& name ) const; private: TiXmlAttribute sentinel; }; /** The element is a container class. It has a value, the element name, and can contain other elements, text, comments, and unknowns. Elements also contain an arbitrary number of attributes. */ class TiXmlElement : public TiXmlNode { public: /// Construct an element. TiXmlElement( const std::string& value ); virtual ~TiXmlElement(); /** Given an attribute name, attribute returns the value for the attribute of that name, or null if none exists. */ const std::string* Attribute( const std::string& name ) const; /** Given an attribute name, attribute returns the value for the attribute of that name, or null if none exists. */ const std::string* Attribute( const std::string& name, int* i ) const; /** Sets an attribute of name to a given value. The attribute will be created if it does not exist, or changed if it does. */ void SetAttribute( const std::string& name, const std::string& value ); /** Sets an attribute of name to a given value. The attribute will be created if it does not exist, or changed if it does. */ void SetAttribute( const std::string& name, int value ); /** Deletes an attribute with the given name. */ void RemoveAttribute( const std::string& name ); TiXmlAttribute* FirstAttribute() { return attributeSet.First(); } ///< Access the first attribute in this element. TiXmlAttribute* LastAttribute() { return attributeSet.Last(); } ///< Access the last attribute in this element. // [internal use] Creates a new Element and returs it. virtual TiXmlNode* Clone() const; // [internal use] virtual void Print( FILE* fp, int depth ); protected: /* [internal use] Attribtue parsing starts: next char past '<' returns: next char past '>' */ virtual const char* Parse( const char* ); const char* ReadValue( const char* p ); private: TiXmlAttributeSet attributeSet; }; /** An XML comment. */ class TiXmlComment : public TiXmlNode { public: /// Constructs an empty comment. TiXmlComment() : TiXmlNode( TiXmlNode::COMMENT ) {} virtual ~TiXmlComment() {} // [internal use] Creates a new Element and returs it. virtual TiXmlNode* Clone() const; // [internal use] virtual void Print( FILE* fp, int depth ); protected: /* [internal use] Attribtue parsing starts: at the ! of the !-- returns: next char past '>' */ virtual const char* Parse( const char* ); }; /** XML text. Contained in an element. */ class TiXmlText : public TiXmlNode { public: TiXmlText() : TiXmlNode( TiXmlNode::TEXT ) {} virtual ~TiXmlText() {} // [internal use] Creates a new Element and returns it. virtual TiXmlNode* Clone() const; // [internal use] virtual void Print( FILE* fp, int depth ); // [internal use] bool Blank(); // returns true if all white space and new lines /* [internal use] Attribtue parsing starts: First char of the text returns: next char past '>' */ virtual const char* Parse( const char* ); }; /** XML Cdata section. Contained in an element. * Always start with */ class TiXmlCData : public TiXmlText { friend class TiXmlElement; public: /// Constructor. TiXmlCData () {} virtual ~TiXmlCData() {} protected : virtual const char* Parse( const char* p ); }; /** In correct XML the declaration is the first entry in the file. @verbatim @endverbatim TinyXml will happily read or write files without a declaration, however. There are 3 possible attributes to the declaration: version, encoding, and standalone. Note: In this version of the code, the attributes are handled as special cases, not generic attributes, simply because there can only be at most 3 and they are always the same. */ class TiXmlDeclaration : public TiXmlNode { public: /// Construct an empty declaration. TiXmlDeclaration() : TiXmlNode( TiXmlNode::DECLARATION ) {} /// Construct. TiXmlDeclaration( const std::string& version, const std::string& encoding, const std::string& standalone ); virtual ~TiXmlDeclaration() {} /// Version. Will return empty if none was found. const std::string& Version() { return version; } /// Encoding. Will return empty if none was found. const std::string& Encoding() { return encoding; } /// Is this a standalone document? const std::string& Standalone() { return standalone; } // [internal use] Creates a new Element and returs it. virtual TiXmlNode* Clone() const; // [internal use] virtual void Print( FILE* fp, int depth ); protected: // [internal use] // Attribtue parsing starts: next char past '<' // returns: next char past '>' virtual const char* Parse( const char* ); private: std::string version; std::string encoding; std::string standalone; }; /** Any tag that tinyXml doesn't recognize is save as an unknown. It is a tag of text, but should not be modified. It will be written back to the XML, unchanged, when the file is saved. */ class TiXmlUnknown : public TiXmlNode { public: TiXmlUnknown() : TiXmlNode( TiXmlNode::UNKNOWN ) {} virtual ~TiXmlUnknown() {} // [internal use] virtual TiXmlNode* Clone() const; // [internal use] virtual void Print( FILE* fp, int depth ); protected: /* [internal use] Attribute parsing starts: First char of the text returns: next char past '>' */ virtual const char* Parse( const char* ); }; /** Always the top level node. A document binds together all the XML pieces. It can be saved, loaded, and printed to the screen. The 'value' of a document node is the xml file name. */ class TiXmlDocument : public TiXmlNode { public: /// Create an empty document, that has no name. TiXmlDocument(); /// Create a document with a name. The name of the document is also the filename of the xml. TiXmlDocument( const std::string& documentName ); virtual ~TiXmlDocument() {} /** Load a file using the current document value. Returns true if successful. Will delete any existing document data before loading. */ bool LoadFile(); /// Save a file using the current document value. Returns true if successful. bool SaveFile(); /// Load a file using the given filename. Returns true if successful. bool LoadFile( const std::string& filename ); /// Save a file using the given filename. Returns true if successful. bool SaveFile( const std::string& filename ); /// Load a file using the given file pointer. Returns true if successful. bool LoadFile(FILE* fp); /// Parse the given null terminated block of xml data. const char* Parse( const char* ); /// If, during parsing, a error occurs, Error will be set to true. bool Error() { return error; } /// Contains a textual (english) description of the error if one occurs. const std::string& ErrorDesc() { return errorDesc; } /// Write the document to a file -- usually invoked by SaveFile. virtual void Print( FILE* fp, int depth = 0 ); /// Dump the document to standard out. void Print() { Print( stdout, 0 ); } // [internal use] virtual TiXmlNode* Clone() const; // [internal use] void SetError( int err ) { assert( err > 0 && err < TIXML_ERROR_STRING_COUNT ); error = true; errorId = err; errorDesc = errorString[ errorId ]; } private: bool error; int errorId; std::string errorDesc; }; #endif bulletml/src/tinyxml/demotest.xml0000644000076400007640000000050507714246010014470 0ustar Go to the Toy store! Do bills Look for Evil Dinosaurs! bulletml/src/tinyxml/tinyxml.cpp0000644000076400007640000003512107714246010014334 0ustar /* Copyright (c) 2000 Lee Thomason (www.grinninglizard.com) This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages arising from the use of this software. Permission is granted to anyone to use this software for any purpose, including commercial applications, and to alter it and redistribute it freely, subject to the following restrictions: 1. The origin of this software must not be misrepresented; you must not claim that you wrote the original software. If you use this software in a product, an acknowledgment in the product documentation would be appreciated but is not required. 2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software. 3. This notice may not be removed or altered from any source distribution. */ #include "tinyxml.h" TiXmlNode::TiXmlNode( NodeType _type ) { parent = 0; type = _type; firstChild = 0; lastChild = 0; prev = 0; next = 0; } TiXmlNode::~TiXmlNode() { TiXmlNode* node = firstChild; TiXmlNode* temp = 0; while ( node ) { temp = node; node = node->next; delete temp; } } void TiXmlNode::Clear() { TiXmlNode* node = firstChild; TiXmlNode* temp = 0; while ( node ) { temp = node; node = node->next; delete temp; } firstChild = 0; lastChild = 0; } TiXmlNode* TiXmlNode::LinkEndChild( TiXmlNode* node ) { node->parent = this; node->prev = lastChild; node->next = 0; if ( lastChild ) lastChild->next = node; else firstChild = node; // it was an empty list. lastChild = node; return node; } TiXmlNode* TiXmlNode::InsertEndChild( const TiXmlNode& addThis ) { TiXmlNode* node = addThis.Clone(); if ( !node ) return 0; return LinkEndChild( node ); } TiXmlNode* TiXmlNode::InsertBeforeChild( TiXmlNode* beforeThis, const TiXmlNode& addThis ) { if ( beforeThis->parent != this ) return 0; TiXmlNode* node = addThis.Clone(); if ( !node ) return 0; node->parent = this; node->next = beforeThis; node->prev = beforeThis->prev; beforeThis->prev->next = node; beforeThis->prev = node; return node; } TiXmlNode* TiXmlNode::InsertAfterChild( TiXmlNode* afterThis, const TiXmlNode& addThis ) { if ( afterThis->parent != this ) return 0; TiXmlNode* node = addThis.Clone(); if ( !node ) return 0; node->parent = this; node->prev = afterThis; node->next = afterThis->next; afterThis->next->prev = node; afterThis->next = node; return node; } TiXmlNode* TiXmlNode::ReplaceChild( TiXmlNode* replaceThis, const TiXmlNode& withThis ) { if ( replaceThis->parent != this ) return 0; TiXmlNode* node = withThis.Clone(); if ( !node ) return 0; node->next = replaceThis->next; node->prev = replaceThis->prev; if ( replaceThis->next ) replaceThis->next->prev = node; else lastChild = node; if ( replaceThis->prev ) replaceThis->prev->next = node; else firstChild = node; delete replaceThis; return node; } bool TiXmlNode::RemoveChild( TiXmlNode* removeThis ) { if ( removeThis->parent != this ) { assert( 0 ); return false; } if ( removeThis->next ) removeThis->next->prev = removeThis->prev; else lastChild = removeThis->prev; if ( removeThis->prev ) removeThis->prev->next = removeThis->next; else firstChild = removeThis->next; delete removeThis; return true; } TiXmlNode* TiXmlNode::FirstChild( const std::string& value ) const { TiXmlNode* node; for ( node = firstChild; node; node = node->next ) { if ( node->Value() == value ) return node; } return 0; } TiXmlNode* TiXmlNode::LastChild( const std::string& value ) const { TiXmlNode* node; for ( node = lastChild; node; node = node->prev ) { if ( node->Value() == value ) return node; } return 0; } TiXmlNode* TiXmlNode::IterateChildren( TiXmlNode* previous ) { if ( !previous ) { return FirstChild(); } else { assert( previous->parent == this ); return previous->NextSibling(); } } TiXmlNode* TiXmlNode::IterateChildren( const std::string& val, TiXmlNode* previous ) { if ( !previous ) { return FirstChild( val ); } else { assert( previous->parent == this ); return previous->NextSibling( val ); } } TiXmlNode* TiXmlNode::NextSibling( const std::string& value ) const { TiXmlNode* node; for ( node = next; node; node = node->next ) { if ( node->Value() == value ) return node; } return 0; } TiXmlNode* TiXmlNode::PreviousSibling( const std::string& value ) const { TiXmlNode* node; for ( node = prev; node; node = node->prev ) { if ( node->Value() == value ) return node; } return 0; } void TiXmlElement::RemoveAttribute( const std::string& name ) { TiXmlAttribute* node = attributeSet.Find( name ); if ( node ) { attributeSet.Remove( node ); delete node; } } TiXmlElement* TiXmlNode::FirstChildElement() const { TiXmlNode* node; for ( node = FirstChild(); node; node = node->NextSibling() ) { if ( node->ToElement() ) return node->ToElement(); } return 0; } TiXmlElement* TiXmlNode::FirstChildElement( const std::string& value ) const { TiXmlNode* node; for ( node = FirstChild( value ); node; node = node->NextSibling( value ) ) { if ( node->ToElement() ) return node->ToElement(); } return 0; } TiXmlElement* TiXmlNode::NextSiblingElement() const { TiXmlNode* node; for ( node = NextSibling(); node; node = node->NextSibling() ) { if ( node->ToElement() ) return node->ToElement(); } return 0; } TiXmlElement* TiXmlNode::NextSiblingElement( const std::string& value ) const { TiXmlNode* node; for ( node = NextSibling( value ); node; node = node->NextSibling( value ) ) { if ( node->ToElement() ) return node->ToElement(); } return 0; } TiXmlDocument* TiXmlNode::GetDocument() const { const TiXmlNode* node; for( node = this; node; node = node->parent ) { if ( node->ToDocument() ) return node->ToDocument(); } return 0; } // TiXmlElement::TiXmlElement() // : TiXmlNode( TiXmlNode::ELEMENT ) // { // } TiXmlElement::TiXmlElement( const std::string& _value ) : TiXmlNode( TiXmlNode::ELEMENT ) { firstChild = lastChild = 0; value = _value; } TiXmlElement::~TiXmlElement() { while( attributeSet.First() ) { TiXmlAttribute* node = attributeSet.First(); attributeSet.Remove( node ); delete node; } } const std::string* TiXmlElement::Attribute( const std::string& name ) const { TiXmlAttribute* node = attributeSet.Find( name ); if ( node ) return &(node->Value() ); return 0; } const std::string* TiXmlElement::Attribute( const std::string& name, int* i ) const { const std::string* s = Attribute( name ); if ( s ) *i = atoi( s->c_str() ); else *i = 0; return s; } void TiXmlElement::SetAttribute( const std::string& name, int val ) { char buf[64]; sprintf( buf, "%d", val ); std::string v = buf; SetAttribute( name, v ); } void TiXmlElement::SetAttribute( const std::string& name, const std::string& value ) { TiXmlAttribute* node = attributeSet.Find( name ); if ( node ) { node->SetValue( value ); return; } TiXmlAttribute* attrib = new TiXmlAttribute( name, value ); if ( attrib ) { attributeSet.Add( attrib ); } else { TiXmlDocument* document = GetDocument(); if ( document ) document->SetError( TIXML_ERROR_OUT_OF_MEMORY ); } } void TiXmlElement::Print( FILE* fp, int depth ) { int i; for ( i=0; iNext() ) { fprintf( fp, " " ); attrib->Print( fp, 0 ); } // If this node has children, give it a closing tag. Else // make it an empty tag. TiXmlNode* node; if ( firstChild ) { fprintf( fp, ">" ); for ( node = firstChild; node; node=node->NextSibling() ) { if ( !node->ToText() ) fprintf( fp, "\n" ); node->Print( fp, depth+1 ); } fprintf( fp, "\n" ); for ( i=0; i", value.c_str() ); } else { fprintf( fp, " />" ); } } TiXmlNode* TiXmlElement::Clone() const { TiXmlElement* clone = new TiXmlElement( Value() ); if ( !clone ) return 0; CopyToClone( clone ); // Clone the attributes, then clone the children. TiXmlAttribute* attribute = 0; for( attribute = attributeSet.First(); attribute; attribute = attribute->Next() ) { clone->SetAttribute( attribute->Name(), attribute->Value() ); } TiXmlNode* node = 0; for ( node = firstChild; node; node = node->NextSibling() ) { clone->LinkEndChild( node->Clone() ); } return clone; } TiXmlDocument::TiXmlDocument() : TiXmlNode( TiXmlNode::DOCUMENT ) { error = false; // factory = new TiXmlFactory(); } TiXmlDocument::TiXmlDocument( const std::string& documentName ) : TiXmlNode( TiXmlNode::DOCUMENT ) { // factory = new TiXmlFactory(); value = documentName; error = false; } // void TiXmlDocument::SetFactory( TiXmlFactory* f ) // { // delete factory; // factory = f; // } bool TiXmlDocument::LoadFile() { return LoadFile( value ); } bool TiXmlDocument::SaveFile() { return SaveFile( value ); } bool TiXmlDocument::LoadFile( FILE* fp ) { // Delete the existing data: Clear(); unsigned size, first; first = ftell( fp ); fseek( fp, 0, SEEK_END ); size = ftell( fp ) - first + 1; fseek( fp, first, SEEK_SET ); char* buf = new char[size]; char* p = buf; while( fgets( p, size, fp ) ) { p = strchr( p, 0 ); } fclose( fp ); Parse( buf ); delete [] buf; if ( !Error() ) return true; return false; } bool TiXmlDocument::LoadFile( const std::string& filename ) { // Delete the existing data: Clear(); // Load the new data: FILE* fp = fopen( filename.c_str(), "r" ); if ( fp ) { return LoadFile(fp); } else { SetError( TIXML_ERROR_OPENING_FILE ); } return false; } bool TiXmlDocument::SaveFile( const std::string& filename ) { FILE* fp = fopen( filename.c_str(), "w" ); if ( fp ) { Print( fp, 0 ); fclose( fp ); return true; } return false; } TiXmlNode* TiXmlDocument::Clone() const { TiXmlDocument* clone = new TiXmlDocument(); if ( !clone ) return 0; CopyToClone( clone ); clone->error = error; clone->errorDesc = errorDesc; TiXmlNode* node = 0; for ( node = firstChild; node; node = node->NextSibling() ) { clone->LinkEndChild( node->Clone() ); } return clone; } void TiXmlDocument::Print( FILE* fp, int ) { TiXmlNode* node; for ( node=FirstChild(); node; node=node->NextSibling() ) { node->Print( fp, 0 ); fprintf( fp, "\n" ); } } TiXmlAttribute* TiXmlAttribute::Next() { // We are using knowledge of the sentinel. The sentinel // have a value or name. if ( next->value.empty() && next->name.empty() ) return 0; return next; } TiXmlAttribute* TiXmlAttribute::Previous() { // We are using knowledge of the sentinel. The sentinel // have a value or name. if ( prev->value.empty() && prev->name.empty() ) return 0; return prev; } void TiXmlAttribute::Print( FILE* fp, int ) { if ( value.find( '\"' ) != std::string::npos ) fprintf( fp, "%s='%s'", name.c_str(), value.c_str() ); else fprintf( fp, "%s=\"%s\"", name.c_str(), value.c_str() ); } void TiXmlComment::Print( FILE* fp, int depth ) { for ( int i=0; i", value.c_str() ); } TiXmlNode* TiXmlComment::Clone() const { TiXmlComment* clone = new TiXmlComment(); if ( !clone ) return 0; CopyToClone( clone ); return clone; } void TiXmlText::Print( FILE* fp, int ) { fprintf( fp, "%s", value.c_str() ); } TiXmlNode* TiXmlText::Clone() const { TiXmlText* clone = 0; clone = new TiXmlText(); if ( !clone ) return 0; CopyToClone( clone ); return clone; } TiXmlDeclaration::TiXmlDeclaration( const std::string& _version, const std::string& _encoding, const std::string& _standalone ) : TiXmlNode( TiXmlNode::DECLARATION ) { version = _version; encoding = _encoding; standalone = _standalone; } void TiXmlDeclaration::Print( FILE* fp, int ) { std::string out = ""; fprintf( fp, "%s", out.c_str() ); } TiXmlNode* TiXmlDeclaration::Clone() const { TiXmlDeclaration* clone = new TiXmlDeclaration(); if ( !clone ) return 0; CopyToClone( clone ); clone->version = version; clone->encoding = encoding; clone->standalone = standalone; return clone; } void TiXmlUnknown::Print( FILE* fp, int depth ) { for ( int i=0; i", value.c_str() ); } TiXmlNode* TiXmlUnknown::Clone() const { TiXmlUnknown* clone = new TiXmlUnknown(); if ( !clone ) return 0; CopyToClone( clone ); return clone; } TiXmlAttributeSet::TiXmlAttributeSet() { sentinel.next = &sentinel; sentinel.prev = &sentinel; } TiXmlAttributeSet::~TiXmlAttributeSet() { assert( sentinel.next == &sentinel ); assert( sentinel.prev == &sentinel ); } void TiXmlAttributeSet::Add( TiXmlAttribute* addMe ) { assert( !Find( addMe->Name() ) ); // Shouldn't be multiply adding to the set. addMe->next = &sentinel; addMe->prev = sentinel.prev; sentinel.prev->next = addMe; sentinel.prev = addMe; } void TiXmlAttributeSet::Remove( TiXmlAttribute* removeMe ) { TiXmlAttribute* node; for( node = sentinel.next; node != &sentinel; node = node->next ) { if ( node == removeMe ) { node->prev->next = node->next; node->next->prev = node->prev; node->next = 0; node->prev = 0; return; } } assert( 0 ); // we tried to remove a non-linked attribute. } TiXmlAttribute* TiXmlAttributeSet::Find( const std::string& name ) const { TiXmlAttribute* node; for( node = sentinel.next; node != &sentinel; node = node->next ) { if ( node->Name() == name ) return node; } return 0; } bulletml/src/tinyxml/tinyxmlerror.cpp0000644000076400007640000000124007714246010015401 0ustar #include "tinyxml.h" // The goal of the seperate error file is to make the first // step towards localization. tinyxml (currently) only supports // latin-1, but at least the error messages could now be translated. // // It also cleans up the code a bit. const char* TiXmlBase::errorString[ TIXML_ERROR_STRING_COUNT ] = { "No error", "Failed to open file", "Memory allocation failed.", "Error parsing Element.", "Failed to read Element name", "Error reading Element value.", "Error reading Attributes.", "Error: empty tag.", "Error reading end tag.", "Error parsing Unknown.", "Error parsing Comment.", "Error parsing Declaration.", }; bulletml/src/tinyxml/changes.txt0000644000076400007640000000521407714246010014275 0ustar Changes in version 1.0.1: - Fixed comment tags which were outputing as ' include. Thanks to Steve Lhomme for that.bulletml/src/tinyxml/README-sdmkun.txt0000644000076400007640000000122307714246010015115 0ustar --- in English --- This TinyXML is NOT original version of TinyXML. This is hacked by me. You should not use this TinyXML, and if you want to get original version, go http://www.sourceforge.net/projects/tinyxml I hacked it with "Crystal Space 3D"'s source code for addition of CDATA support. http://crystal.sourceforge.net/drupal/ --- in japanese --- この TinyXML はオリジナルのバージョンではなくて、 私がいじったものです。 普通、この TinyXML を使うべきじゃなくて、以下のを使うべきです。 http://www.sourceforge.net/projects/tinyxml 私は "Crystal Space 3D" のソースコードを参考に CDATA セクション対応を行いました。 http://crystal.sourceforge.net/drupal/ bulletml/src/tinyxml/Makefile0000644000076400007640000000615607714246010013572 0ustar #**************************************************************************** # # Makefil for TinyXml test. # Lee Thomason # www.grinninglizard.com # # This is a GNU make (gmake) makefile #**************************************************************************** # DEBUG can be set to YES to include debugging info, or NO otherwise DEBUG := NO # PROFILE can be set to YES to include profiling info, or NO otherwise PROFILE := NO #**************************************************************************** CC := gcc CXX := g++ LD := g++ AR := ar rc RANLIB := ranlib DEBUG_CFLAGS := -Wall -Wno-unknown-pragmas -Wno-format -g -DDEBUG RELEASE_CFLAGS := -Wall -Wno-unknown-pragmas -Wno-format -O2 LIBS := DEBUG_CXXFLAGS := ${DEBUG_CFLAGS} RELEASE_CXXFLAGS := ${RELEASE_CFLAGS} DEBUG_LDFLAGS := -g RELEASE_LDFLAGS := ifeq (YES, ${DEBUG}) CFLAGS += ${DEBUG_CFLAGS} CXXFLAGS += ${DEBUG_CXXFLAGS} LDFLAGS += ${DEBUG_LDFLAGS} else CFLAGS += ${RELEASE_CFLAGS} CXXFLAGS += ${RELEASE_CXXFLAGS} LDFLAGS += ${RELEASE_LDFLAGS} endif ifeq (YES, ${PROFILE}) CFLAGS := ${CFLAGS} -pg CXXFLAGS := ${CXXFLAGS} -pg LDFLAGS := ${LDFLAGS} -pg endif #**************************************************************************** # Preprocessor directives #**************************************************************************** ifeq (YES, ${PROFILE}) DEFS := else DEFS := endif #**************************************************************************** # Include paths #**************************************************************************** #INCS := -I/usr/include/g++-2 -I/usr/local/include INCS := #**************************************************************************** # Makefile code common to all platforms #**************************************************************************** CFLAGS := ${CFLAGS} ${DEFS} CXXFLAGS := ${CXXFLAGS} ${DEFS} #**************************************************************************** # Targets of the build #**************************************************************************** OUTPUT := xmltest all: ${OUTPUT} #**************************************************************************** # Source files #**************************************************************************** SRCS := tinyxml.cpp tinyxmlparser.cpp xmltest.cpp tinyxmlerror.cpp # Add on the sources for libraries SRCS := ${SRCS} OBJS := $(addsuffix .o,$(basename ${SRCS})) #**************************************************************************** # Output #**************************************************************************** ${OUTPUT}: ${OBJS} ${LD} -o $@ ${LDFLAGS} ${OBJS} ${LIBS} ${EXTRA_LIBS} #**************************************************************************** # common rules #**************************************************************************** # Rules for compiling source files to object files %.o : %.cpp ${CXX} -c ${CXXFLAGS} ${INCS} $< -o $@ %.o : %.c ${CC} -c ${CFLAGS} ${INCS} $< -o $@ clean: -rm -f core ${OBJS} ${OUTPUT} depend: makedepend ${INCS} ${SRCS} distdir: bulletml/src/tinyxml/tinyxml.dsp0000644000076400007640000001046107714246010014340 0ustar # Microsoft Developer Studio Project File - Name="tinyxml" - Package Owner=<4> # Microsoft Developer Studio Generated Build File, Format Version 6.00 # ** DO NOT EDIT ** # TARGTYPE "Win32 (x86) Console Application" 0x0103 CFG=tinyxml - Win32 Debug !MESSAGE This is not a valid makefile. To build this project using NMAKE, !MESSAGE use the Export Makefile command and run !MESSAGE !MESSAGE NMAKE /f "tinyxml.mak". !MESSAGE !MESSAGE You can specify a configuration when running NMAKE !MESSAGE by defining the macro CFG on the command line. For example: !MESSAGE !MESSAGE NMAKE /f "tinyxml.mak" CFG="tinyxml - Win32 Debug" !MESSAGE !MESSAGE Possible choices for configuration are: !MESSAGE !MESSAGE "tinyxml - Win32 Release" (based on "Win32 (x86) Console Application") !MESSAGE "tinyxml - Win32 Debug" (based on "Win32 (x86) Console Application") !MESSAGE # Begin Project # PROP AllowPerConfigDependencies 0 # PROP Scc_ProjName "" # PROP Scc_LocalPath "" CPP=cl.exe RSC=rc.exe !IF "$(CFG)" == "tinyxml - Win32 Release" # PROP BASE Use_MFC 0 # PROP BASE Use_Debug_Libraries 0 # PROP BASE Output_Dir "Release" # PROP BASE Intermediate_Dir "Release" # PROP BASE Target_Dir "" # PROP Use_MFC 0 # PROP Use_Debug_Libraries 0 # PROP Output_Dir "Release" # PROP Intermediate_Dir "Release" # PROP Target_Dir "" # ADD BASE CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c # ADD CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c # ADD BASE RSC /l 0x409 /d "NDEBUG" # ADD RSC /l 0x409 /d "NDEBUG" BSC32=bscmake.exe # ADD BASE BSC32 /nologo # ADD BSC32 /nologo LINK32=link.exe # ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /machine:I386 # ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /machine:I386 !ELSEIF "$(CFG)" == "tinyxml - Win32 Debug" # PROP BASE Use_MFC 0 # PROP BASE Use_Debug_Libraries 1 # PROP BASE Output_Dir "Debug" # PROP BASE Intermediate_Dir "Debug" # PROP BASE Target_Dir "" # PROP Use_MFC 0 # PROP Use_Debug_Libraries 1 # PROP Output_Dir "Debug" # PROP Intermediate_Dir "Debug" # PROP Ignore_Export_Lib 0 # PROP Target_Dir "" # ADD BASE CPP /nologo /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /GZ /c # ADD CPP /nologo /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /FR /YX /FD /GZ /c # ADD BASE RSC /l 0x409 /d "_DEBUG" # ADD RSC /l 0x409 /d "_DEBUG" BSC32=bscmake.exe # ADD BASE BSC32 /nologo # ADD BSC32 /nologo LINK32=link.exe # ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /debug /machine:I386 /pdbtype:sept # ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /debug /machine:I386 /pdbtype:sept !ENDIF # Begin Target # Name "tinyxml - Win32 Release" # Name "tinyxml - Win32 Debug" # Begin Source File SOURCE=.\changes.txt # End Source File # Begin Source File SOURCE=.\readme.txt # End Source File # Begin Source File SOURCE=.\tinyxml.cpp # End Source File # Begin Source File SOURCE=.\tinyxml.h # End Source File # Begin Source File SOURCE=.\tinyxmlerror.cpp # End Source File # Begin Source File SOURCE=.\tinyxmlparser.cpp # End Source File # Begin Source File SOURCE=.\xmltest.cpp # End Source File # End Target # End Project bulletml/src/tinyxml/tinyxmlparser.cpp0000644000076400007640000003117507714246010015556 0ustar /* Copyright (c) 2000 Lee Thomason (www.grinninglizard.com) This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages arising from the use of this software. Permission is granted to anyone to use this software for any purpose, including commercial applications, and to alter it and redistribute it freely, subject to the following restrictions: 1. The origin of this software must not be misrepresented; you must not claim that you wrote the original software. If you use this software in a product, an acknowledgment in the product documentation would be appreciated but is not required. 2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software. 3. This notice may not be removed or altered from any source distribution. */ #include "tinyxml.h" #include const char* TiXmlBase::SkipWhiteSpace( const char* p ) { while ( p && *p && ( isspace( *p ) || *p == '\n' || *p == '\r' ) ) p++; return p; } const char* TiXmlBase::ReadName( const char* p, std::string* name ) { *name = ""; const char* start = p; // Names start with letters or underscores. // After that, they can be letters, underscores, numbers, // hyphens, or colons. (Colons are valid ony for namespaces, // but tinyxml can't tell namespaces from names.) if ( p && ( isalpha( *p ) || *p == '_' ) ) { p++; while( p && *p && ( isalnum( *p ) || *p == '_' || *p == '-' || *p == ':' ) ) { p++; } name->append( start, p - start ); return p; } return 0; } const char* TiXmlBase::ReadText( const char* p, std::string* text, bool trimWhiteSpace, const char* endTag, bool caseInsensitive ) { *text = ""; if ( !trimWhiteSpace // certain tags always keep whitespace /*|| !condenseWhiteSpace*/ ) // if true, whitespace is always kept { // Keep all the white space. while ( p && *p && strncmp( p, endTag, strlen(endTag) ) != 0 ) { char c = *(p++); (* text) += c; } } else { bool whitespace = false; // Remove leading white space: p = SkipWhiteSpace( p ); while ( p && *p && strncmp( p, endTag, strlen(endTag) ) != 0 ) { if ( *p == '\r' || *p == '\n' ) { whitespace = true; ++p; } else if ( isspace( *p ) ) { whitespace = true; ++p; } else { // If we've found whitespace, add it before the // new character. Any whitespace just becomes a space. if ( whitespace ) { (* text) += ' '; whitespace = false; } char c = *(p++); (* text) += c; } } } return p + strlen( endTag ); } const char* TiXmlDocument::Parse( const char* start ) { // Parse away, at the document level. Since a document // contains nothing but other tags, most of what happens // here is skipping white space. const char* p = start; p = SkipWhiteSpace( p ); if ( !p || !*p ) { error = true; errorDesc = "Document empty."; } while ( p && *p ) { if ( *p != '<' ) { error = true; errorDesc = "The '<' symbol that starts a tag was not found."; break; } else { TiXmlNode* node = IdentifyAndParse( &p ); if ( node ) { LinkEndChild( node ); } } p = SkipWhiteSpace( p ); } return 0; // Return null is fine for a document: once it is read, the parsing is over. } TiXmlNode* TiXmlNode::IdentifyAndParse( const char** where ) { const char* p = *where; TiXmlNode* returnNode = 0; assert( *p == '<' ); TiXmlDocument* doc = GetDocument(); p = SkipWhiteSpace( p+1 ); // What is this thing? // - Elements start with a letter or underscore, but xml is reserved. // - Comments: " ); if ( !end ) { TiXmlDocument* document = GetDocument(); if ( document ) document->SetError( TIXML_ERROR_PARSING_COMMENT ); return 0; } else { // Assemble the comment, removing the white space. bool whiteSpace = false; const char* q; for( q=start; q' } } const char* TiXmlAttribute::Parse( const char* p ) { // Read the name, the '=' and the value. p = ReadName( p, &name ); if ( !p ) { if ( document ) document->SetError( TIXML_ERROR_READING_ATTRIBUTES ); return 0; } p = SkipWhiteSpace( p ); if ( !p || *p != '=' ) { if ( document ) document->SetError( TIXML_ERROR_READING_ATTRIBUTES ); return 0; } p = SkipWhiteSpace( p+1 ); if ( !p || !*p ) { if ( document ) document->SetError( TIXML_ERROR_READING_ATTRIBUTES ); return 0; } const char* end = 0; const char* start = p+1; const char* past = 0; if ( *p == '\'' ) { end = strchr( start, '\'' ); past = end+1; } else if ( *p == '"' ) { end = strchr( start, '"' ); past = end+1; } else { // All attribute values should be in single or double quotes. // But this is such a common error that the parser will try // its best, even without them. start--; for ( end = start; *end; end++ ) { if ( isspace( *end ) || *end == '/' || *end == '>' ) break; } past = end; } value = std::string( start, end-start ); return past; } const char* TiXmlText::Parse( const char* p ) { value = ""; bool ignoreWhite = true; const char* end = "<"; p = ReadText( p, &value, ignoreWhite, end, false ); if ( p ) return p-1; // don't truncate the '<' return 0; #if 0 // Remove leading white space: p = SkipWhiteSpace( p ); while ( *p && *p != '<' ) { if ( *p == '\r' || *p == '\n' ) { whitespace = true; } else if ( isspace( *p ) ) { whitespace = true; } else { // If we've found whitespace, add it before the // new character. Any whitespace just becomes a space. if ( whitespace ) { value += ' '; whitespace = false; } value += *p; } p++; } // Keep white space before the '<' if ( whitespace ) value += ' '; return p; #endif } const char* TiXmlCData::Parse( const char* p ) { value = ""; bool ignoreWhite = false; p += 8; const char* end = "]]>"; p = ReadText( p, &value, ignoreWhite, end, false ); if ( p ) return p; return 0; } const char* TiXmlDeclaration::Parse( const char* p ) { // Find the beginning, find the end, and look for // the stuff in-between. const char* start = p+4; const char* end = strstr( start, "?>" ); // Be nice to the user: if ( !end ) { end = strstr( start, ">" ); end++; } else { end += 2; } if ( !end ) { TiXmlDocument* document = GetDocument(); if ( document ) document->SetError( TIXML_ERROR_PARSING_DECLARATION ); return 0; } else { const char* p; p = strstr( start, "version" ); if ( p && p < end ) { TiXmlAttribute attrib; attrib.Parse( p ); version = attrib.Value(); } p = strstr( start, "encoding" ); if ( p && p < end ) { TiXmlAttribute attrib; attrib.Parse( p ); encoding = attrib.Value(); } p = strstr( start, "standalone" ); if ( p && p < end ) { TiXmlAttribute attrib; attrib.Parse( p ); standalone = attrib.Value(); } } return end; } bool TiXmlText::Blank() { for ( unsigned i=0; i #include #include std::string BulletMLNode::name2string[nameSize] = { "bullet", "action", "fire", "changeDirection", "changeSpeed", "accel", "wait", "repeat", "bulletRef", "actionRef", "fireRef", "vanish", "horizontal", "vertical", "term", "times", "direction", "speed", "param", "bulletml" }; BulletMLNode::Type BulletMLNode::string2type(const std::string& str) { if (str == "aim") return aim; else if (str == "absolute") return absolute; else if (str == "relative") return relative; else if (str == "sequence") return sequence; else BulletMLError::doAssert( std::string("BulletML parser: unknown type ") + str + "."); return typeSize; // not reach } BulletMLNode::Name BulletMLNode::string2name(const std::string& str) { if (str == "bulletml") return bulletml; else if (str == "bullet") return bullet; else if (str == "action") return action; else if (str == "fire") return fire; else if (str == "changeDirection") return changeDirection; else if (str == "changeSpeed") return changeSpeed; else if (str == "accel") return accel; else if (str == "vanish") return vanish; else if (str == "wait") return wait; else if (str == "repeat") return repeat; else if (str == "direction") return direction; else if (str == "speed") return speed; else if (str == "horizontal") return horizontal; else if (str == "vertical") return vertical; else if (str == "term") return term; else if (str == "bulletRef") return bulletRef; else if (str == "actionRef") return actionRef; else if (str == "fireRef") return fireRef; else if (str == "param") return param; else if (str == "times") return times; else BulletMLError::doAssert( std::string("BulletML parser: unknown tag ") + str + "."); return nameSize; // not reach } BulletMLNode::BulletMLNode(const std::string& name) : name_(string2name(name)), type_(none) { setReleaseDuty(true); } BulletMLNode::~BulletMLNode() {} void BulletMLNode::setValue(const std::string& val) { auto_ptr_copy(val_, calc(val)); } void BulletMLNode::dump() { #if 0 std::cout << "<" << name2string[name_]; /* AttributeMap::const_iterator ite; for (ite = attributes_.begin(); ite != attributes_.end(); ite++) { std::cout << " " << ite->first << "=" << ite->second; } */ std::cout << ">" << std::endl; /* if (val_ != "") std::cout << val_ << std::endl; */ std::for_each(childBegin(), childEnd(), std::mem_fun(&BulletMLNode::dump)); std::cout << "" << std::endl; #endif } BulletMLNode* BulletMLNode::getChild(Name name) { ChildIterator ite; for (ite = childBegin(); ite != childEnd(); ite++) { if ((*ite)->getName() == name) return *ite; } return 0; } bool BulletMLNode::findNode(Name name) const { if (getName() == name) return true; ConstChildIterator ite; for (ite = childBegin(); ite != childEnd(); ite++) { if ((*ite)->findNode(name)) return true; } return false; } BulletMLNode* BulletMLNode::next() { BulletMLNode* parent = getParent(); if (parent == 0) return 0; ChildIterator ite = std::find(parent->childBegin(), parent->childEnd(), this); BulletMLError::doAssert(ite != parent->childEnd(), name_ + ": not found"); ite++; if (ite == parent->childEnd()) return 0; else return *ite; } void BulletMLNode::getAllChildrenVec(Name name, std::vector& outvec) { ChildIterator ite; for (ite = childBegin(); ite != childEnd(); ite++) { if ((*ite)->getName() == name) outvec.push_back(*ite); } } bulletml/src/bulletmlrunner.cpp0000644000076400007640000000266007726413361014210 0ustar #include "bulletmlrunner.h" #include "bulletmlparser.h" #include "bulletmlerror.h" #include "formula-variables.h" #include "bulletmlrunnerimpl.h" BulletMLRunner::BulletMLRunner(BulletMLParser* bulletml) { const std::vector& acts = bulletml->getTopActions(); for (size_t i = 0; i < acts.size(); i++) { std::vector act; act.push_back(acts[i]); BulletMLState* state = new BulletMLState(bulletml, act, boost::shared_ptr()); impl_.push_back(makeImpl(state)); } } BulletMLRunner::BulletMLRunner(BulletMLState* state) { impl_.push_back(makeImpl(state)); } BulletMLRunner::~BulletMLRunner() { for (size_t i = 0; i < impl_.size(); i++) { delete impl_[i]; } } void BulletMLRunner::run() { /* std::for_each(impl_.begin(), impl_.end(), std::mem_fun(&BulletMLRunnerImpl::run)); */ for (std::vector::const_iterator ite = impl_.begin(); ite != impl_.end(); ++ite) { (*ite)->run(); } } bool BulletMLRunner::isEnd() const { /* return std::find_if(impl_.begin(), impl_.end(), std::not1(std::mem_fun(&BulletMLRunnerImpl::isEnd))) == impl_.end(); */ for (std::vector::const_iterator ite = impl_.begin(); ite != impl_.end(); ++ite) { if ((*ite)->isEnd()) return true; } return false; } BulletMLRunnerImpl* BulletMLRunner::makeImpl(BulletMLState* state) { return new BulletMLRunnerImpl(state, this); } bulletml/src/Makefile0000644000076400007640000000123207715004710012054 0ustar CC = g++ INCLUDES = -I. LIBS = tinyxml/tinyxml.o tinyxml/tinyxmlparser.o tinyxml/tinyxmlerror.o #CXXFLAGS = -g -W -Wall -ansi -pedantic #CXXFLAGS = -pg -g -W -Wall -ansi -pedantic CXXFLAGS = -O2 -W -Wall -ansi -pedantic CFLAGS = -O2 OBJS = bulletmlparser-tinyxml.o bulletmlparser.o bulletmltree.o calc.o formula-variables.o bulletmlrunner.o bulletmlrunnerimpl.o all: libbulletml.a libbulletml.a: $(OBJS) $(MAKE) -C tinyxml $(AR) -r libbulletml.a *.o tinyxml/tiny*.o clean: rm -f *.o *.a $(MAKE) -C tinyxml clean calc.cpp: calc.yy bison -y calc.yy && mv y.tab.c calc.cpp $(OBJS): %.o: %.cpp $(CC) -c $(CXXFLAGS) $(INCLUDES) $< doxy: doxygen distdir: bulletml/src/sstream-0000644000076400007640000001703107715004725012104 0ustar /* This is part of libio/iostream, providing -*- C++ -*- input/output. Copyright (C) 2000 Free Software Foundation This file is part of the GNU IO Library. This library is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2, or (at your option) any later version. This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this library; see the file COPYING. If not, write to the Free Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. As a special exception, if you link this library with files compiled with a GNU compiler to produce an executable, this does not cause the resulting executable to be covered by the GNU General Public License. This exception does not however invalidate any other reasons why the executable file might be covered by the GNU General Public License. */ /* Written by Magnus Fromreide (magfr@lysator.liu.se). */ #ifndef __SSTREAM__ #define __SSTREAM__ #include #include #include namespace std { class stringbuf : public streambuf { public: typedef char char_type; typedef int int_type; typedef streampos pos_type; typedef streamoff off_type; explicit stringbuf(int which=ios::in|ios::out) : streambuf(which), buf(), mode(static_cast(which)), rpos(0), bufsize(1) { } explicit stringbuf(const std::string &s, int which=ios::in|ios::out) : streambuf(which), buf(s), mode(static_cast(which)), bufsize(1) { if(mode & ios::in) { setg(&defbuf, &defbuf + bufsize, &defbuf + bufsize); } if(mode & ios::out) { setp(&defbuf, &defbuf + bufsize); } rpos = (mode & ios::ate ? s.size() : 0); } std::string str() const { const_cast(this)->sync(); // Sigh, really ugly hack return buf; }; void str(const std::string& s) { buf = s; if(mode & ios::in) { gbump(egptr() - gptr()); } if(mode & ios::out) { pbump(pbase() - pptr()); } rpos = (mode & ios::ate ? s.size() : 0); } inline streampos seekoff(streamoff o, _seek_dir d, int mode=ios::in|ios::out); inline streampos seekpos(streampos pos, int mode = ios::in|ios::out); protected: inline virtual int sync(); inline virtual int overflow(int = EOF); inline virtual int underflow(); private: std::string buf; ios::open_mode mode; std::string::size_type rpos; streamsize bufsize; char defbuf; }; class stringstreambase : virtual public ios { protected: stringbuf __my_sb; public: std::string str() const { return dynamic_cast(_strbuf)->str(); } void str(const std::string& s) { clear(); dynamic_cast(_strbuf)->str(s); } stringbuf* rdbuf() { return &__my_sb; } protected: stringstreambase(int which) : __my_sb(which) { init (&__my_sb); } stringstreambase(const std::string& s, int which) : __my_sb(s, which) { init (&__my_sb); } }; class istringstream : public stringstreambase, public istream { public: istringstream(int which=ios::in) : stringstreambase(which) { } istringstream(const std::string& s, int which=ios::in) : stringstreambase(s, which) { } istringstream& seekg(streampos pos) { pos = __my_sb.seekpos(pos, ios::in); if (pos == streampos(EOF)) set(ios::badbit); return *this; } istringstream& seekg(streamoff off, _seek_dir dir) { off = __my_sb.seekoff(off, dir, ios::in); if (off == streamoff(EOF)) set(ios::badbit); return *this; } streampos tellg() { streampos pos = __my_sb.seekoff(0, ios::cur, ios::in); if (pos == streampos(EOF)) set(ios::badbit); return pos; } }; class ostringstream : public stringstreambase, public ostream { public: ostringstream(int which=ios::out) : stringstreambase(which) { } ostringstream(const std::string& s, int which=ios::out) : stringstreambase(s, which) { } ostringstream& seekp(streampos pos) { pos = __my_sb.seekpos(pos, ios::out); if (pos == streampos(EOF)) set(ios::badbit); return *this; } ostringstream& seekp(streamoff off, _seek_dir dir) { off = __my_sb.seekoff(off, dir, ios::out); if (off == streamoff(EOF)) set(ios::badbit); return *this; } streampos tellp() { streampos pos = __my_sb.seekoff(0, ios::cur, ios::out); if (pos == streampos(EOF)) set(ios::badbit); return pos; } }; class stringstream : public stringstreambase, public iostream { public: stringstream(int which=ios::in|ios::out) : stringstreambase(which) { } stringstream(const std::string &s, int which=ios::in|ios::out) : stringstreambase(s, which) { } stringstream& seekg(streampos pos) { pos = __my_sb.seekpos(pos, ios::in); if (pos == streampos(EOF)) set(ios::badbit); return *this; } stringstream& seekg(streamoff off, _seek_dir dir) { off = __my_sb.seekoff(off, dir, ios::in); if (off == streamoff(EOF)) set(ios::badbit); return *this; } streampos tellg() { streampos pos = __my_sb.seekoff(0, ios::cur, ios::in); if (pos == streampos(EOF)) set(ios::badbit); return pos; } stringstream& seekp(streampos pos) { pos = __my_sb.seekpos(pos, ios::out); if (pos == streampos(EOF)) set(ios::badbit); return *this; } stringstream& seekp(streamoff off, _seek_dir dir) { off = __my_sb.seekoff(off, dir, ios::out); if (off == streamoff(EOF)) set(ios::badbit); return *this; } streampos tellp() { streampos pos = __my_sb.seekoff(0, ios::cur, ios::out); if (pos == streampos(EOF)) set(ios::badbit); return pos; } }; } inline int std::stringbuf::sync() { if((mode & ios::out) == 0) return EOF; streamsize n = pptr() - pbase(); if(n) { buf.replace(rpos, std::string::npos, pbase(), n); if(buf.size() - rpos != (std::string::size_type) n) return EOF; rpos += n; pbump(-n); gbump(egptr() - gptr()); } return 0; } inline int std::stringbuf::overflow(int ch) { if((mode & ios::out) == 0) return EOF; streamsize n = pptr() - pbase(); if(n && sync()) return EOF; if(ch != EOF) { buf.replace(rpos, std::string::npos, ch); ++rpos; } return 0; } inline int std::stringbuf::underflow() { sync(); if((mode & ios::in) == 0) { return EOF; } if(rpos >= buf.size()) { return EOF; } std::string::size_type n = egptr() - eback(); std::string::size_type s; s = buf.copy(eback(), n, rpos); pbump(pbase() - pptr()); gbump(eback() - gptr()); int res = (0377 & buf[rpos]); rpos += s; return res; } inline streampos std::stringbuf::seekoff(streamoff o, _seek_dir d, int mode) { sync(); streamoff newpos = rpos; switch (d) { case ios::beg: newpos = o; break; case ios::cur: if ((mode & (ios::in|ios::out)) == (ios::in|ios::out)) return streampos(EOF); newpos += o; break; case ios::end: newpos = buf.size() + o; break; } if (newpos < 0 || newpos > buf.size()) return streampos(EOF); rpos = newpos; return newpos; } inline streampos std::stringbuf::seekpos(streampos pos, int mode) { return seekoff(pos, ios::beg, mode); } #endif /* not __STRSTREAM__ */ bulletml/src/bulletmlrunner.h0000644000076400007640000001044307726413362013654 0ustar /// BulletML タs /** * gF * BulletMLRunner pzタB */ #ifndef BULLETRUNNER_H_ #define BULLETRUNNER_H_ #include "bulletmltree.h" #include "bulletmlcommon.h" #include #include class BulletMLParser; class BulletMLNode; class BulletMLRunnerImpl; typedef std::vector BulletMLParameter; /// BulletMLRunner `BgpNX class BulletMLState { public: DECLSPEC BulletMLState(BulletMLParser* bulletml, const std::vector& node, boost::shared_ptr para) : bulletml_(bulletml), node_(node.begin(), node.end()), para_(para) {} DECLSPEC BulletMLParser* getBulletML() { return bulletml_; } DECLSPEC const std::vector& getNode() const { return node_; } DECLSPEC boost::shared_ptr getParameter() { return para_; } private: BulletMLParser* bulletml_; std::vector node_; boost::shared_ptr para_; }; /// BulletML タsNX /** *
 * gB
 *  1. pABullet タNXB
 *  2. zSタB
 *  3. KvAchangeDirection KvzタB
 *  4. NXIuWFNgAcom_->run(); B
 * 
*/ class BulletMLRunner { public: DECLSPEC explicit BulletMLRunner(BulletMLParser* bulletml); DECLSPEC explicit BulletMLRunner(BulletMLState* state); DECLSPEC virtual ~BulletMLRunner(); /// タs DECLSPEC void run(); public: /// タsI DECLSPEC bool isEnd() const; public: // ----- タQn ----- //@{ /// epx /** * @return pxxPA 0 v */ DECLSPEC virtual double getBulletDirection() =0; /// eゥ@_px /** * @return pxxPA 0 v */ DECLSPEC virtual double getAimDirection() =0; /// ex DECLSPEC virtual double getBulletSpeed() =0; /// ftHgx DECLSPEC virtual double getDefaultSpeed() =0; /// N /** * @return 0 1 タ */ DECLSPEC virtual double getRank() =0; /// action e DECLSPEC virtual void createSimpleBullet(double direction, double speed) =0; /// action e /** * @param state * Ve BulletMLRunner RXgN^nB * nAdelete B */ DECLSPEC virtual void createBullet(BulletMLState* state, double direction, double speed) =0; /// e^[lAt[ /** * @return * Q[I[_[X\A * B * xml f[^Await term I[_[B */ DECLSPEC virtual int getTurn() =0; /// DECLSPEC virtual void doVanish() =0; //@} // ----- タQI ----- // ----- KvタQn ----- //@{ /// ewX DECLSPEC virtual void doChangeDirection(double) {} /// exwlX DECLSPEC virtual void doChangeSpeed(double) {} /// accel C^[tFCX /** * @todo * horizontal, vertical type タB * absolute B */ DECLSPEC virtual void doAccelX(double) {} /// accel C^[tFCX /** * @todo * horizontal, vertical type タB * absolute B */ DECLSPEC virtual void doAccelY(double) {} /// e X /** * accel gI[o[Ch */ DECLSPEC virtual double getBulletSpeedX() { return 0; } /// e Y /** * accel gI[o[Ch */ DECLSPEC virtual double getBulletSpeedY() { return 0; } //@} // ----- KvタQI ----- /// /** * AftHg std::rand pB */ DECLSPEC virtual double getRand() { return (double)rand() / RAND_MAX; } private: /// BulletMLRunnerImpl I[o[ChAI[o[Ch DECLSPEC virtual BulletMLRunnerImpl* makeImpl(BulletMLState* state); protected: std::vector impl_; }; #endif // ! BULLETRUNNER_H_ bulletml/bulletml.dsp0000644000076400007640000001563107726414210012167 0ustar # Microsoft Developer Studio Project File - Name="bulletml" - Package Owner=<4> # Microsoft Developer Studio Generated Build File, Format Version 6.00 # ** W ** # TARGTYPE "Win32 (x86) Dynamic-Link Library" 0x0102 CFG=bulletml - Win32 Debug !MESSAGE L頒恩箕荷B 面炳灼個靄湶爪 NMAKE gpB !MESSAGE [匆弧Р夢現累按] 栽歡gpタs !MESSAGE !MESSAGE NMAKE /f "bulletml.mak". !MESSAGE !MESSAGE NMAKE タs\w !MESSAGE 栽歡 弉渡雇`B: !MESSAGE !MESSAGE NMAKE /f "bulletml.mak" CFG="bulletml - Win32 Debug" !MESSAGE !MESSAGE I\繁湶爪 唹爪: !MESSAGE !MESSAGE "bulletml - Win32 Release" ("Win32 (x86) Dynamic-Link Library" p) !MESSAGE "bulletml - Win32 Debug" ("Win32 (x86) Dynamic-Link Library" p) !MESSAGE # Begin Project # PROP AllowPerConfigDependencies 0 # PROP Scc_ProjName "" # PROP Scc_LocalPath "" CPP=cl.exe MTL=midl.exe RSC=rc.exe !IF "$(CFG)" == "bulletml - Win32 Release" # PROP BASE Use_MFC 0 # PROP BASE Use_Debug_Libraries 0 # PROP BASE Output_Dir "Release" # PROP BASE Intermediate_Dir "Release" # PROP BASE Target_Dir "" # PROP Use_MFC 0 # PROP Use_Debug_Libraries 0 # PROP Output_Dir "Release" # PROP Intermediate_Dir "Release" # PROP Target_Dir "" # ADD BASE CPP /nologo /MT /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "BULLETML_EXPORTS" /Yu"stdafx.h" /FD /c # ADD CPP /nologo /MT /W3 /GR /GX /O2 /I "src" /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "BULLETML_EXPORTS" /D "WIN32_DLL_EXPORT" /FD /c # SUBTRACT CPP /YX /Yc /Yu # ADD BASE MTL /nologo /D "NDEBUG" /mktyplib203 /win32 # ADD MTL /nologo /D "NDEBUG" /mktyplib203 /win32 # ADD BASE RSC /l 0x411 /d "NDEBUG" # ADD RSC /l 0x411 /d "NDEBUG" BSC32=bscmake.exe # ADD BASE BSC32 /nologo # ADD BSC32 /nologo LINK32=link.exe # ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /dll /machine:I386 # ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /dll /machine:I386 !ELSEIF "$(CFG)" == "bulletml - Win32 Debug" # PROP BASE Use_MFC 0 # PROP BASE Use_Debug_Libraries 1 # PROP BASE Output_Dir "Debug" # PROP BASE Intermediate_Dir "Debug" # PROP BASE Target_Dir "" # PROP Use_MFC 0 # PROP Use_Debug_Libraries 1 # PROP Output_Dir "Debug" # PROP Intermediate_Dir "Debug" # PROP Ignore_Export_Lib 0 # PROP Target_Dir "" # ADD BASE CPP /nologo /MTd /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "BULLETML_EXPORTS" /Yu"stdafx.h" /FD /GZ /c # ADD CPP /nologo /MTd /W3 /Gm /GR /GX /ZI /Od /I "src" /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "BULLETML_EXPORTS" /D "WIN32_DLL_EXPORT" /FD /GZ /c # ADD BASE MTL /nologo /D "_DEBUG" /mktyplib203 /win32 # ADD MTL /nologo /D "_DEBUG" /mktyplib203 /win32 # ADD BASE RSC /l 0x411 /d "_DEBUG" # ADD RSC /l 0x411 /d "_DEBUG" BSC32=bscmake.exe # ADD BASE BSC32 /nologo # ADD BSC32 /nologo LINK32=link.exe # ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /dll /debug /machine:I386 /pdbtype:sept # ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /dll /debug /machine:I386 /pdbtype:sept !ENDIF # Begin Target # Name "bulletml - Win32 Release" # Name "bulletml - Win32 Debug" # Begin Group "Source Files" # PROP Default_Filter "cpp;c;cxx;rc;def;r;odl;idl;hpj;bat" # Begin Group "libBulletML src" # PROP Default_Filter "" # Begin Source File SOURCE=.\bulletml.cpp # End Source File # Begin Source File SOURCE=".\src\bulletmlparser-tinyxml.cpp" # End Source File # Begin Source File SOURCE=".\src\bulletmlparser-xerces.cpp" # End Source File # Begin Source File SOURCE=".\src\bulletmlparser-ygg.cpp" # End Source File # Begin Source File SOURCE=.\src\bulletmlparser.cpp # End Source File # Begin Source File SOURCE=.\src\bulletmlrunner.cpp # End Source File # Begin Source File SOURCE=.\src\bulletmlrunnerimpl.cpp # End Source File # Begin Source File SOURCE=.\src\bulletmltree.cpp # End Source File # Begin Source File SOURCE=.\src\calc.cpp # End Source File # Begin Source File SOURCE=".\src\formula-variables.cpp" # End Source File # End Group # Begin Group "TinyXML src" # PROP Default_Filter "" # Begin Source File SOURCE=.\src\tinyxml\tinyxml.cpp # End Source File # Begin Source File SOURCE=.\src\tinyxml\tinyxmlerror.cpp # End Source File # Begin Source File SOURCE=.\src\tinyxml\tinyxmlparser.cpp # End Source File # End Group # Begin Group "ygg src" # PROP Default_Filter "" # Begin Source File SOURCE=.\src\ygg\ygg.cpp # End Source File # End Group # Begin Source File SOURCE=.\StdAfx.cpp # ADD CPP /Yc"stdafx.h" # End Source File # End Group # Begin Group "Header Files" # PROP Default_Filter "h;hpp;hxx;hm;inl" # Begin Group "libBulletML header" # PROP Default_Filter "" # Begin Source File SOURCE=.\src\auto_ptr_fix.h # End Source File # Begin Source File SOURCE=.\bulletml.h # End Source File # Begin Source File SOURCE=.\src\bulletmlcommon.h # End Source File # Begin Source File SOURCE=.\src\bulletmlerror.h # End Source File # Begin Source File SOURCE=".\src\bulletmlparser-tinyxml.h" # End Source File # Begin Source File SOURCE=".\src\bulletmlparser-xerces.h" # End Source File # Begin Source File SOURCE=".\src\bulletmlparser-ygg.h" # End Source File # Begin Source File SOURCE=.\src\bulletmlparser.h # End Source File # Begin Source File SOURCE=.\src\bulletmlrunner.h # End Source File # Begin Source File SOURCE=.\src\bulletmlrunnerimpl.h # End Source File # Begin Source File SOURCE=.\src\bulletmltree.h # End Source File # Begin Source File SOURCE=.\src\calc.h # End Source File # Begin Source File SOURCE=".\src\formula-variables.h" # End Source File # Begin Source File SOURCE=.\src\formula.h # End Source File # Begin Source File SOURCE=.\src\tree.h # End Source File # End Group # Begin Group "TinyXML header" # PROP Default_Filter "" # Begin Source File SOURCE=.\src\tinyxml\tinyxml.h # End Source File # End Group # Begin Group "ygg header" # PROP Default_Filter "" # Begin Source File SOURCE=.\src\ygg\ygg.h # End Source File # End Group # Begin Source File SOURCE=.\StdAfx.h # End Source File # End Group # Begin Group "Resource Files" # PROP Default_Filter "ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe" # End Group # Begin Source File SOURCE=.\ReadMe.txt # End Source File # End Target # End Project bulletml/libbulletml.dsw0000644000076400007640000000104707726415420012665 0ustar Microsoft Developer Studio Workspace File, Format Version 6.00 # x: 目宛粛澎 箕荷 W! ############################################################################### Project: "libbulletml"=.\libbulletml.dsp - Package Owner=<4> Package=<5> {{{ }}} Package=<4> {{{ }}} ############################################################################### Global: Package=<5> {{{ }}} Package=<3> {{{ }}} ############################################################################### bulletml/bulletml.cpp0000644000076400007640000000143707726416166012176 0ustar // bulletml.cpp : DLL AvP[VpGg |Cg`B // #include "stdafx.h" #include "bulletml.h" BOOL APIENTRY DllMain( HANDLE hModule, DWORD ul_reason_for_call, LPVOID lpReserved ) { switch (ul_reason_for_call) { case DLL_PROCESS_ATTACH: case DLL_THREAD_ATTACH: case DLL_THREAD_DETACH: case DLL_PROCESS_DETACH: break; } return TRUE; } // GNX|[gB BULLETML_API int nBulletml=0; // GNX|[gB BULLETML_API int fnBulletml(void) { return 42; } // GNX|[gNXRXgN^B // NX` bulletml.h QB CBulletml::CBulletml() { return; } bulletml/d_cpp/0000755000076400007640000000000007733636445010734 5ustar bulletml/d_cpp/cpp.cpp0000644000076400007640000000510407733165167012220 0ustar class C { public: C() {} C(int a) : a_(a) {} int a() const { return a_; } void setA(int a) { a_ = a; } void f2(int, int) {} void f3(int, int, int) {} void f4(int, int, int, int) {} void f5(int, int, int, int, int) {} void f6(int, int, int, int, int, int) {} void f7(int, int, int, int, int, int, int) {} void f8(int, int, int, int, int, int, int, int) {} void f9(int, int, int, int, int, int, int, int, int) {} void over_load(int a) { a_ = a; } void over_load(char a) { a_ = a-48; } static int sf0() { return 6; } static int sf1(int) { return 7; } private: int a_; }; template class TC { public: T_ f() { return 5; } template T2_ tf() { return 6; } }; class I { public: int load_callback() { return callback(); } int load_callback2(int x, int y) { return callback2(x, y); } virtual int callback() =0; virtual int callback2(int, int) =0; }; #include "d_cpp_interface.h" extern "C" { D_CPP_CLASS(C, D_C) D_CPP_NEW_0(C, D_C_new) D_CPP_NEW_1(C, D_C_new_1, int) D_CPP_DELETE(C, D_C_delete) D_CPP_METHOD_0(C, a, D_C_a, int) D_CPP_METHOD_1(C, setA, D_C_setA, void, int) D_CPP_METHOD_2(C, f2, D_C_f2, void, int, int) D_CPP_METHOD_3(C, f3, D_C_f3, void, int, int, int) D_CPP_METHOD_4(C, f4, D_C_f4, void, int, int, int, int) D_CPP_METHOD_5(C, f5, D_C_f5, void, int, int, int, int, int) D_CPP_METHOD_6(C, f6, D_C_f6, void, int, int, int, int, int, int) D_CPP_METHOD_7(C, f7, D_C_f7, void, int, int, int, int, int, int, int) D_CPP_METHOD_8(C, f8, D_C_f8, void, int, int, int, int, int, int, int, int) D_CPP_METHOD_9(C, f9, D_C_f9, void, int, int, int, int, int, int, int, int, int) D_CPP_METHOD_1(C, over_load, D_C_over_load_int, void, int) D_CPP_METHOD_1(C, over_load, D_C_over_load_char, void, char) D_CPP_CLASS(TC, D_TC_int) D_CPP_NEW_0(TC, D_TC_int_new) D_CPP_METHOD_0(TC, f, D_TC_int_f, int) D_CPP_METHOD_0(TC, tf, D_TC_int_tf, int) D_CPP_DELETE(TC, D_TC_int_delete) D_CPP_STATIC_METHOD_0(C, sf0, D_C_sf0, int) D_CPP_STATIC_METHOD_1(C, sf1, D_C_sf1, int, int) } // inherit D_CPP_BASE_CLASS_OPEN(I, D_I) D_CPP_VIRTUAL_METHOD_0(D_I, callback, int) D_CPP_VIRTUAL_METHOD_2(D_I, callback2, int, int, int) D_CPP_BASE_CLASS_CLOSE() extern "C" { D_CPP_CLASS(D_I, D_I) D_CPP_NEW_0(D_I, D_I_new) D_CPP_METHOD_0(D_I, load_callback, D_I_load_callback, int) D_CPP_METHOD_2(D_I, load_callback2, D_I_load_callback2, int, int, int) D_CPP_VIRTUAL_METHOD_SETTER_0(D_I, callback, D_I_setCallbackFunc, int) D_CPP_VIRTUAL_METHOD_SETTER_2(D_I, callback2, D_I_setCallback2Func, int, int, int) D_CPP_DELETE(D_I, D_I_delete) } bulletml/d_cpp/cpp_test.d0000644000076400007640000000171007733165226012713 0ustar import cpp_inter; import stream; import string; extern (C) { int return7(D_I* i) { return 7; } int add(D_I* i, int x, int y) { return x+y; } } int main() { D_C* c = D_C_new_1(1); stdout.writeLine(string.toString(D_C_a(c))); D_C_delete(c); c = D_C_new(); D_C_setA(c, 2); stdout.writeLine(string.toString(D_C_a(c))); D_C_f2(c, 0, 0); D_C_f5(c, 0,0,0,0,0); D_C_f9(c, 0,0,0,0,0,0,0,0,0); D_C_over_load_int(c, 3); stdout.writeLine(string.toString(D_C_a(c))); D_C_over_load_char(c, '4'); stdout.writeLine(string.toString(D_C_a(c))); D_TC_int* tc = D_TC_int_new(); stdout.writeLine(string.toString(D_TC_int_f(tc))); stdout.writeLine(string.toString(D_TC_int_tf(tc))); D_C_delete(c); D_TC_int_delete(tc); D_I* i = D_I_new(); D_I_setCallbackFunc(i, &return7); D_I_setCallback2Func(i, &add); stdout.writeLine(string.toString(D_I_load_callback(i))); stdout.writeLine(string.toString(D_I_load_callback2(i, 3, 5))); D_I_delete(i); return 0; } bulletml/d_cpp/Makefile.win320000644000076400007640000000057507733201144013324 0ustar CXX=sc DMD=dmd PERL=perl CPPFLAGS=-g DFLAGS=-g all: cpp_test cpp_test: cpp.obj cpp_test.obj $(DMD) cpp_test $(CPPFLAGS) cpp.obj cpp.obj: d_cpp_interface.h cpp.cpp $(CXX) $(CPPFLAGS) -c cpp.cpp cpp_test.obj: cpp_inter.d cpp_test.d $(DMD) $(DFLAGS) -c cpp_test.d cpp_inter.d: cpp.cpp $(PERL) create_d_import.pl cpp.cpp cpp_inter.d clean: rm -f *.obj cpp_test cpp_inter.d bulletml/d_cpp/create_d_cpp_interface.pl0000644000076400007640000000565707732735563015736 0ustar use strict; print "#define D_CPP_CLASS(CLASS, CLASS_NAME) ;\n"; print "\n"; for (my $i = 0; $i < 10; $i++) { print "#define D_CPP_NEW_$i(CLASS, NEW_NAME"; my @args; my @args2; for (my $j = 1; $j <= $i; $j++) { print ", ARG$j"; push @args, "ARG$j arg$j"; push @args2, "arg$j"; } print ") \\\n"; my $argStr = join ', ', @args; my $argStr2 = join ', ', @args2; print "CLASS* NEW_NAME($argStr) { \\\n"; print " return new CLASS($argStr2); \\\n"; print "}\n"; print "\n"; } print "#define D_CPP_DELETE(CLASS, DELETE_NAME) \\\n"; print "void DELETE_NAME(CLASS* c) { delete c; } \n"; print "\n"; for (my $i = 0; $i < 10; $i++) { print "#define D_CPP_METHOD_$i(CLASS, METHOD, METHOD_NAME, RETURN"; my $argStr; my @args2; for (my $j = 1; $j <= $i; $j++) { print ", ARG$j"; $argStr .= ", ARG$j arg$j"; push @args2, "arg$j"; } print ") \\\n"; my $argStr2 = join ', ', @args2; print "RETURN METHOD_NAME(CLASS* c$argStr) { \\\n"; print " return c->METHOD($argStr2); \\\n"; print "}\n"; print "\n"; } for (my $i = 0; $i < 10; $i++) { print "#define D_CPP_STATIC_METHOD_$i(CLASS, METHOD, METHOD_NAME, RETURN"; my @args; my @args2; for (my $j = 1; $j <= $i; $j++) { print ", ARG$j"; push @args, "ARG$j arg$j"; push @args2, "arg$j"; } print ") \\\n"; my $argStr = join ', ', @args;; my $argStr2 = join ', ', @args2; print "RETURN METHOD_NAME($argStr) { \\\n"; print " return CLASS::METHOD($argStr2); \\\n"; print "}\n"; print "\n"; } print "#define D_CPP_BASE_CLASS_OPEN(BASE, BASE_NAME) \\\n"; print "struct BASE_NAME : public BASE { \n"; for (my $i = 0; $i < 10; $i++) { print "#define D_CPP_VIRTUAL_METHOD_$i(CLASS, METHOD, RETURN"; my @args; my @args2; my @args3; for (my $j = 1; $j <= $i; $j++) { print ", ARG$j"; push @args, "ARG$j arg$j"; push @args2, ", arg$j"; push @args3, ", ARG$j"; } print ") \\\n"; my $argStr = join ', ', @args;; my $argStr2 = join '', @args2; my $argStr3 = join '', @args3; print " virtual RETURN METHOD($argStr) { \\\n"; print " return D_##METHOD##_fp(this $argStr2); \\\n"; print " } \\\n"; print " void D_set_##METHOD(RETURN (*fp) (CLASS* $argStr3)) { \\\n"; print " D_##METHOD##_fp = fp; \\\n"; print " } \\\n"; print " RETURN (*D_##METHOD##_fp) (CLASS*$argStr3); \n"; print "\n"; } for (my $i = 0; $i < 10; $i++) { print "#define D_CPP_VIRTUAL_METHOD_SETTER_$i(CLASS, METHOD, SETTER_NAME, RETURN"; my @args; my @args2; my @args3; for (my $j = 1; $j <= $i; $j++) { print ", ARG$j"; push @args, "ARG$j arg$j"; push @args2, ", arg$j"; push @args3, ", ARG$j"; } print ") \\\n"; my $argStr = join ', ', @args;; my $argStr2 = join '', @args2; my $argStr3 = join '', @args3; print "void SETTER_NAME(CLASS* c, RETURN (*fp) (CLASS*$argStr3)) { \\\n"; print " c->D_set_##METHOD(fp); \\\n"; print "}\n"; print "\n"; } print "#define D_CPP_BASE_CLASS_CLOSE() \\\n"; print "};\n"; print "\n"; print "#define D_CPP_D_DECLARE(arg) ; \n"; print "\n"; bulletml/d_cpp/d_cpp_interface.h0000644000076400007640000003106707732735575014224 0ustar #define D_CPP_CLASS(CLASS, CLASS_NAME) ; #define D_CPP_NEW_0(CLASS, NEW_NAME) \ CLASS* NEW_NAME() { \ return new CLASS(); \ } #define D_CPP_NEW_1(CLASS, NEW_NAME, ARG1) \ CLASS* NEW_NAME(ARG1 arg1) { \ return new CLASS(arg1); \ } #define D_CPP_NEW_2(CLASS, NEW_NAME, ARG1, ARG2) \ CLASS* NEW_NAME(ARG1 arg1, ARG2 arg2) { \ return new CLASS(arg1, arg2); \ } #define D_CPP_NEW_3(CLASS, NEW_NAME, ARG1, ARG2, ARG3) \ CLASS* NEW_NAME(ARG1 arg1, ARG2 arg2, ARG3 arg3) { \ return new CLASS(arg1, arg2, arg3); \ } #define D_CPP_NEW_4(CLASS, NEW_NAME, ARG1, ARG2, ARG3, ARG4) \ CLASS* NEW_NAME(ARG1 arg1, ARG2 arg2, ARG3 arg3, ARG4 arg4) { \ return new CLASS(arg1, arg2, arg3, arg4); \ } #define D_CPP_NEW_5(CLASS, NEW_NAME, ARG1, ARG2, ARG3, ARG4, ARG5) \ CLASS* NEW_NAME(ARG1 arg1, ARG2 arg2, ARG3 arg3, ARG4 arg4, ARG5 arg5) { \ return new CLASS(arg1, arg2, arg3, arg4, arg5); \ } #define D_CPP_NEW_6(CLASS, NEW_NAME, ARG1, ARG2, ARG3, ARG4, ARG5, ARG6) \ CLASS* NEW_NAME(ARG1 arg1, ARG2 arg2, ARG3 arg3, ARG4 arg4, ARG5 arg5, ARG6 arg6) { \ return new CLASS(arg1, arg2, arg3, arg4, arg5, arg6); \ } #define D_CPP_NEW_7(CLASS, NEW_NAME, ARG1, ARG2, ARG3, ARG4, ARG5, ARG6, ARG7) \ CLASS* NEW_NAME(ARG1 arg1, ARG2 arg2, ARG3 arg3, ARG4 arg4, ARG5 arg5, ARG6 arg6, ARG7 arg7) { \ return new CLASS(arg1, arg2, arg3, arg4, arg5, arg6, arg7); \ } #define D_CPP_NEW_8(CLASS, NEW_NAME, ARG1, ARG2, ARG3, ARG4, ARG5, ARG6, ARG7, ARG8) \ CLASS* NEW_NAME(ARG1 arg1, ARG2 arg2, ARG3 arg3, ARG4 arg4, ARG5 arg5, ARG6 arg6, ARG7 arg7, ARG8 arg8) { \ return new CLASS(arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8); \ } #define D_CPP_NEW_9(CLASS, NEW_NAME, ARG1, ARG2, ARG3, ARG4, ARG5, ARG6, ARG7, ARG8, ARG9) \ CLASS* NEW_NAME(ARG1 arg1, ARG2 arg2, ARG3 arg3, ARG4 arg4, ARG5 arg5, ARG6 arg6, ARG7 arg7, ARG8 arg8, ARG9 arg9) { \ return new CLASS(arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9); \ } #define D_CPP_DELETE(CLASS, DELETE_NAME) \ void DELETE_NAME(CLASS* c) { delete c; } #define D_CPP_METHOD_0(CLASS, METHOD, METHOD_NAME, RETURN) \ RETURN METHOD_NAME(CLASS* c) { \ return c->METHOD(); \ } #define D_CPP_METHOD_1(CLASS, METHOD, METHOD_NAME, RETURN, ARG1) \ RETURN METHOD_NAME(CLASS* c, ARG1 arg1) { \ return c->METHOD(arg1); \ } #define D_CPP_METHOD_2(CLASS, METHOD, METHOD_NAME, RETURN, ARG1, ARG2) \ RETURN METHOD_NAME(CLASS* c, ARG1 arg1, ARG2 arg2) { \ return c->METHOD(arg1, arg2); \ } #define D_CPP_METHOD_3(CLASS, METHOD, METHOD_NAME, RETURN, ARG1, ARG2, ARG3) \ RETURN METHOD_NAME(CLASS* c, ARG1 arg1, ARG2 arg2, ARG3 arg3) { \ return c->METHOD(arg1, arg2, arg3); \ } #define D_CPP_METHOD_4(CLASS, METHOD, METHOD_NAME, RETURN, ARG1, ARG2, ARG3, ARG4) \ RETURN METHOD_NAME(CLASS* c, ARG1 arg1, ARG2 arg2, ARG3 arg3, ARG4 arg4) { \ return c->METHOD(arg1, arg2, arg3, arg4); \ } #define D_CPP_METHOD_5(CLASS, METHOD, METHOD_NAME, RETURN, ARG1, ARG2, ARG3, ARG4, ARG5) \ RETURN METHOD_NAME(CLASS* c, ARG1 arg1, ARG2 arg2, ARG3 arg3, ARG4 arg4, ARG5 arg5) { \ return c->METHOD(arg1, arg2, arg3, arg4, arg5); \ } #define D_CPP_METHOD_6(CLASS, METHOD, METHOD_NAME, RETURN, ARG1, ARG2, ARG3, ARG4, ARG5, ARG6) \ RETURN METHOD_NAME(CLASS* c, ARG1 arg1, ARG2 arg2, ARG3 arg3, ARG4 arg4, ARG5 arg5, ARG6 arg6) { \ return c->METHOD(arg1, arg2, arg3, arg4, arg5, arg6); \ } #define D_CPP_METHOD_7(CLASS, METHOD, METHOD_NAME, RETURN, ARG1, ARG2, ARG3, ARG4, ARG5, ARG6, ARG7) \ RETURN METHOD_NAME(CLASS* c, ARG1 arg1, ARG2 arg2, ARG3 arg3, ARG4 arg4, ARG5 arg5, ARG6 arg6, ARG7 arg7) { \ return c->METHOD(arg1, arg2, arg3, arg4, arg5, arg6, arg7); \ } #define D_CPP_METHOD_8(CLASS, METHOD, METHOD_NAME, RETURN, ARG1, ARG2, ARG3, ARG4, ARG5, ARG6, ARG7, ARG8) \ RETURN METHOD_NAME(CLASS* c, ARG1 arg1, ARG2 arg2, ARG3 arg3, ARG4 arg4, ARG5 arg5, ARG6 arg6, ARG7 arg7, ARG8 arg8) { \ return c->METHOD(arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8); \ } #define D_CPP_METHOD_9(CLASS, METHOD, METHOD_NAME, RETURN, ARG1, ARG2, ARG3, ARG4, ARG5, ARG6, ARG7, ARG8, ARG9) \ RETURN METHOD_NAME(CLASS* c, ARG1 arg1, ARG2 arg2, ARG3 arg3, ARG4 arg4, ARG5 arg5, ARG6 arg6, ARG7 arg7, ARG8 arg8, ARG9 arg9) { \ return c->METHOD(arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9); \ } #define D_CPP_STATIC_METHOD_0(CLASS, METHOD, METHOD_NAME, RETURN) \ RETURN METHOD_NAME() { \ return CLASS::METHOD(); \ } #define D_CPP_STATIC_METHOD_1(CLASS, METHOD, METHOD_NAME, RETURN, ARG1) \ RETURN METHOD_NAME(ARG1 arg1) { \ return CLASS::METHOD(arg1); \ } #define D_CPP_STATIC_METHOD_2(CLASS, METHOD, METHOD_NAME, RETURN, ARG1, ARG2) \ RETURN METHOD_NAME(ARG1 arg1, ARG2 arg2) { \ return CLASS::METHOD(arg1, arg2); \ } #define D_CPP_STATIC_METHOD_3(CLASS, METHOD, METHOD_NAME, RETURN, ARG1, ARG2, ARG3) \ RETURN METHOD_NAME(ARG1 arg1, ARG2 arg2, ARG3 arg3) { \ return CLASS::METHOD(arg1, arg2, arg3); \ } #define D_CPP_STATIC_METHOD_4(CLASS, METHOD, METHOD_NAME, RETURN, ARG1, ARG2, ARG3, ARG4) \ RETURN METHOD_NAME(ARG1 arg1, ARG2 arg2, ARG3 arg3, ARG4 arg4) { \ return CLASS::METHOD(arg1, arg2, arg3, arg4); \ } #define D_CPP_STATIC_METHOD_5(CLASS, METHOD, METHOD_NAME, RETURN, ARG1, ARG2, ARG3, ARG4, ARG5) \ RETURN METHOD_NAME(ARG1 arg1, ARG2 arg2, ARG3 arg3, ARG4 arg4, ARG5 arg5) { \ return CLASS::METHOD(arg1, arg2, arg3, arg4, arg5); \ } #define D_CPP_STATIC_METHOD_6(CLASS, METHOD, METHOD_NAME, RETURN, ARG1, ARG2, ARG3, ARG4, ARG5, ARG6) \ RETURN METHOD_NAME(ARG1 arg1, ARG2 arg2, ARG3 arg3, ARG4 arg4, ARG5 arg5, ARG6 arg6) { \ return CLASS::METHOD(arg1, arg2, arg3, arg4, arg5, arg6); \ } #define D_CPP_STATIC_METHOD_7(CLASS, METHOD, METHOD_NAME, RETURN, ARG1, ARG2, ARG3, ARG4, ARG5, ARG6, ARG7) \ RETURN METHOD_NAME(ARG1 arg1, ARG2 arg2, ARG3 arg3, ARG4 arg4, ARG5 arg5, ARG6 arg6, ARG7 arg7) { \ return CLASS::METHOD(arg1, arg2, arg3, arg4, arg5, arg6, arg7); \ } #define D_CPP_STATIC_METHOD_8(CLASS, METHOD, METHOD_NAME, RETURN, ARG1, ARG2, ARG3, ARG4, ARG5, ARG6, ARG7, ARG8) \ RETURN METHOD_NAME(ARG1 arg1, ARG2 arg2, ARG3 arg3, ARG4 arg4, ARG5 arg5, ARG6 arg6, ARG7 arg7, ARG8 arg8) { \ return CLASS::METHOD(arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8); \ } #define D_CPP_STATIC_METHOD_9(CLASS, METHOD, METHOD_NAME, RETURN, ARG1, ARG2, ARG3, ARG4, ARG5, ARG6, ARG7, ARG8, ARG9) \ RETURN METHOD_NAME(ARG1 arg1, ARG2 arg2, ARG3 arg3, ARG4 arg4, ARG5 arg5, ARG6 arg6, ARG7 arg7, ARG8 arg8, ARG9 arg9) { \ return CLASS::METHOD(arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9); \ } #define D_CPP_BASE_CLASS_OPEN(BASE, BASE_NAME) \ struct BASE_NAME : public BASE { #define D_CPP_VIRTUAL_METHOD_0(CLASS, METHOD, RETURN) \ virtual RETURN METHOD() { \ return D_##METHOD##_fp(this ); \ } \ void D_set_##METHOD(RETURN (*fp) (CLASS* )) { \ D_##METHOD##_fp = fp; \ } \ RETURN (*D_##METHOD##_fp) (CLASS*); #define D_CPP_VIRTUAL_METHOD_1(CLASS, METHOD, RETURN, ARG1) \ virtual RETURN METHOD(ARG1 arg1) { \ return D_##METHOD##_fp(this , arg1); \ } \ void D_set_##METHOD(RETURN (*fp) (CLASS* , ARG1)) { \ D_##METHOD##_fp = fp; \ } \ RETURN (*D_##METHOD##_fp) (CLASS*, ARG1); #define D_CPP_VIRTUAL_METHOD_2(CLASS, METHOD, RETURN, ARG1, ARG2) \ virtual RETURN METHOD(ARG1 arg1, ARG2 arg2) { \ return D_##METHOD##_fp(this , arg1, arg2); \ } \ void D_set_##METHOD(RETURN (*fp) (CLASS* , ARG1, ARG2)) { \ D_##METHOD##_fp = fp; \ } \ RETURN (*D_##METHOD##_fp) (CLASS*, ARG1, ARG2); #define D_CPP_VIRTUAL_METHOD_3(CLASS, METHOD, RETURN, ARG1, ARG2, ARG3) \ virtual RETURN METHOD(ARG1 arg1, ARG2 arg2, ARG3 arg3) { \ return D_##METHOD##_fp(this , arg1, arg2, arg3); \ } \ void D_set_##METHOD(RETURN (*fp) (CLASS* , ARG1, ARG2, ARG3)) { \ D_##METHOD##_fp = fp; \ } \ RETURN (*D_##METHOD##_fp) (CLASS*, ARG1, ARG2, ARG3); #define D_CPP_VIRTUAL_METHOD_4(CLASS, METHOD, RETURN, ARG1, ARG2, ARG3, ARG4) \ virtual RETURN METHOD(ARG1 arg1, ARG2 arg2, ARG3 arg3, ARG4 arg4) { \ return D_##METHOD##_fp(this , arg1, arg2, arg3, arg4); \ } \ void D_set_##METHOD(RETURN (*fp) (CLASS* , ARG1, ARG2, ARG3, ARG4)) { \ D_##METHOD##_fp = fp; \ } \ RETURN (*D_##METHOD##_fp) (CLASS*, ARG1, ARG2, ARG3, ARG4); #define D_CPP_VIRTUAL_METHOD_5(CLASS, METHOD, RETURN, ARG1, ARG2, ARG3, ARG4, ARG5) \ virtual RETURN METHOD(ARG1 arg1, ARG2 arg2, ARG3 arg3, ARG4 arg4, ARG5 arg5) { \ return D_##METHOD##_fp(this , arg1, arg2, arg3, arg4, arg5); \ } \ void D_set_##METHOD(RETURN (*fp) (CLASS* , ARG1, ARG2, ARG3, ARG4, ARG5)) { \ D_##METHOD##_fp = fp; \ } \ RETURN (*D_##METHOD##_fp) (CLASS*, ARG1, ARG2, ARG3, ARG4, ARG5); #define D_CPP_VIRTUAL_METHOD_6(CLASS, METHOD, RETURN, ARG1, ARG2, ARG3, ARG4, ARG5, ARG6) \ virtual RETURN METHOD(ARG1 arg1, ARG2 arg2, ARG3 arg3, ARG4 arg4, ARG5 arg5, ARG6 arg6) { \ return D_##METHOD##_fp(this , arg1, arg2, arg3, arg4, arg5, arg6); \ } \ void D_set_##METHOD(RETURN (*fp) (CLASS* , ARG1, ARG2, ARG3, ARG4, ARG5, ARG6)) { \ D_##METHOD##_fp = fp; \ } \ RETURN (*D_##METHOD##_fp) (CLASS*, ARG1, ARG2, ARG3, ARG4, ARG5, ARG6); #define D_CPP_VIRTUAL_METHOD_7(CLASS, METHOD, RETURN, ARG1, ARG2, ARG3, ARG4, ARG5, ARG6, ARG7) \ virtual RETURN METHOD(ARG1 arg1, ARG2 arg2, ARG3 arg3, ARG4 arg4, ARG5 arg5, ARG6 arg6, ARG7 arg7) { \ return D_##METHOD##_fp(this , arg1, arg2, arg3, arg4, arg5, arg6, arg7); \ } \ void D_set_##METHOD(RETURN (*fp) (CLASS* , ARG1, ARG2, ARG3, ARG4, ARG5, ARG6, ARG7)) { \ D_##METHOD##_fp = fp; \ } \ RETURN (*D_##METHOD##_fp) (CLASS*, ARG1, ARG2, ARG3, ARG4, ARG5, ARG6, ARG7); #define D_CPP_VIRTUAL_METHOD_8(CLASS, METHOD, RETURN, ARG1, ARG2, ARG3, ARG4, ARG5, ARG6, ARG7, ARG8) \ virtual RETURN METHOD(ARG1 arg1, ARG2 arg2, ARG3 arg3, ARG4 arg4, ARG5 arg5, ARG6 arg6, ARG7 arg7, ARG8 arg8) { \ return D_##METHOD##_fp(this , arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8); \ } \ void D_set_##METHOD(RETURN (*fp) (CLASS* , ARG1, ARG2, ARG3, ARG4, ARG5, ARG6, ARG7, ARG8)) { \ D_##METHOD##_fp = fp; \ } \ RETURN (*D_##METHOD##_fp) (CLASS*, ARG1, ARG2, ARG3, ARG4, ARG5, ARG6, ARG7, ARG8); #define D_CPP_VIRTUAL_METHOD_9(CLASS, METHOD, RETURN, ARG1, ARG2, ARG3, ARG4, ARG5, ARG6, ARG7, ARG8, ARG9) \ virtual RETURN METHOD(ARG1 arg1, ARG2 arg2, ARG3 arg3, ARG4 arg4, ARG5 arg5, ARG6 arg6, ARG7 arg7, ARG8 arg8, ARG9 arg9) { \ return D_##METHOD##_fp(this , arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9); \ } \ void D_set_##METHOD(RETURN (*fp) (CLASS* , ARG1, ARG2, ARG3, ARG4, ARG5, ARG6, ARG7, ARG8, ARG9)) { \ D_##METHOD##_fp = fp; \ } \ RETURN (*D_##METHOD##_fp) (CLASS*, ARG1, ARG2, ARG3, ARG4, ARG5, ARG6, ARG7, ARG8, ARG9); #define D_CPP_VIRTUAL_METHOD_SETTER_0(CLASS, METHOD, SETTER_NAME, RETURN) \ void SETTER_NAME(CLASS* c, RETURN (*fp) (CLASS*)) { \ c->D_set_##METHOD(fp); \ } #define D_CPP_VIRTUAL_METHOD_SETTER_1(CLASS, METHOD, SETTER_NAME, RETURN, ARG1) \ void SETTER_NAME(CLASS* c, RETURN (*fp) (CLASS*, ARG1)) { \ c->D_set_##METHOD(fp); \ } #define D_CPP_VIRTUAL_METHOD_SETTER_2(CLASS, METHOD, SETTER_NAME, RETURN, ARG1, ARG2) \ void SETTER_NAME(CLASS* c, RETURN (*fp) (CLASS*, ARG1, ARG2)) { \ c->D_set_##METHOD(fp); \ } #define D_CPP_VIRTUAL_METHOD_SETTER_3(CLASS, METHOD, SETTER_NAME, RETURN, ARG1, ARG2, ARG3) \ void SETTER_NAME(CLASS* c, RETURN (*fp) (CLASS*, ARG1, ARG2, ARG3)) { \ c->D_set_##METHOD(fp); \ } #define D_CPP_VIRTUAL_METHOD_SETTER_4(CLASS, METHOD, SETTER_NAME, RETURN, ARG1, ARG2, ARG3, ARG4) \ void SETTER_NAME(CLASS* c, RETURN (*fp) (CLASS*, ARG1, ARG2, ARG3, ARG4)) { \ c->D_set_##METHOD(fp); \ } #define D_CPP_VIRTUAL_METHOD_SETTER_5(CLASS, METHOD, SETTER_NAME, RETURN, ARG1, ARG2, ARG3, ARG4, ARG5) \ void SETTER_NAME(CLASS* c, RETURN (*fp) (CLASS*, ARG1, ARG2, ARG3, ARG4, ARG5)) { \ c->D_set_##METHOD(fp); \ } #define D_CPP_VIRTUAL_METHOD_SETTER_6(CLASS, METHOD, SETTER_NAME, RETURN, ARG1, ARG2, ARG3, ARG4, ARG5, ARG6) \ void SETTER_NAME(CLASS* c, RETURN (*fp) (CLASS*, ARG1, ARG2, ARG3, ARG4, ARG5, ARG6)) { \ c->D_set_##METHOD(fp); \ } #define D_CPP_VIRTUAL_METHOD_SETTER_7(CLASS, METHOD, SETTER_NAME, RETURN, ARG1, ARG2, ARG3, ARG4, ARG5, ARG6, ARG7) \ void SETTER_NAME(CLASS* c, RETURN (*fp) (CLASS*, ARG1, ARG2, ARG3, ARG4, ARG5, ARG6, ARG7)) { \ c->D_set_##METHOD(fp); \ } #define D_CPP_VIRTUAL_METHOD_SETTER_8(CLASS, METHOD, SETTER_NAME, RETURN, ARG1, ARG2, ARG3, ARG4, ARG5, ARG6, ARG7, ARG8) \ void SETTER_NAME(CLASS* c, RETURN (*fp) (CLASS*, ARG1, ARG2, ARG3, ARG4, ARG5, ARG6, ARG7, ARG8)) { \ c->D_set_##METHOD(fp); \ } #define D_CPP_VIRTUAL_METHOD_SETTER_9(CLASS, METHOD, SETTER_NAME, RETURN, ARG1, ARG2, ARG3, ARG4, ARG5, ARG6, ARG7, ARG8, ARG9) \ void SETTER_NAME(CLASS* c, RETURN (*fp) (CLASS*, ARG1, ARG2, ARG3, ARG4, ARG5, ARG6, ARG7, ARG8, ARG9)) { \ c->D_set_##METHOD(fp); \ } #define D_CPP_BASE_CLASS_CLOSE() \ }; #define D_CPP_D_DECLARE(arg) ; bulletml/d_cpp/create_d_import.pl0000755000076400007640000000326107733636445014436 0ustar #!/usr/bin/env perl use strict; my @args; my $in = *STDIN; if ($ARGV[0]) { open $in, $ARGV[0]; } my $out = *STDOUT; if ($ARGV[1]) { open $out, "> $ARGV[1]"; } print $out "extern (C) {\n"; while (<$in>) { s/const //g; if (parseArgs("D_CPP_CLASS")) { my $class = shift @args; my $name = shift @args; print $out "alias int $name;\n"; } if (parseArgs("D_CPP_NEW_\\d")) { my $class = shift @args; my $name = shift @args; my $args = join ', ', @args; print $out "int* $name($args);\n"; } if (parseArgs("D_CPP_DELETE")) { my $class = shift @args; my $name = shift @args; print $out "void $name(int*);\n"; } if (parseArgs("D_CPP_METHOD_\\d")) { my $class = shift @args; my $method = shift @args; my $name = shift @args; my $ret = shift @args; my $args = join ', ', @args; if ($args) { $args = ", $args"; } print $out "$ret $name(int* $args);\n"; } if (parseArgs("D_CPP_STATIC_METHOD_\\d")) { my $class = shift @args; my $method = shift @args; my $name = shift @args; my $ret = shift @args; my $args = join ', ', @args; print $out "$ret $name($args);\n"; } if (parseArgs("D_CPP_VIRTUAL_METHOD_SETTER_\\d")) { my $class = shift @args; my $method = shift @args; my $name = shift @args; my $ret = shift @args; my $args = join ', ', @args; if ($args) { $args = ", $args"; } print $out "void $name(int*, $ret (*fp) (int* $args)); \n"; } if (parseArgs("D_CPP_D_DECLARE")) { my $declare = shift @args; $declare =~ s/^\"//; $declare =~ s/\"$//; print $out "$declare\n"; } } print $out "}\n"; sub parseArgs { my $name = shift; if (/$name\s*\(([^\)]*)\)/) { @args = split /\s*,\s*/, $1; return 1; } else { return 0; } } bulletml/d_cpp/README.en0000644000076400007640000000563507733201220012201 0ustar from D to C++ I'm sorry of my poor English... * Introduction This package helps to access C++ library from D. If D compiler supports such as extern(C++), this package becomes useless. * Figure generating process C++ using d_cpp -----------------------> C wrapper (interface definition) | preprocesser | --------------------> D import interface perl script accessing process D client code --> D import interface --> C wrapper --> C++ using d_cpp --> C++ library code * File Description README: this file. Makefile: linux's makefile. Makefile.win32: windows's makefile. d_cpp_interface.h: helps C++ using d_cpp to C wrapper create_d_import.pl: helps C++ using d_cpp to D import interface cpp.cc: sample of C++ using d_cpp and C++ library code. cpp_test.d: sample of D client code. create_d_cpp_interface.pl: I created d_cpp_interface.h with this script. * Misc This package is alpha release. I'm glad if you give me advice. More complicated sample is available as "barrage 360 deg.", a BulletML viewer. - Japanese page http://user.ecc.u-tokyo.ac.jp/~s31552/wp/bulletss/ - Download http://user.ecc.u-tokyo.ac.jp/~s31552/wp/bulletss/bulletss.tar.bz2 - BulletML http://www.asahi-net.or.jp/~cs8k-cyu/bulletml/index_e.html This package distributes under the modified BSD license Copyright (c) 2003, shinichiro.h All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. * The name of the author may not be used to endorse or promote products derived from this software without specific prior written permission. TTHIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ------------------ shinichiro.h s31552@mail.ecc.u-tokyo.ac.jp http://user.ecc.u-tokyo.ac.jp/~s31552/wp/ bulletml/d_cpp/README0000644000076400007640000000707307733202002011575 0ustar from D to C++ If you are more familiar English than Japanese, please read README.en. ・説明。 C++ の遺産(死んでない) を D から触るためのものです。 extern(C++) がサポートされた時、無意味に帰ります。 C++ からは C のインターフェイスを提供して、 D からそれを触るためのインポートライブラリも作らなければならない、 ということを理解して頂ければ何がやりたいかがわかるかと思います。 C 関数の宣言/定義は C++ ソースからプリプロセッサで、 D 関数の宣言は C++ ソースから perl スクリプトで生成されます。 README.en で説明を放棄するために作った図。 generating process C++ using d_cpp -----------------------> C wrapper (interface definition) | preprocesser | --------------------> D import interface perl script accessing process D client code --> D import interface --> C wrapper --> C++ using d_cpp --> C++ library code ・ファイルの説明 README: これ。 Makefile: サンプルであるところの cpp_test 実行ファイルを作る。 Makefile.win32: windows での Makefile。 d_cpp_interface.h: C++ から C の宣言を生成するためのヘッダ。 create_d_import.pl: D の宣言を自動生成する perl スクリプト。 cpp.cc: サンプル、ユーザが書かにゃならんのはこの部分です。 cpp_test.d: D から cpp.cc を実際にいじってみるサンプル。 create_d_cpp_interface.pl: おまけ。d_cpp_interface.h を生成する。改造したい場合にどうぞ。 cpp.cc の前半が D から使いたいクラスライブラリ、 後半部が D で import するのに必要な作業です。 cpp.cc に C 関数の定義がマクロで生成されます。 このマクロは雑な perl script でパースするため、 途中で絶対改行しないで下さい。 D による import は create_d_import.pl を用いて import するためのファイルを作成して下さい。 このファイルには宣言しか含まれないので、 コンパイル・リンクする必要はありません。 こんなややこしいものの説明を書く自信が無いので、 cpp.cc を眺めて適当に理解して下さい。 ・その他 とてもとてもα版です。ご意見頂けるととても嬉しいです。 以下が実際的な実例となっています。 http://user.ecc.u-tokyo.ac.jp/~s31552/wp/bulletss/ 修正 BSD ライセンスに従って配布します。 Copyright (c) 2003, shinichiro.h All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. * The name of the author may not be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ------------------ shinichiro.h s31552@mail.ecc.u-tokyo.ac.jp http://user.ecc.u-tokyo.ac.jp/~s31552/wp/ bulletml/d_cpp/Makefile0000644000076400007640000000056207733205135012363 0ustar CXX=g++ DMD=dmd PERL=perl CPPFLAGS=-g DFLAGS=-g all: cpp_test cpp_test: cpp.o cpp_test.o $(DMD) cpp_test $(CPPFLAGS) cpp.o cpp.o: d_cpp_interface.h cpp.cpp $(CXX) $(CPPFLAGS) -c cpp.cpp cpp_test.o: cpp_inter.d cpp_test.d $(DMD) $(DFLAGS) -c cpp_test.d cpp_inter.d: cpp.cpp $(PERL) create_d_import.pl cpp.cpp cpp_inter.d clean: rm -f *.o cpp_test cpp_inter.d bulletml/stdafx.cpp0000644000076400007640000000050507726416166011642 0ustar // stdafx.cpp : WCN[ht@C\[X t@C // bulletml.pch vRpCwb_[ // stdafx.obj vRpC^Cv #include "stdafx.h" // TODO: STDAFX.H At@CLq // wb_[t@CB bulletml/stdafx.h0000644000076400007640000000144107726416167011310 0ustar // stdafx.h : WVXe CN[h t@CA // QAX // vWFNgpCN[h t@CLqB // #if !defined(AFX_STDAFX_H__9F54202F_1F20_4F4E_A10A_460A1B4E98B4__INCLUDED_) #define AFX_STDAFX_H__9F54202F_1F20_4F4E_A10A_460A1B4E98B4__INCLUDED_ #if _MSC_VER > 1000 #pragma once #endif // _MSC_VER > 1000 // uwb_[} #define WIN32_LEAN_AND_MEAN // Windows wb_[wgpX^btO #include // TODO: vOKvwb_[QB //{{AFX_INSERT_LOCATION}} // Microsoft Visual C++ OsO}B #endif // !defined(AFX_STDAFX_H__9F54202F_1F20_4F4E_A10A_460A1B4E98B4__INCLUDED_) bulletml/bulletml.dsw0000644000076400007640000000104107726414210012164 0ustar Microsoft Developer Studio Workspace File, Format Version 6.00 # x: 目宛粛澎 箕荷 W! ############################################################################### Project: "bulletml"=.\bulletml.dsp - Package Owner=<4> Package=<5> {{{ }}} Package=<4> {{{ }}} ############################################################################### Global: Package=<5> {{{ }}} Package=<3> {{{ }}} ############################################################################### bulletml/README.en0000644000076400007640000001231110370171147011106 0ustar libBulletML 0.0.5 * Abstract It is a C++ library to handle BulletML, the Bullet Markup Language. You can use BulletML in your program without bothering to parse XML. If you want to know BulletML more, please see following web site by ABA (author of BulletML): http://www.asahi-net.or.jp/~cs8k-cyu/bulletml/index_e.html * Usage You can use it with VC and BorlandC++ and gcc and I wish, almost all compiler that supports standard C++. An example of this library is available in my software "siroi danmakukun": http://user.ecc.u-tokyo.ac.jp/~s31552/wp/sdmkun/sdmkun-1.5.6.zip You can see usage of this library in src/command_bulletml.* . * Tutorial This library's basic usage is event driven model. 0. Get XML file written in BulletML. You can use BulletML file in "siroi danmakukun". (bosses.d/*.xml in archive) 1. Include headers #include "bulletml/bulletmlparser.h" #include "bulletml/bulletmlparser-tinyxml.h" #include "bulletml/bulletmlrunner.h" 2. Create class that inherits BulletMLRunner class BulletCommand : public BulletMLRunner { // ... // the bullet you will handle Bullet* bullet_; } 3. Implement all pure virtual function defined in bulletmlrunner.h For example: class BulletCommand : public BulletMLRunner { virtual void doVanish() { bullet_->die(); } // ... and other pure virtual functions } createSimpleBullet and createBullet method should be implemented carefully. In libBulletML, all bullets are divided to two types. createSimpleBullet type does not have , createBullet type has . For example, "siroi danmakukun" uses two class: Shot and Enemy. When libBulletML handle element that does not have element, BulletMLRunner calls createSimpleBullet method with two arguments: direction and speed. In the other hand, if element has element, BulletMLRunner calls createBullet method with three arguments: direction, speed, and state. You should not care the detail of the state argument. But it should be given to the class derived from BulletMLRunner in its constructor. The creation of this class is described in next section. 4. Create of the class derived from BulletMLRunner In libBulletML, the batteries are divided two types. One type is the battery that is defined in (first order battery), and one type is the battery that is created by the other battery (second, third, forth... battery). Then, you should create two constructors to handle these two kind of batteries. For example, first order battery is implemented like following: BulletCommand::BulletCommand(BulletMLParser* bp, Bullet* b) : BulletMLRunner(bp), bullet_(b) For example, second, third... order battery is implemented like following: BulletCommand::BulletCommand(BulletMLState* bs, Bullet* b) : BulletMLRunner(bs), bullet_(b) You should call this constructor when createBullet method is called. 5. Create BulletML document BulletMLParser* bp = new BulletMLParserTinyXML("foo.xml"); bp->build(); Because parsing BulletML is slow, all xml files should be loaded in the initialization of the program. 6. Create first order battery BulletCommand* bc = new BulletCommand(bp) 7. Run BulletCommand in all turn. while (1) { // the main loop of game bc->run(); } If some errors are occured, libBulletML throws BulletMLError. You can catch this exception. * Misc TinyXML is used to parse XML. http://www.gibaradunn.srac.org/tiny/index.shtml If you cannot understand this document (yes, it's poor document and writen in poor English), please ask me with email. * Modified BSD License Copyright (c) 2003, shinichiro.h All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. * The name of the author may not be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. shinichiro.h hamaji@nii.ac.jp http://shinh.skr.jp/ bulletml/README0000644000076400007640000001474510370171130010512 0ustar libBulletML 0.0.5 ETv eLq BulletML c++ CuB pALxLq BulletML A XMLmッpB OtBbNQ[SA S\tggpB vOeLqxvA Svf enum A タsrxNB BulletML ABAfUCeLqB B http://www.asahi-net.or.jp/~cs8k-cyu/bulletml/index.html Eg VC Borland C++ gcc mFB hLgAA uevSタpB Ge command.cc, command.h ZvOvB Ql enemy.cc, enemy.h B Ahtml/index.html P API t@XB CugzB * ACxg^ PgB AZ_B 0. BulletML Lq XML t@CpB nuev ABA XML t@CpB AREADME.bulletml t@XB 1. Kvt@CCN[hB #include "bulletml/bulletmlparser.h" #include "bulletml/bulletmlparser-tinyxml.h" #include "bulletml/bulletmlrunner.h" 2. BulletMLRunner pNXB class BulletCommand : public BulletMLRunner { // ... // NX Bullet iAtB Bullet* bullet_; } 3. bulletmlrunner.h LqzSタB AB virtual void doVanish() { bullet->die(); } __B create n\bhI[o[ChB libBulletML eeB e^sA VvタA sB NCAgR[hAvB uev Shot Enemy NXpB A e GgタsA BulletMLRunner createSimpleBullet oB pxxnA]eB AA BulletMLState* state IuWFNgnB ABulletML p[XcA NCAgR[heCKvB AVe BulletMLRunner hNX nKvB BulletMLRunner B 4. BulletMLRunner hNX libBulletML eB Axmlt@ChLgSA SeeA e GgA OceB ABulletMLRunner hNX RXgN^pKvB OメRXgN^タB BulletCommand::BulletCommand(BulletMLParser* bp, Bullet* b) : BulletMLRunner(bp), bullet_(b) メRXgN^タB BulletCommand::BulletCommand(BulletMLState* bs, Bullet* b) : BulletMLRunner(bs), bullet_(b) 5. BulletML hLgB BulletMLParser* bp = new BulletMLParserTinyXML("hoge.xml"); bp->build(); タタssdA vOJnB 6. hLgpeB BulletCommand* bc = new BulletCommand(bp) 7. e^[S BulletCommand タsB bc->run(); ACxgョeB ANAlibBulletML BulletMLError B B * Aゥc[ zgAbB 1. Kvt@CCN[hB #include "bulletml/bulletmlparser.h" #include "bulletml/bulletmlparser-tinyxml.h" #include "bulletml/bulletmltree.h" 2. BulletML hLgB BulletMLParser* bp = new BulletMLParserTinyXML("hoge.xml"); bp->build(); 3. BulletMLParser gbvANVB const std::vector& nodes = bp->getTopActions(); 4. ゥc[B bulletmltree.h Qlc[GeB E @\~[B CBSDCZX]B TinyXMLbB http://www.gibaradunn.srac.org/tiny/index.shtml hLg Doxygen pB http://www.stack.nl/~dimitri/doxygen/ EToDo 1. dl Eattribute 2. ゥg Edl^OAgr[g 3. G[bZ[WAG[[タ 4. eB ECBSDCZX Copyright (c) 2003, shinichiro.h All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. * The name of the author may not be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. shinichiro.h hamaji@nii.ac.jp http://shinh.skr.jp/ bulletml/bulletml.h0000644000076400007640000000161707726416167011644 0ustar // ifdef ubN DLL PGNX|[g}NWI@B // DLL t@CR}hC` BULLETML_EXPORTS V{ // RpCBV{ DLL gpvWFNg` // B@\[Xt@Ct@CvWFNg DLL // C|[g BULLETML_API QA DLL }N // `V{GNX|[gQB #ifdef BULLETML_EXPORTS #define BULLETML_API __declspec(dllexport) #else #define BULLETML_API __declspec(dllimport) #endif // NX bulletml.dll GNX|[g class BULLETML_API CBulletml { public: CBulletml(void); // TODO: u\bhB }; extern BULLETML_API int nBulletml; BULLETML_API int fnBulletml(void);