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, 1 );
 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|            break;
 179|          }
 180|          if ( m->attr_names + m->attr_n >= m->attr_values ) {
 181|            BLex3_EngineU_skipTo( engU, ">", 0 );
 182|            break;
 183|          }
 184|          p = StrX_Mem_alloc( &m->mem );
 185|          BLex3_EngineU_readWord( engU,
 186|            p, StrX_Mem_getLeftSize( &m->mem ), " =>\r\n\t", true );
 187|          StrX_cpyLower( p, p );
 188|          m->attr_names[m->attr_n] = p;
 189|
 190|          /* 属性値を取得する: get attribute value */
 191|          BLex3_EngineU_skip( engU, " \t\n\r" );
 192|          fp = BLex3_Engine_getFilePtr( &engU->inherit_BLex3_Engine, 1 );
 193|          if ( fp == NULL || *fp == '>' )  break;
 194|          p = StrX_Mem_alloc( &m->mem );
 195|          if ( *fp == '=' ) {
 196|            BLex3_Engine_next( &engU->inherit_BLex3_Engine, 1 );
 197|            BLex3_EngineU_skip( engU, " \t\n\r" );
 198|            BLex3_EngineU_readWord( engU,
 199|              p, StrX_Mem_getLeftSize( &m->mem ), " =>\r\n\t", true );
 200|          }
 201|          else {
 202|            *p = '\0';
 203|          }
 204|          m->attr_values[m->attr_n] = p;
 205|          m->attr_n ++;
 206|        }
 207|        BLex3_Engine_next( &engU->inherit_BLex3_Engine, 1 );
 208|      }
 209|      BLex3_Engine_getPos( &engU->inherit_BLex3_Engine, &m->parsedPos );
 210|      m->prevTokenType = HtmlPars_StartOfTag;
 211|      m->bInTag = true;
 212|      return;
 213|    }
 214|    fp++;  fp2++;
 215|  }
 216|
 217|  BLex3_Engine_getPos2( &engU->inherit_BLex3_Engine, fp_over, &m->parsedPos );
 218|  m->prevTokenType = BLex3_OutOfToken;
 219|  return;
 220|}
 221|
 222|
 223| 
 224|/**************************************************************************
 225|  7. <<< [HtmlPars_getTokenType] 現在位置のトークンタイプを返す >>> 
 226|【補足】
 227|・HtmlPars用トークンタイプを返します。
 228|***************************************************************************/
 229|int  HtmlPars_getTokenType( HtmlPars* m )
 230|{
 231|  return  m->prevTokenType;
 232|}
 233| 
 234|/**************************************************************************
 235|*  8. <<< [HtmlPars_getNextParsePos] 次に解析すべき位置を取得する >>> 
 236|***************************************************************************/
 237|void  HtmlPars_getNextParsePos( HtmlPars* m, BLex3_Pos* pos )
 238|{
 239|  *pos = m->parsedPos;
 240|}
 241|
 242| 
 243|/**************************************************************************
 244|*  9. <<< [HtmlPars_isInTag] タグの途中またはコメントの途中かどうかを返す >>> 
 245|***************************************************************************/
 246|bool  HtmlPars_isInTag( HtmlPars* m )
 247|{
 248|  return  m->bInTag && m->prevTokenType != HtmlPars_StartOfTag;
 249|}
 250|
 251| 
 252|/**************************************************************************
 253|*  10. <<< [HtmlPars_getValue] 属性の値を返す >>> 
 254|*【補足】
 255|*・該当する属性が無いときは NULL を返します。
 256|***************************************************************************/
 257|char*  HtmlPars_getValue( HtmlPars* m, const char* attr_name )
 258|{
 259|  char**  s;
 260|  char**  s_over = m->attr_names + m->attr_n;
 261|
 262|  #ifndef  NDEBUG
 263|  {
 264|    /* attr_name は小文字を指定してください */
 265|    const char*  p;
 266|    for ( p = attr_name; *p != '\0'; p++ ) {
 267|      ASSERT( (*p >= 'a' && *p <= 'z') || (*p >= '0' && *p <= '9') ||
 268|        *p == '_' || *p == ':' );
 269|    }
 270|  }
 271|  #endif
 272|
 273|  for ( s = m->attr_names;  s < s_over; s++ ) {
 274|    if ( stricmp( *s, attr_name ) == 0 )
 275|      return  m->attr_values[ s - m->attr_names ];
 276|  }
 277|  return  NULL;
 278|}
 279|
 280| 
 281|/**************************************************************************
 282|*  11. <<< [HtmlPars_getTokenFirstPos] 現在位置にあるタグの先頭のファイルアドレスを返す >>> 
 283|*【引数】
 284|*  ・HtmlPars*  m;   HTML パーサ
 285|*  ・int  返り値;       現在位置にあるタグの先頭のファイルアドレス
 286|***************************************************************************/
 287|#if 0
 288|int  HtmlPars_getTokenFirstPos( HtmlPars* m )
 289|{
 290|  ERRORS_INITCHK( m, 1 );
 291|
 292|  return  m->firstPos;
 293|}
 294|#endif
 295|
 296| 
 297|/**************************************************************************
 298|*  12. <<< [HtmlPars_getTokenOverPos] 現在位置にあるタグの末尾の次のファイルアドレスを返す >>> 
 299|*【引数】
 300|*  ・HtmlPars*  m;   HTML パーサ
 301|*  ・int  返り値;       現在位置にあるタグの末尾の次のファイルアドレス
 302|***************************************************************************/
 303|#if 0
 304|int  HtmlPars_getTokenOverPos( HtmlPars* m )
 305|{
 306|  ERRORS_INITCHK( m, 1 );
 307|
 308|  return  m->overPos;
 309|}
 310|#endif
 311|
 312| 
 313|/**************************************************************************
 314|*  13. <<< [HtmlPars_printLastMsg] ファイル解析後に結果を出力する >>> 
 315|*【引数】
 316|*  ・HtmlPars*  m;   HTML パーサ
 317|***************************************************************************/
 318|void  HtmlPars_printLastMsg( HtmlPars* m, FILE* f, const char* title )
 319|{
 320|  ERRORS_INITCHK( m, 1 );
 321|
 322|  /* no printing */
 323|}
 324|
 325|
 326| 
 327|