htmlpars.c

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|