C:\home\SVGCats_src\src\XMLPars.c
1|/************************************************************************** 2| 1. <<< XMLパーサ (XMLPars) >>> 3|***************************************************************************/ 4| 5|#include "mixer_precomp.h" 6| 7|#ifdef USES_MXP_AUTOINC 8| #include <XMLPars.ah> /* Auto include header, Look at mixer-... folder */ 9|#endif 10| 11| 12| 13|/*---------------------------------------------------------------------*/ 14|/* 2. <<<<◆(XMLPars) XMLパーサ >>>> */ 15|/*---------------------------------------------------------------------*/ 16| 17| 18|/************************************************************************** 19| 2-1. <<< [XMLPars_init] 初期化する >>> 20|【引数】 21| ・XMLPars* m; XMLパーサ 22| ・char* path; 読み込むファイルのパス 23| ・void* buf; タグ解析用バッファ(→補足) 24| ・int buf_size; buf のサイズ(バイト) 25|【補足】 26|・buf_size は、3072ぐらいを設定します。 buf は、1つのタグの最大バイト数と 27| 1つのタグの最大属性数(40固定)*8 と、BLex3_Engine で使用するバッファの 28| サイズ(1024固定)*2 の合計です。 29|・本関数を呼び出した後、XMLPars_parse を呼び出して初めて、XMLPars_getTagName 30| などを呼び出すことができます。 31|***************************************************************************/ 32|void XMLPars_init( XMLPars* m, const char* path, void* buf, int buf_size ) 33|{ 34| enum { eng_buf_size = 1024, mAttr = 40, mem2_size = mAttr*2*sizeof(char*) }; 35| 36| ERRORS_INITCHK( m, 0 ); 37| ASSERT( buf_size >= eng_buf_size*2 + mem2_size + 40 ); 38| 39| BLex3_Engine_init( &m->engU.inherit_BLex3_Engine, path, buf, eng_buf_size, 256 ); 40| BLex3_Engine_setSJisBuf( &m->engU.inherit_BLex3_Engine, (char*)buf + eng_buf_size, 41| eng_buf_size ); 42| 43| LineCnt_init( &m->lineCnt ); 44| LineCnt_linkEngine( &m->lineCnt, &m->engU.inherit_BLex3_Engine ); 45| 46| HtmlPars_init( &m->htmlPars, 47| (char*)buf + eng_buf_size*2 + mem2_size, 48| buf_size - eng_buf_size*2 - mem2_size, 49| (char**)( (char*)buf + eng_buf_size*2 ), 50| mem2_size ); 51| HtmlPars_linkEngine( &m->htmlPars, &m->engU ); 52| 53| m->bText = false; 54| m->spaceTagName[0] = '\0'; 55| 56| ERRORS_FINISHCHK_FOR_INIT( XMLPars_finish ); 57|} 58| 59| 60| 61|/************************************************************************** 62| 2-2. <<< [XMLPars_finish] 後始末する >>> 63|***************************************************************************/ 64|void XMLPars_finish( XMLPars* m ) 65|{ 66| ERRORS_INITCHK( m, 1 ); 67| ERRORS_FINISHCHK_FOR_FINISH( XMLPars_finish ); 68| 69| BLex3_Engine_finish( &m->engU.inherit_BLex3_Engine ); 70|} 71| 72| 73| 74|/************************************************************************** 75| 2-3. <<< [XMLPars_parse] 字句解析を行う。次のタグ等へ移動する >>> 76|【引数】 77| ・XMLPars* m; XMLパーサ 78| ・bool 返り値; 次のタグ等があったかどうか(ファイルの末尾でないか) 79|***************************************************************************/ 80|bool XMLPars_parse( XMLPars* m ) 81|{ 82| BLex3_Pos pos; 83| BLex3_Engine* eng = &m->engU.inherit_BLex3_Engine; 84| 85| ERRORS_INITCHK( m, 1 ); 86| 87| m->bText = false; 88| 89| /* パース */ 90| do { 91| BLex3_Engine_setPos( eng, &m->htmlPars.parsedPos ); 92| BLex3_Pos_copy( &pos, &m->htmlPars.parsedPos ); 93| if ( BLex3_Engine_getFilePtr( eng, 0 ) == NULL ) 94| return false; 95| HtmlPars_parse( &m->htmlPars ); 96| 97| /* タグ間のテキストがあるかどうかを調べる */ 98| if ( HtmlPars_getTokenType( &m->htmlPars ) == HtmlPars_EndOfTag ) { 99| char* fp; 100| char* xml_space; 101| 102| BLex3_Engine_setPos( eng, &m->htmlPars.parsedPos ); 103| if ( m->spaceTagName[0] == '\0' ) { 104| xml_space = HtmlPars_getValue( &m->htmlPars, "xml:space" ); 105| if ( xml_space != NULL && strcmp( xml_space, "preserve" ) == 0 ) 106| strcpy( m->spaceTagName, HtmlPars_getName( &m->htmlPars ) ); 107| } 108| else if ( strcmp( m->spaceTagName, HtmlPars_getName( &m->htmlPars )+1 ) == 0 ) { 109| if ( HtmlPars_getName( &m->htmlPars )[0] == '/' ) 110| m->spaceTagName[0] = '\0'; 111| } 112| if ( m->spaceTagName[0] == '\0' ) 113| BLex3_EngineU_skip( &m->engU, " \t\r\n" ); 114| else 115| BLex3_EngineU_skip( &m->engU, "\r\n" ); 116| 117| fp = BLex3_Engine_getFilePtr( eng, 1 ); 118| if ( fp == NULL ) return false; 119| if ( *fp != '<' || m->htmlPars.endCh == '\0' ) { 120| BLex3_Engine_getPos( eng, &pos ); 121| m->bText = true; 122| break; 123| } 124| else 125| continue; 126| } 127| } while ( HtmlPars_getTokenType( &m->htmlPars ) != HtmlPars_StartOfTag ); 128| 129| BLex3_Engine_setPos( eng, &pos ); 130| LineCnt_parse( &m->lineCnt ); 131| 132| return true; 133|} 134| 135| 136| 137|/************************************************************************** 138| 2-4. <<< [XMLPars_getTokenType] 現在位置のXMLトークンタイプを返す >>> 139|【引数】 140| ・XMLPars* m; XMLパーサ 141| ・int 返り値; XMLトークンタイプ 142|***************************************************************************/ 143|int XMLPars_getTokenType( XMLPars* m ) 144|{ 145| ERRORS_INITCHK( m, 1 ); 146| 147| if ( m->bText ) 148| return XMLPars_TextBetweenTags; 149| 150| else if ( m->htmlPars.endCh == '/' || m->htmlPars.endCh == '?' ) 151| return XMLPars_StartAndEndTag; 152| 153| else if ( XMLPars_getTagName( m )[0] == '/' ) 154| return XMLPars_EndTag; 155| 156| else if ( XMLPars_getTagName( m )[0] == '!' ) 157| return XMLPars_StartAndEndTag; 158| 159| else 160| return XMLPars_StartTag; 161|} 162| 163| 164| 165|/************************************************************************** 166| 2-5. <<< [XMLPars_getTagName] 現在位置のタグの名前を返す >>> 167|【引数】 168| ・XMLPars* m; XMLパーサ 169| ・char* 返り値; 現在位置のタグの名前 170|【補足】 171|・返り値は、本クラスを初期化したときに指定した領域の内部を指しています。 172|・XMLPars_TextBetweenTags のときは、そのテキストを囲むタグの名前を返します。 173|・XMLPars_EndTag のときは、先頭に '/' の付いた名前を返します。 174|***************************************************************************/ 175|char* XMLPars_getTagName( XMLPars* m ) 176|{ 177| ERRORS_INITCHK( m, 1 ); 178| 179| return HtmlPars_getName( &m->htmlPars ); 180|} 181| 182| 183| 184|/************************************************************************** 185| 2-6. <<< [XMLPars_getValue] 現在位置のタグの中の属性の値を返す >>> 186|【引数】 187| ・XMLPars* m; XMLパーサ 188| ・char* name; 属性の名前 189| ・char* 返り値; 属性の値(NULL=該当する属性が無い) 190|【補足】 191|・返り値は、本クラスを初期化したときに指定した領域の内部を指しています。 192|***************************************************************************/ 193|char* XMLPars_getValue( XMLPars* m, const char* name ) 194|{ 195| ERRORS_INITCHK( m, 1 ); 196| 197| return HtmlPars_getValue( &m->htmlPars, name ); 198|} 199| 200| 201| 202|/************************************************************************** 203| 2-7. <<< [XMLPars_getText] 現在位置のタグの間のテキストを取得する >>> 204|【引数】 205| ・XMLPars* m; XMLパーサ 206| ・int offset; 取得する位置をテキストの先頭から offset だけ足す 207| ・char* s; テキストを格納する領域のアドレス 208| ・int s_size; s のサイズ(バイト) 209| ・int 返り値; 格納したテキストのサイズ(0=offset が大きいかテキストが無い) 210|【補足】 211|・s より大きな領域を複数に分けて取得するときは、返り値が 0になるまで 212| offset を足して、繰り返し本関数を呼び出してください。 213|***************************************************************************/ 214|int XMLPars_getText( XMLPars* m, int offset, char* s, int s_size ) 215|{ 216| BLex3_Pos pos; 217| char* xml_space; 218| 219| XMLPars_getPos( m, &pos ); 220| BLex3_Engine_setPos2( &m->engU.inherit_BLex3_Engine, &pos, offset ); 221| BLex3_EngineU_readWord( &m->engU, s, s_size, "<", false ); 222| xml_space = HtmlPars_getValue( &m->htmlPars, "xml:space" ); 223| if ( m->spaceTagName[0] == '\0' ) 224| StrX_trim( s ); 225| 226| return strlen(s); 227|} 228| 229| 230|/*********************************************************************** 231| 2-8. <<< [XMLPars_getPos] 現在位置を取得する >>> 232|【引数】 233| ・XMLPars* m; XMLパーサ 234| ・BLex3_Pos* pos; 現在位置 235|************************************************************************/ 236|void XMLPars_getPos( XMLPars* m, BLex3_Pos* pos ) 237|{ 238| BLex3_Pos_copy( pos, &m->lineCnt.prevPos ); 239|} 240| 241|/*********************************************************************** 242| 2-9. <<< [XMLPars_setPos1] 現在位置を移動する >>> 243|【引数】 244| ・XMLPars* m; XMLパーサ 245| ・int pos; 現在位置 246|************************************************************************/ 247|void XMLPars_setPos1( XMLPars* m, int pos ) 248|{ 249| BLex3_Pos p; 250| 251| p.sjis_type = BLex3_Ascii; 252| p.pos = pos; 253| BLex3_Pos_copy( &m->lineCnt.prevPos, &p ); 254|} 255| 256|/*********************************************************************** 257| 2-10. <<< [XMLPars_getLineNum] 現在位置の行番号を返す >>> 258|【引数】 259| ・XMLPars* m; XMLパーサ 260| ・int 返り値; 現在位置の行番号(1〜) 261|************************************************************************/ 262|int XMLPars_getLineNum( XMLPars* m ) 263|{ 264| return m->lineCnt.iLine; 265|} 266| 267| 268|/************************************************************************** 269| 2-11. <<< [XMLPars_print] デバッグ表示する >>> 270|***************************************************************************/ 271|#ifndef ERRORS_CUT_DEBUG_TOOL 272|void XMLPars_print( XMLPars* m, const char* title ) 273|{ 274| Errors_printf( "%sXMLPars[%p]", title, m ); 275| HtmlPars_print( &m->htmlPars, title ); 276|} 277|#endif 278| 279| 280| 281|