C:\home\SVGCats_src\src\htmlpars.c
1|/************************************************************************** 2|* 1. <<< HTML パーサ (HtmlPars) >>> 3|***************************************************************************/ 4| 5|#include "mixer_precomp.h" /* Auto precompiled header, Look at mixer-... folder */ 6|// #pragma hdrstop 7| 8|#ifdef USES_MXP_AUTOINC 9| #include <htmlpars.ah> /* Auto include header, Look at mixer-... folder */ 10|#endif 11| 12| 13|/*---------------------------------------------------------------------*/ 14|/* 2. <<<◆(HtmlPars) HTML パーサ >>> */ 15|/*---------------------------------------------------------------------*/ 16| 17| 18|/************************************************************************** 19|* 3. <<< [HtmlPars_init] 初期化する >>> 20|*【引数】 21|* ・HtmlPars* m; HTML パーサ 22|* ・void* mem; 文字列記憶領域1 23|* ・int mem_size; mem の領域サイズ、最大の全文字数 24|* ・char** mem2; 文字列記憶領域2、char* 型配列 25|* ・int mem2_size; mem2 の領域サイズ、最大の属性数×2×sizeof(char*) 26|***************************************************************************/ 27|void HtmlPars_init( HtmlPars* m, void* mem, int mem_size, 28| char** mem2, int mem2_size ) 29|{ 30| ERRORS_INITCHK( m, 0 ); 31| 32| m->engU = NULL; 33| 34| BLex3_Pos_init( &m->parsedPos ); 35| m->prevTokenType = BLex3_OutOfToken; 36| m->bInTag = false; 37| 38| m->name = NULL; 39| m->attr_names = mem2; 40| m->attr_values = mem2 + mem2_size / (sizeof(char*) * 2); 41| m->attr_n = 0; 42| StrX_Mem_init( &m->mem, mem, mem_size ); 43|} 44| 45| 46| 47|/************************************************************************** 48|* 4. <<< [HtmlPars_print] デバッグ表示する >>> 49|***************************************************************************/ 50|#ifndef ERRORS_CUT_DEBUG_TOOL 51|void HtmlPars_print( HtmlPars* m, const char* title ) 52|{ 53| int i; 54| 55| ERRORS_INITCHK( m, 1 ); 56| 57| Errors_printf( "%sHtmlPars[%p] engU=[%p]", title, m, m->engU ); 58| BLex3_Pos_print( &m->parsedPos, title ); 59| Errors_printf( "%s prevTokenType = %d", title, m->prevTokenType ); 60| 61| Errors_printf( "%s name = %s, attr_n = %d", title, m->name, m->attr_n ); 62| 63| for ( i = 0; i < m->attr_n; i++ ) { 64| Errors_printf( "%s attr_name = %s, attr_value = %s", title, 65| m->attr_names[i], m->attr_values[i] ); 66| } 67| Errors_printf( "%s mem = [%p]", title, &m->mem ); 68|} 69|#endif 70| 71| 72| 73|/************************************************************************** 74|* 5. <<< [HtmlPars_linkEngine] 字句解析エンジンと関連付ける >>> 75|*【引数】 76|* ・HtmlPars* m; HTML パーサ 77|* ・BLex3_EngineU* engU; 字句解析エンジン 78|***************************************************************************/ 79|void HtmlPars_linkEngine( HtmlPars* m, BLex3_EngineU* engU ) 80|{ 81| ERRORS_INITCHK( m, 1 ); 82| 83| m->engU = engU; 84|} 85| 86| 87| 88|/************************************************************************** 89|* 6. <<< [HtmlPars_parse] HTML タグを解析する >>> 90|*【引数】 91|* ・HtmlPars* m; HTML パーサ 92|*【補足】 93|*・前回に本関数を呼び出したときより、ファイルポインタが進んでいること。 94|***************************************************************************/ 95|void HtmlPars_parse( HtmlPars* m ) 96|{ 97| BLex3_EngineU* engU = m->engU; 98| char* fp; 99| char* fp0; 100| char* fp2; 101| char* fp_over; 102| BLex3_Pos pos; 103| 104| ERRORS_INITCHK( m, 1 ); 105| 106| BLex3_Engine_getPos( &engU->inherit_BLex3_Engine, &pos ); 107| if ( pos.pos < m->parsedPos.pos ) { 108| m->prevTokenType = BLex3_MiddleOfToken; 109| return; 110| } 111| 112| /* 前回が、タグの開始だったとき */ 113| if ( m->bInTag ) { 114| m->prevTokenType = HtmlPars_EndOfTag; 115| m->bInTag = false; 116| return; 117| } 118| 119| /* それ以外のとき, '<' を見つけてタグを解析する */ 120| fp = BLex3_Engine_getFilePtr( &engU->inherit_BLex3_Engine, 0 ); 121| fp2 = BLex3_Engine_getSJisPtr( &engU->inherit_BLex3_Engine ); 122| fp_over = BLex3_Engine_getOverPtr( &engU->inherit_BLex3_Engine ); 123| 124| fp0 = fp; 125| while ( fp < fp_over ) { 126| 127| if ( *fp == '<' && *fp2 != BLex3_SJisSecond ) { 128| char* p; 129| 130| /* 数バイト先にタグの開始があるとき、そこまで解析して一旦抜ける */ 131| if ( fp != fp0 ) { 132| BLex3_Engine_getPos2( &engU->inherit_BLex3_Engine, fp, &m->parsedPos ); 133| m->prevTokenType = BLex3_OutOfToken; 134| return; 135| } 136| 137| /* タグ名を取得する: get tag name */ 138| BLex3_Engine_next( &engU->inherit_BLex3_Engine, 1 ); 139| 140| StrX_Mem_toEmpty( &m->mem ); 141| m->attr_n = 0; 142| 143| p = StrX_Mem_alloc( &m->mem ); 144| BLex3_Engine_getPos( &engU->inherit_BLex3_Engine, &pos ); 145| BLex3_EngineU_readWord( engU, 146| p, StrX_Mem_getLeftSize( &m->mem ), " >", true ); 147| StrX_cpyLower( p, p ); 148| m->name = p; 149| if ( ! StrX_isAlpha( *p ) && *p != '/' && *p != '!' && *p != '?' ) { 150| BLex3_Pos_copy( &m->parsedPos, &pos ); 151| m->prevTokenType = BLex3_OutOfToken; 152| return; 153| } 154| 155| /* コメントタグのとき: case of comment tag */ 156| if ( strncmp( m->name, "!--", 3 ) == 0 ) { 157| m->name[3] = '\0'; 158| BLex3_Engine_setPos2( &engU->inherit_BLex3_Engine, &pos, +2 ); 159| BLex3_EngineU_skipToStr( engU, "-->", 3, false ); 160| } 161| 162| /* 一般のタグのとき: case of general tag */ 163| else { 164| for (;;) { 165| 166| /* 属性名を取得する: get attribute name */ 167| BLex3_EngineU_skip( engU, " \t\n\r" ); 168| fp = BLex3_Engine_getFilePtr( &engU->inherit_BLex3_Engine, 2 ); 169| if ( fp == NULL || *fp == '>' ) 170| { m->endCh = '\0'; break; } 171| if ( ( *fp == '/' || *fp == '?' ) && *(fp+1) == '>' ) { 172| m->endCh = *fp; 173| BLex3_Engine_next( &engU->inherit_BLex3_Engine, 1 ); 174| break; 175| } 176| if ( ! StrX_isAlpha( *fp ) ) { 177| BLex3_EngineU_skipTo( engU, ">", 0 ); 178| BLex3_Engine_getPos( &engU->inherit_BLex3_Engine, &m->parsedPos ); 179| BLex3_Engine_setPos2( &engU->inherit_BLex3_Engine, &m->parsedPos, -1 ); 180| fp = BLex3_Engine_getFilePtr( &engU->inherit_BLex3_Engine, 2 ); 181| m->endCh = ( fp == NULL ? '\0' : *fp ); 182| BLex3_Engine_setPos2( &engU->inherit_BLex3_Engine, &m->parsedPos, 0 ); 183| break; 184| } 185| if ( m->attr_names + m->attr_n >= m->attr_values ) { 186| BLex3_EngineU_skipTo( engU, ">", 0 ); 187| BLex3_Engine_getPos( &engU->inherit_BLex3_Engine, &m->parsedPos ); 188| BLex3_Engine_setPos2( &engU->inherit_BLex3_Engine, &m->parsedPos, -1 ); 189| fp = BLex3_Engine_getFilePtr( &engU->inherit_BLex3_Engine, 2 ); 190| m->endCh = ( fp == NULL ? '\0' : *fp ); 191| BLex3_Engine_setPos2( &engU->inherit_BLex3_Engine, &m->parsedPos, 0 ); 192| break; 193| } 194| p = StrX_Mem_alloc( &m->mem ); 195| BLex3_EngineU_readWord( engU, 196| p, StrX_Mem_getLeftSize( &m->mem ), " =>\r\n\t", true ); 197| StrX_cpyLower( p, p ); 198| m->attr_names[m->attr_n] = p; 199| 200| /* 属性値を取得する: get attribute value */ 201| BLex3_EngineU_skip( engU, " \t\n\r" ); 202| fp = BLex3_Engine_getFilePtr( &engU->inherit_BLex3_Engine, 1 ); 203| if ( fp == NULL || *fp == '>' ) break; 204| p = StrX_Mem_alloc( &m->mem ); 205| if ( *fp == '=' ) { 206| BLex3_Engine_next( &engU->inherit_BLex3_Engine, 1 ); 207| BLex3_EngineU_skip( engU, " \t\n\r" ); 208| BLex3_EngineU_readWord( engU, 209| p, StrX_Mem_getLeftSize( &m->mem ), " =>\r\n\t", true ); 210| } 211| else { 212| *p = '\0'; 213| } 214| m->attr_values[m->attr_n] = p; 215| m->attr_n ++; 216| } 217| BLex3_Engine_next( &engU->inherit_BLex3_Engine, 1 ); 218| } 219| BLex3_Engine_getPos( &engU->inherit_BLex3_Engine, &m->parsedPos ); 220| m->prevTokenType = HtmlPars_StartOfTag; 221| m->bInTag = true; 222| return; 223| } 224| fp++; fp2++; 225| } 226| 227| BLex3_Engine_getPos2( &engU->inherit_BLex3_Engine, fp_over, &m->parsedPos ); 228| m->prevTokenType = BLex3_OutOfToken; 229| return; 230|} 231| 232| 233| 234|/************************************************************************** 235| 7. <<< [HtmlPars_getTokenType] 現在位置のトークンタイプを返す >>> 236|【補足】 237|・HtmlPars用トークンタイプを返します。 238|***************************************************************************/ 239|int HtmlPars_getTokenType( HtmlPars* m ) 240|{ 241| return m->prevTokenType; 242|} 243| 244|/************************************************************************** 245|* 8. <<< [HtmlPars_getNextParsePos] 次に解析すべき位置を取得する >>> 246|***************************************************************************/ 247|void HtmlPars_getNextParsePos( HtmlPars* m, BLex3_Pos* pos ) 248|{ 249| *pos = m->parsedPos; 250|} 251| 252| 253|/************************************************************************** 254|* 9. <<< [HtmlPars_isInTag] タグの途中またはコメントの途中かどうかを返す >>> 255|***************************************************************************/ 256|bool HtmlPars_isInTag( HtmlPars* m ) 257|{ 258| return m->bInTag && m->prevTokenType != HtmlPars_StartOfTag; 259|} 260| 261| 262|/************************************************************************** 263|* 10. <<< [HtmlPars_getValue] 属性の値を返す >>> 264|*【補足】 265|*・該当する属性が無いときは NULL を返します。 266|***************************************************************************/ 267|char* HtmlPars_getValue( HtmlPars* m, const char* attr_name ) 268|{ 269| char** s; 270| char** s_over = m->attr_names + m->attr_n; 271| 272| #ifndef NDEBUG 273| { 274| /* attr_name は小文字を指定してください */ 275| const char* p; 276| for ( p = attr_name; *p != '\0'; p++ ) { 277| ASSERT( (*p >= 'a' && *p <= 'z') || (*p >= '0' && *p <= '9') || 278| *p == '-' || *p == '_' || *p == ':' ); 279| } 280| } 281| #endif 282| 283| for ( s = m->attr_names; s < s_over; s++ ) { 284| if ( stricmp( *s, attr_name ) == 0 ) 285| return m->attr_values[ s - m->attr_names ]; 286| } 287| return NULL; 288|} 289| 290| 291|/************************************************************************** 292|* 11. <<< [HtmlPars_getTokenFirstPos] 現在位置にあるタグの先頭のファイルアドレスを返す >>> 293|*【引数】 294|* ・HtmlPars* m; HTML パーサ 295|* ・int 返り値; 現在位置にあるタグの先頭のファイルアドレス 296|***************************************************************************/ 297|#if 0 298|int HtmlPars_getTokenFirstPos( HtmlPars* m ) 299|{ 300| ERRORS_INITCHK( m, 1 ); 301| 302| return m->firstPos; 303|} 304|#endif 305| 306| 307|/************************************************************************** 308|* 12. <<< [HtmlPars_getTokenOverPos] 現在位置にあるタグの末尾の次のファイルアドレスを返す >>> 309|*【引数】 310|* ・HtmlPars* m; HTML パーサ 311|* ・int 返り値; 現在位置にあるタグの末尾の次のファイルアドレス 312|***************************************************************************/ 313|#if 0 314|int HtmlPars_getTokenOverPos( HtmlPars* m ) 315|{ 316| ERRORS_INITCHK( m, 1 ); 317| 318| return m->overPos; 319|} 320|#endif 321| 322| 323|/************************************************************************** 324|* 13. <<< [HtmlPars_printLastMsg] ファイル解析後に結果を出力する >>> 325|*【引数】 326|* ・HtmlPars* m; HTML パーサ 327|***************************************************************************/ 328|void HtmlPars_printLastMsg( HtmlPars* m, FILE* f, const char* title ) 329|{ 330| ERRORS_INITCHK( m, 1 ); 331| 332| /* no printing */ 333|} 334| 335| 336| 337|