Blex3.c

[目次 | 関数]

目次

関数一覧


   1|/**************************************************************************
   2|*  1. <<< 基本字句解析 ver.3 (BLex3)  >>> 
   3|***************************************************************************/
   4|
   5|#include "mixer_precomp.h"
   6|// #pragma hdrstop ("mixer_precomp")
   7|
   8|#ifdef  USES_MXP_AUTOINC
   9|#include  <BLex3.ah>  /* Auto include header, Look at mixer-... folder */
  10|#endif
  11|
  12|
  13|
  14| 
  15|/*---------------------------------------------------------------------*/
  16|/* 2. <<<◆(BLex3) 基本字句解析 ver.3 >>> */ 
  17|/*---------------------------------------------------------------------*/
  18|
  19| 
  20|/**************************************************************************
  21|*  3. <<< [BLex3_init] 初期化する >>> 
  22|*【引数】
  23|*  ・BLex3*  m;   基本字句解析 ver.3
  24|*【補足】
  25|*・
  26|***************************************************************************/
  27|#ifdef  USES_OTHER
  28|void  BLex3_init( BLex3* m )
  29|{
  30|  int  a;
  31|
  32|  ERRORS_INITCHK( m, 0 );
  33|  ASSERT( a >= 0 );
  34|
  35|  m->a = a;
  36|
  37|  ERRORS_FINISHCHK_FOR_INIT( BLex3_finish );
  38|}
  39|#endif
  40|
  41|
  42| 
  43|/**************************************************************************
  44|*  4. <<< [BLex3_finish] 後始末する >>> 
  45|***************************************************************************/
  46|#ifdef  USES_OTHER
  47|void  BLex3_finish( BLex3* m )
  48|{
  49|  ERRORS_INITCHK( m, 1 );
  50|  ERRORS_FINISHCHK_FOR_FINISH( BLex3_finish );
  51|
  52|  Other_finish( &m->a );
  53|}
  54|#endif
  55|
  56|
  57| 
  58|/**************************************************************************
  59|*  5. <<< [BLex3_assemble] 1つのファイルを字句解析をする >>> 
  60|*【引数】
  61|*  ・BLex3*  m;   基本字句解析 ver.3
  62|*【補足】
  63|*・
  64|***************************************************************************/
  65|BLex3_BackMsg  BLex3_assemble( BLex3* m, const char* in_path, const char* out_path )
  66|{
  67|#if 0
  68|  BLex3_BackMsg  msg;
  69|
  70|  BLex3_openFile( &lex, in_path, out_path );
  71|  c_try {
  72|    for (;;) {
  73|      for ( BLex3_forEachParser( &lex, &par, BLex3_Parser ) ) {
  74|        BLex3_Parser_parse( *par, &lex );
  75|      }
  76|      do {
  77|        for ( BLex3_forEachActor( &lex, &act, BLex3_Actor ) ) {
  78|          msg = BLex3_Actor_act( *act, &lex );
  79|          if ( msg & BLex3_BreakActLoop )  break;
  80|        }
  81|      } while ( msg & BLex3_ReActor );
  82|      if ( msg & BLex3_BreakTokenLoop )  break;
  83|    }
  84|  }
  85|  c_finally {
  86|    BLex3_closeFile( &lex );
  87|  } c_finally;
  88|
  89|  return  msg;
  90|#endif
  91|return  BLex3_NextActor;
  92|}
  93| 
  94|/**************************************************************************
  95|*  6. <<< [BLex3_next] ファイルポインタを進める >>> 
  96|*【引数】
  97|*  ・BLex3*  m;   基本字句解析 ver.3
  98|*【補足】
  99|*・
 100|***************************************************************************/
 101|void  BLex3_next( BLex3* m, int n )
 102|{
 103|#if 0
 104|  for ( BLex3_forEachCounter( &lex, &cnt, BLex3_Counter ) ) {
 105|    BLex3_Counter_count( *cnt, &lex, n );
 106|  }
 107|#endif
 108|}
 109| 
 110|/**************************************************************************
 111|*  7. <<< [BLex3_printLastMsg] 字句解析の最終結果を表示する >>> 
 112|*【引数】
 113|*  ・BLex3*  m;   基本字句解析 ver.3
 114|*【補足】
 115|*・たとえば、エラーの数や、行数などを表示します。
 116|***************************************************************************/
 117|void  BLex3_printLastMsg( BLex3* m )
 118|{
 119|#if 0
 120|  for ( BLex3_forEachParser( m, &par, BLex3_Parser ) ) {
 121|    BLex3_Parser_printLastMsg( *par, &lex );
 122|  }
 123|  for ( BLex3_forEachActor( m, &act, BLex3_Actor ) ) {
 124|    BLex3_Actor_printLastMsg( *act, &lex );
 125|  }
 126|  for ( BLex3_forEachCounter( m, &cnt, BLex3_Counter ) ) {
 127|    BLex3_Counter_printLastMsg( *cnt, &lex, n );
 128|  }
 129|#endif
 130|}
 131| 
 132|/*---------------------------------------------------------------------*/
 133|/* 8. <<<◆(BLex3_Pos) ファイル・アドレス >>> */ 
 134|/*---------------------------------------------------------------------*/
 135|
 136|BLex3_Pos  BLex3_nullPos = { -1L, BLex3_SJisUnknown };
 137| 
 138|/**************************************************************************
 139|*  9. <<< [BLex3_Pos_print] デバッグ表示する >>> 
 140|*************************************************************************/
 141|#ifndef  ERRORS_CUT_DEBUG_TOOL
 142|void  BLex3_Pos_print( BLex3_Pos* m, const char* title )
 143|{
 144|  Errors_printf( "%sBLex3_Pos[%p] pos=0x%lX, sjis_type=%d",
 145|    title, m, m->pos, m->sjis_type );
 146|}
 147|#endif
 148| 
 149|/*---------------------------------------------------------------------*/
 150|/* 10. <<<◆(BLex3_Engine) 字句解析エンジン >>> */ 
 151|/*---------------------------------------------------------------------*/
 152|
 153|void  BLex3_Engine_fillSJisBuf( BLex3_Engine*, char* buf_first,
 154|  char* buf_over, int firstType );
 155| 
 156|/**************************************************************************
 157|*  11. <<< [BLex3_Engine_init] 初期化する >>> 
 158|*【引数】
 159|*  ・BLex3_Engine*  m;   字句解析エンジン
 160|*  ・char*  path;    入力ファイルパス
 161|*  ・void*  buf;     内部バッファ領域として使う領域の先頭アドレス
 162|*  ・int  buf_size;  buf のメモリサイズ(バイト)
 163|*  ・int  sec_size;  ディスクのセクタサイズ(1024など)
 164|*【補足】
 165|*・セクタサイズは、API の GetDiskFreeSpace から取得できます。
 166|*・buf_size のうち、実際に使用されるサイズは buf_size - 1 以下で最も大きい
 167|*  sec_size の倍数です。これは、sec_size の倍数の余る分が '\0' で
 168|*  埋められ、これを文字列の末尾文字 '\0' として使用しているためです。
 169|***************************************************************************/
 170|void  BLex3_Engine_init( BLex3_Engine* m, const char* path,
 171|  void* buf, int buf_size, int sec_size )
 172|{
 173|  int  s = sec_size;
 174|  int  sft = 0;
 175|
 176|  /* セクタサイズは 2 の n 乗であること */
 177|  ASSERT( s != 0 );
 178|  while ( ( s & 1 ) == 0 )  { s >>= 1;  sft++; }
 179|  ASSERT( s == 1 );
 180|
 181|  /* ファイルオープン */
 182|  m->f = FileX_open( path, "rb" );
 183|
 184|  /* メンバ変数を初期化する */
 185|  m->buf = buf;
 186|  m->buf_over = (char*)buf + ( ((buf_size - 1) >> sft) << sft );
 187|  m->sec_size = sec_size;
 188|  m->sec_sft = sft;
 189|
 190|  m->sjis_buf = NULL;
 191|
 192|  m->pos.pos = 0L;
 193|  m->fp = buf;
 194|
 195|  /* 内部バッファの最後の使わない部分は '\0' で埋める */
 196|  memset( m->buf_over, 0, (char*)buf + buf_size - m->buf_over );
 197|
 198|  /* ファイルの内容を buf に読み込む */
 199|  {
 200|    int  count, result;
 201|
 202|    count = (buf_size - 1) >> sft;
 203|    result = fread( buf, sec_size, count, m->f );
 204|    if ( result < count ) {
 205|      fseek( m->f, 0, SEEK_END );
 206|      m->eof_first = (char*)buf + ftell( m->f );
 207|      memset( m->eof_first, 0, m->buf_over - m->eof_first );
 208|    }
 209|    else {
 210|      m->eof_first = (char*)buf + buf_size;
 211|    }
 212|  }
 213|
 214|  ERRORS_FINISHCHK_FOR_INIT( BLex3_Engine_finish );
 215|}
 216| 
 217|/**************************************************************************
 218|*  12. <<< [BLex3_Engine_finish] 後始末する >>> 
 219|***************************************************************************/
 220|void  BLex3_Engine_finish( BLex3_Engine* m )
 221|{
 222|  ERRORS_FINISHCHK_FOR_FINISH( BLex3_Engine_finish );
 223|
 224|  fclose( m->f );
 225|}
 226|
 227|
 228| 
 229|/**************************************************************************
 230|*  13. <<< [BLex3_Engine_print] デバッグ表示する >>> 
 231|***************************************************************************/
 232|#ifndef  ERRORS_CUT_DEBUG_TOOL
 233|void  BLex3_Engine_print( BLex3_Engine* m, const char* title )
 234|{
 235|  int  n;
 236|
 237|  Errors_printf( "%sbuf = %p, buf_over = %p, eof_first = %p, offset_over = %p",
 238|    title, m->buf, m->buf_over, m->eof_first, m->offset_over );
 239|  Errors_printf( "%ssec_size = %d, sec_sft = %d",
 240|    title, m->sec_size, m->sec_sft );
 241|  Errors_printf( "%spos(buf_first) = 0x%lX, pos(fp) = 0x%lX, fp = %p",
 242|    title, m->pos.pos, m->pos.pos + (m->fp - m->buf), m->fp );
 243|
 244|  n = m->buf_over - m->buf;
 245|  WX( m->buf, n );
 246|  n = m->buf_over - m->fp;
 247|  WX( m->fp, n );
 248|  if ( m->sjis_buf == NULL )
 249|    Errors_printf( "%ssjis_buf = NULL", title );
 250|  else {
 251|    n = m->buf_over - m->buf;
 252|    WX( m->sjis_buf, n );
 253|    n = m->buf_over - m->fp;
 254|    WX( m->sjis_buf + (m->fp - m->buf), n );
 255|  }
 256|}
 257|#endif
 258| 
 259|/**************************************************************************
 260|*  14. <<< [BLex3_Engine_setSJisBuf] Shift Jis 判定用バッファを使用する >>> 
 261|*【引数】
 262|*  ・void*  buf;      Shift Jis 判定用バッファに使う領域の先頭アドレス
 263|*  ・int  buf_size;   buf のサイズ(バイト)内部バッファと同じであること
 264|***************************************************************************/
 265|void  BLex3_Engine_setSJisBuf( BLex3_Engine* m, void* buf,
 266|  int  buf_size )
 267|{
 268|  ASSERT( m->pos.pos == 0 );
 269|  ASSERT( m->buf_over - m->buf <= buf_size );
 270|
 271|  m->sjis_buf = buf;
 272|
 273|  BLex3_Engine_fillSJisBuf( m, m->buf, m->buf_over,
 274|    _ismbblead( *m->buf ) ? BLex3_SJisFirst : BLex3_Ascii );
 275|}
 276|
 277|
 278| 
 279|/**************************************************************************
 280|*  15. <<< [BLex3_Engine_fillSJisBuf] Shift Jis 判定用バッファに情報を格納する >>> 
 281|*【引数】
 282|*  ・char*  buf_first;  判定を開始する内部バッファのアドレス
 283|*  ・char*  buf_over;   最後に判定する次の内部バッファのアドレス
 284|*  ・int  firstType;    buf_first の位置のバイト文字のタイプ(BLex3_Ascii など)
 285|*【補足】
 286|*・内部用です。
 287|***************************************************************************/
 288|void  BLex3_Engine_fillSJisBuf( BLex3_Engine* m, char* buf_first,
 289|  char* buf_over, int firstType )
 290|{
 291|  char*  p;   /* 内部バッファのポインタ */
 292|  char*  p2;  /* Shift Jis 判定バッファのポインタ */
 293|
 294|  if ( buf_first == buf_over )  return;
 295|
 296|  /* 最初のバイト文字の情報を格納する */
 297|  p2 = m->sjis_buf + (buf_first - m->buf);
 298|  *p2 = firstType;
 299|  if ( firstType == BLex3_SJisUnknown ) {
 300|    memset( p2, BLex3_SJisUnknown, buf_over - buf_first );
 301|    ERRORS_WARNING_0( "filled SJisUnknown" );
 302|    return;
 303|  }
 304|  else if ( firstType == BLex3_SJisFirst ) {
 305|    *(p2 + 1) = BLex3_SJisSecond;
 306|    p = buf_first + 2;
 307|    p2 += 2;
 308|  }
 309|  else {
 310|    p = buf_first + 1;
 311|    p2 ++;
 312|  }
 313|
 314|  /* 途中のバイト文字の情報を格納する */
 315|  while ( p < buf_over - 1 ) {
 316|    if ( _ismbblead( *p ) ) {
 317|      p += 2;
 318|      *p2 = BLex3_SJisFirst;
 319|      *(p2 + 1) = BLex3_SJisSecond;
 320|      p2 += 2;
 321|    }
 322|    else {
 323|      p ++;
 324|      *p2 = BLex3_Ascii;
 325|      p2 ++;
 326|    }
 327|  }
 328|
 329|  /* 最後のバイト文字の情報を格納する */
 330|  if ( p < buf_over ) {  /* except 2byte ch */
 331|    if ( _ismbblead( *p ) )
 332|      *p2 = BLex3_SJisFirst;
 333|    else
 334|      *p2 = BLex3_Ascii;
 335|  }
 336|}
 337|
 338| 
 339|/**************************************************************************
 340|*  16. <<< [BLex3_Engine_getFilePtr] アクセス用ファイルポインタを取得する >>> 
 341|*【引数】
 342|*  ・BLex3_Engine*  m;  字句解析エンジン
 343|*  ・int  offsetOver;  ファイルポインタからアクセスできる最大のオフセット+1
 344|*  ・char*  返り値;    ファイルポインタ、ファイルの末尾より後=NULL
 345|*【補足】
 346|*・BLex3_Engine_next 関数などを呼び出したら、前に本関数から取得したファイル
 347|*  ポインタは使えなくなります。
 348|*・返り値のファイルポインタ fp は、指定した最大のオフセット(fp + offsetOver)
 349|*  までアクセスできます。指定した offsetOver を超えて、内部バッファの最後まで
 350|*  アクセスすることもできます。
 351|*・offsetOver に 0 を指定したときは、
 352|*  内部バッファの最後(BLex3_Engine_getOverPtr() - 1)までアクセスできます。
 353|*  そのとき、少なくとも1バイトはアクセスできます。
 354|*・n 文字のキーワードと一致するかどうか判定するときは、offsetOver に n を
 355|*  指定します。ただし、in と inter のように、そのキーワードから始まる
 356|*  別のキーワードである可能性があることに注意してください。
 357|*・ファイルの末尾より後に相当する内部バッファには、'\0' が入ります。
 358|*・本関数は、内部バッファにファイルデータを読み込むときと読みこまないときが
 359|*  あります。
 360|***************************************************************************/
 361|char*  BLex3_Engine_getFilePtr( BLex3_Engine* m, int offsetOver )
 362|{
 363|  int  offset = ( (m->fp - m->buf) & (m->sec_size - 1) );
 364|  int  count, result;
 365|  char*  readAdr;
 366|
 367|  ASSERT( offsetOver >= 0 );
 368|  ASSERT( m->buf + m->sec_size + offsetOver <= m->buf_over );
 369|    /* offsetOver が大きすぎます */
 370|
 371|  /* 内部バッファの内容をファイルポインタのある前方の位置のデータに戻す */
 372|  if ( m->fp < m->buf ) {
 373|    char*  fp0 = m->fp - offset;
 374|    m->pos.pos += (m->fp - offset) - m->buf;
 375|    ASSERT( m->pos.pos >= 0 );
 376|    fseek( m->f, m->pos.pos, SEEK_SET );
 377|
 378|    readAdr = m->buf;
 379|    count = (m->buf_over - m->buf) >> m->sec_sft;
 380|    result = fread( readAdr, m->sec_size, count, m->f );
 381|    if ( result == 0 ) {
 382|      fseek( m->f, m->pos.pos + offset, SEEK_SET );  /* for next feof */
 383|      fgetc( m->f );  /* for next feof */
 384|    }
 385|    if ( result == 0 && feof( m->f ) ) {
 386|      m->fp = m->buf + offset;
 387|      m->eof_first = m->buf + offset;
 388|      return  NULL;
 389|    }
 390|    else if ( result < count ) {
 391|      fseek( m->f, 0, SEEK_END );
 392|      m->eof_first = m->buf + ( ftell( m->f ) - m->pos.pos );
 393|      if ( m->sjis_buf != NULL ) {
 394|        BLex3_Engine_fillSJisBuf( m, readAdr, m->eof_first,
 395|          m->pos.sjis_type );
 396|      }
 397|    }
 398|    else {
 399|      m->eof_first = m->buf_over;
 400|      if ( m->sjis_buf != NULL  /*&& result > 0*/ ) {  /* BLEX3_USES_OLD_010831 */
 401|        BLex3_Engine_fillSJisBuf( m, readAdr,
 402|          readAdr + (result << m->sec_sft), m->pos.sjis_type );
 403|      }
 404|    }
 405|    m->fp = m->buf + offset;
 406|    ASSERT( m->fp + offsetOver <= m->buf_over );
 407|
 408|    if ( offsetOver == 0 )  m->offset_over = m->buf_over;
 409|    else  m->offset_over = m->fp + offsetOver;
 410|    return  m->fp;
 411|  }
 412|
 413|  /* offsetOver までアクセスできないときは、内部バッファをスクロールする */
 414|  if ( m->fp + offsetOver > m->buf_over || m->fp >= m->buf_over ) {
 415|    char*  fp0 = m->fp - offset;
 416|    int   sjis_type = BLex3_Ascii;
 417|    int   seekPos;
 418|
 419|    /* 内部バッファの外を読みこむとき */
 420|    if ( fp0 >= m->buf_over ) {
 421|      seekPos = (fp0 - m->buf) + m->pos.pos;
 422|      fseek( m->f, seekPos, SEEK_SET );
 423|      if ( fp0 >= m->buf_over + m->sec_size ) {
 424|        sjis_type = m->pos.sjis_type;
 425|      }
 426|      else {
 427|        if ( m->sjis_buf != NULL )
 428|          sjis_type = *( m->sjis_buf + (m->buf_over - m->buf) - 1 );
 429|      }
 430|      readAdr = m->buf;
 431|      count = (m->buf_over - m->buf) >> m->sec_sft;
 432|    }
 433|    /* 内部バッファの一部をスクロールするとき */
 434|    else {
 435|      memmove( m->buf, fp0, m->buf_over - fp0 );
 436|      memmove( m->sjis_buf, m->sjis_buf + (fp0 - m->buf), m->buf_over - fp0 );
 437|      seekPos = m->pos.pos + (m->buf_over - m->buf);
 438|      fseek( m->f, seekPos, SEEK_SET );
 439|      readAdr = m->buf + (m->buf_over - fp0);
 440|      count = (fp0 - m->buf) >> m->sec_sft;
 441|      if ( m->sjis_buf != NULL )
 442|        sjis_type = *( m->sjis_buf + (fp0 - m->buf) - 1 );
 443|    }
 444|
 445|    /* 読みこむ */
 446|    result = fread( readAdr, m->sec_size, count, m->f );
 447|    if ( result == 0 ) {
 448|      fseek( m->f, seekPos, SEEK_SET );  fgetc( m->f );  /* for next feof */
 449|    }
 450|    if ( m->sjis_buf != NULL &&  ! feof(m->f) ) {
 451|      if ( sjis_type != BLex3_SJisUnknown ) {
 452|        if ( sjis_type == BLex3_SJisFirst )
 453|          sjis_type = BLex3_SJisSecond;
 454|        else
 455|          sjis_type = _ismbblead( *readAdr ) ? BLex3_SJisFirst : BLex3_Ascii;
 456|      }
 457|      BLex3_Engine_fillSJisBuf( m, readAdr,
 458|        readAdr + (result << m->sec_sft), sjis_type );
 459|    }
 460|    m->pos.pos += fp0 - m->buf;
 461|
 462|    /* EOF より後は、'\0' を埋め、m->eof_first を設定する */
 463|    if ( result < count ) {
 464|      int  fSizeOfs;
 465|
 466|      if ( m->eof_first < m->buf_over ) {
 467|        m->eof_first -= m->fp - offset - m->buf;
 468|        memset( readAdr, 0, m->buf_over - readAdr );
 469|      }
 470|      else {
 471|        fseek( m->f, 0, SEEK_END );
 472|        fSizeOfs = ftell( m->f ) % m->sec_size;
 473|        m->eof_first = readAdr + (result << m->sec_sft) + fSizeOfs;
 474|        BLex3_Engine_fillSJisBuf( m, readAdr, m->eof_first, sjis_type );
 475|        memset( m->eof_first, 0, m->sec_size - fSizeOfs );
 476|      }
 477|    }
 478|    else
 479|      m->eof_first = m->buf_over;
 480|
 481|    m->fp = m->buf + offset;
 482|    if ( offsetOver == 0 )  m->offset_over = m->buf_over;
 483|    else  m->offset_over = m->fp + offsetOver;
 484|    return  ( m->fp >= m->eof_first ) ? NULL : m->fp;
 485|  }
 486|
 487|  /* 読みこむ必要が無いとき */
 488|  else {
 489|    if ( offsetOver == 0 )  m->offset_over = m->buf_over;
 490|    else  m->offset_over = m->fp + offsetOver;
 491|    return  ( m->fp >= m->eof_first ) ? NULL : m->fp;
 492|  }
 493|}
 494|
 495| 
 496|/**************************************************************************
 497|*  17. <<< [BLex3_Engine_getFilePtrByPos] アクセス用ファイルポインタを取得する >>> 
 498|*【引数】
 499|*  ・BLex3_Engine*  m;  字句解析エンジン
 500|*  ・long  pos;            ファイル・アドレス
 501|*  ・char*  返り値;        ファイルポインタ
 502|*【補足】
 503|*・pos に内部バッファの外(末尾の次を除く)に相当するアドレスは指定できません。
 504|***************************************************************************/
 505|char*  BLex3_Engine_getFilePtrByPos( BLex3_Engine* m, long pos )
 506|{
 507|  char*  fp = m->buf + ( pos - m->pos.pos );
 508|
 509|  ASSERT( fp >= m->buf && fp <= m->buf_over );
 510|
 511|  return  fp;
 512|}
 513| 
 514|/**************************************************************************
 515|*  18. <<< [BLex3_Engine_getFilePtrByPos2] アクセス用ファイルポインタを取得する >>> 
 516|*【補足】
 517|*・pos に内部バッファの外が指定できる BLex3_Engine_getFilePtrByPos 関数です。
 518|*  ただし、ASSERT に引っかからないだけで、内部バッファの外の場合、
 519|*  返り値のファイルポインタを使って、ファイルの内容にアクセスできません。
 520|*  ファイルポインタの位置の比較のために使います。
 521|***************************************************************************/
 522|char*  BLex3_Engine_getFilePtrByPos2( BLex3_Engine* m, long pos )
 523|{
 524|  return  m->buf + ( pos - m->pos.pos );
 525|}
 526| 
 527|/**************************************************************************
 528|*  19. <<< [BLex3_Engine_getOverPtr] 内部バッファに入っている最後のデータの次のアドレスを返す >>> 
 529|*【引数】
 530|*  ・BLex3_Engine*  m;  字句解析エンジン
 531|*  ・char*  返り値;        アクセスできる領域の次のアドレス
 532|*【補足】
 533|*・返り値は、内部バッファのサイズや、ファイルの末尾を考慮しています。
 534|*・EOF(EndOfFile)かどうかは、BLex3_Engine_getFilePtr 関数か、
 535|*  BLex3_Engine_isPtrEOF 関数で判定できます。
 536|***************************************************************************/
 537|char*  BLex3_Engine_getOverPtr( BLex3_Engine* m )
 538|{
 539|  #if 0
 540|    return  m->eof_first < m->offset_over ? m->eof_first : m->offset_over;
 541|  #endif
 542|
 543|  return  m->eof_first < m->buf_over ? m->eof_first : m->buf_over;
 544|}
 545|
 546| 
 547|/**************************************************************************
 548|*  20. <<< [BLex3_Engine_isPtrEOF] 指定のファイルポインタの位置は EOF かを返す >>> 
 549|*【引数】
 550|*  ・BLex3_Engine*  m;  字句解析エンジン
 551|*  ・char*  fp;            ファイルポインタ
 552|*  ・bool  返り値;         fp は EOF(End of File)かどうか
 553|***************************************************************************/
 554|bool  BLex3_Engine_isPtrEOF( BLex3_Engine* m, char* fp )
 555|{
 556|  return  m->eof_first < m->buf_over && fp >= m->eof_first;
 557|}
 558|
 559| 
 560|/**************************************************************************
 561|*  21. <<< [BLex3_Engine_getSJisPtr] Shift Jis 判定バッファにアクセスするポインタを返す >>> 
 562|*【引数】
 563|*  ・BLex3_Engine*  m;  字句解析エンジン
 564|*  ・char*  返り値;        Shift Jis 判定バッファにアクセスするポインタ
 565|*【補足】
 566|*・本関数を呼び出す前に、BLex3_Engine_getFiltPtr 関数を呼び出してください。
 567|*・返り値を p とすると、*p で現在のファイルポインタの位置のコードタイプ
 568|*  (BLex3_Ascii など)を参照することができます。*(p+1) で次の位置の
 569|*  コードタイプを参照することができます。
 570|***************************************************************************/
 571|char*  BLex3_Engine_getSJisPtr( BLex3_Engine* m )
 572|{
 573|  char*  fp2;
 574|
 575|  ASSERT( m->sjis_buf != NULL );
 576|
 577|  fp2 = m->sjis_buf + ( m->fp - m->buf );
 578|
 579|  #if ! ERRORS_DEBUG_FALSE
 580|    ASSERT( *fp2 != BLex3_SJisUnknown );
 581|  #endif
 582|
 583|  return  fp2;
 584|}
 585|
 586| 
 587|/**************************************************************************
 588|*  22. <<< [BLex3_Engine_next] ファイルポインタを進める(バイト数指定) >>> 
 589|*【引数】
 590|*  ・BLex3_Engine*  m;  字句解析エンジン
 591|*  ・int  n;               進めるバイト数(負の数も可)
 592|*【補足】
 593|*・本関数を呼び出したら、前に BLex3_Engine_getFilePtr 関数から取得したファイル
 594|*  ポインタは使えなくなります。再び、BLex3_Engine_getFilePtr 関数を呼び出して、
 595|*  新しいファイルポインタを取得してください。
 596|***************************************************************************/
 597|void  BLex3_Engine_next( BLex3_Engine* m, int n )
 598|{
 599|  m->fp += n;
 600|  m->pos.sjis_type = BLex3_SJisUnknown;  /* BLex3_Engine_getFilePtr で本設定 */
 601|}
 602| 
 603|/**************************************************************************
 604|*  23. <<< [BLex3_Engine_nextBuf] 内部バッファの次の位置にファイルポインタを移動する >>> 
 605|*【引数】
 606|*  ・BLex3_Engine*  m;  字句解析エンジン
 607|***************************************************************************/
 608|void  BLex3_Engine_nextBuf( BLex3_Engine* m )
 609|{
 610|  m->fp = m->buf_over;
 611|}
 612| 
 613|/**************************************************************************
 614|*  24. <<< [BLex3_Engine_nextByPtr] ファイルポインタを進める(アドレス指定) >>> 
 615|*【引数】
 616|*  ・BLex3_Engine*  m;  字句解析エンジン
 617|*  ・char*  next_fp;       ファイルポインタ(→補足)
 618|*【補足】
 619|*・本関数は、BLex3_Engine_getFilePtr 関数で取得したポインタ fp を進めた
 620|*  アドレス next_fp = fp + n に m のファイルポインタを合わせます。
 621|*・next_fp は、BLex3_Engine_getFilePtr 関数から取得できる内部バッファの
 622|*  アドレスを指定します。内部バッファの外(前後)を指定しても、その位置に相当する
 623|*  ファイルアドレスに正しく設定します。
 624|***************************************************************************/
 625|void  BLex3_Engine_nextByPtr( BLex3_Engine* m, char* next_fp )
 626|{
 627|  m->fp = next_fp;
 628|  m->pos.sjis_type = BLex3_SJisUnknown;
 629|}
 630| 
 631|/**************************************************************************
 632|*  25. <<< [BLex3_Engine_getPos] ファイルポインタのある位置のファイルアドレスを返す >>> 
 633|*【引数】
 634|*  ・BLex3_Engine*  m;  字句解析エンジン
 635|*  ・BLex3_Pos*  pos;      (出力)ファイルアドレス
 636|*【補足】
 637|*・BLex3_Engine_getPos2 関数の fp 引数に、BLex3_Engine_getFilePtr 関数の返り値を
 638|*  そのまま指定したものと同じです。
 639|***************************************************************************/
 640|void  BLex3_Engine_getPos( BLex3_Engine* m, BLex3_Pos* pos )
 641|{
 642|  if ( m->fp - m->buf < 0 )
 643|    BLex3_Engine_getFilePtr( m, 0 );
 644|  pos->pos = m->pos.pos + (m->fp - m->buf);
 645|  if ( m->sjis_buf != NULL )
 646|    pos->sjis_type = *( m->sjis_buf + (m->fp - m->buf) );
 647|}
 648|
 649| 
 650|/**************************************************************************
 651|*  26. <<< [BLex3_Engine_getPos0] ファイルポインタのある位置のファイルアドレスを返す >>> 
 652|*【引数】
 653|*  ・BLex3_Engine*  m;  字句解析エンジン
 654|*  ・int  返り値;          ファイルアドレス
 655|*【補足】
 656|*・本関数の返り値では、BLex3_Engine_setPos 関数が使えませんが、
 657|*  BLex3_Pos::pos とファイルアドレスの大小比較ができます。
 658|***************************************************************************/
 659|int  BLex3_Engine_getPos0( BLex3_Engine* m )
 660|{
 661|  return  m->pos.pos + (m->fp - m->buf);
 662|}
 663|
 664| 
 665|/**************************************************************************
 666|*  27. <<< [BLex3_Engine_getPos2] ファイルアドレスを返す >>> 
 667|*【引数】
 668|*  ・BLex3_Engine*  m;  字句解析エンジン
 669|*  ・char*  fp;            ファイルポインタ(→補足)
 670|*  ・BLex3_Pos*  pos;      (出力)ファイルアドレス
 671|*【補足】
 672|*・fp は、BLex3_Engine_getFilePtr 関数から取得できる内部バッファの
 673|*  アドレスを指定します。
 674|*・fp の位置に対応するファイルアドレス(ファイルの先頭を0としたオフセット)
 675|*  を pos に格納します。取得したファイルアドレスは、BLex3_Engine_setPos 関数に使います。
 676|***************************************************************************/
 677|void  BLex3_Engine_getPos2( BLex3_Engine* m, char* fp, BLex3_Pos* pos )
 678|{
 679|  ASSERT( fp >= m->buf );
 680|
 681|  pos->pos = m->pos.pos + ( fp - m->buf );
 682|  if ( fp < m->buf_over ) {
 683|    pos->sjis_type = *( m->sjis_buf + (fp - m->buf) );
 684|  }
 685|
 686|  /* 内部バッファより後のアドレスを返すとき、sjis_type を求める */
 687|  else {
 688|    char*  p = m->sjis_buf + (m->buf_over - m->buf) - 1;
 689|    int  n;
 690|    int  c;
 691|
 692|    if ( *p == BLex3_SJisUnknown )  return;
 693|
 694|    /* 内部バッファの直後の文字について */
 695|    if ( *p == BLex3_SJisFirst ) {
 696|      if ( fp == m->buf_over ) {
 697|        pos->sjis_type = BLex3_SJisSecond;
 698|        return;
 699|      }
 700|      fseek( m->f, pos->pos + 1, SEEK_SET );
 701|      n = fp - m->buf_over - 1;
 702|    }
 703|    else {
 704|      fseek( m->f, pos->pos, SEEK_SET );
 705|      n = fp - m->buf_over;
 706|    }
 707|
 708|    /* 内部バッファの直後より後の文字について */
 709|    for(;;) {
 710|      c = fgetc( m->f );
 711|      if ( _ismbblead( c ) ) {
 712|        if ( n == 0 )
 713|          { pos->sjis_type = BLex3_SJisFirst;  return; }
 714|        else if ( n == 1 )
 715|          { pos->sjis_type = BLex3_SJisSecond;  return; }
 716|        fgetc( m->f );
 717|        n--;
 718|      }
 719|      else {
 720|        if ( n == 0 )
 721|          { pos->sjis_type = BLex3_Ascii;  return; }
 722|      }
 723|      n--;
 724|    }
 725|  }
 726|}
 727|
 728| 
 729|/**************************************************************************
 730|*  28. <<< [BLex3_Engine_getPos3] ファイルアドレスを返す >>> 
 731|*【引数】
 732|*  ・BLex3_Engine*  m;  字句解析エンジン
 733|*  ・int  n;               現在のファイルポインタの位置からの相対位置
 734|*  ・BLex3_Pos*  pos;      (出力)ファイルアドレス
 735|*【補足】
 736|*・相対位置が内部バッファの外でも構いません。
 737|***************************************************************************/
 738|void  BLex3_Engine_getPos3( BLex3_Engine* m, int n, BLex3_Pos* pos )
 739|{
 740|  ASSERT( n >= 0 && n < m->buf_over - m->buf );
 741|
 742|  if ( m->fp + n > m->buf_over ) {
 743|    BLex3_Pos  here;
 744|
 745|    Errors_notSupport();
 746|    BLex3_Engine_getPos( m, &here );
 747|    BLex3_Engine_next( m, n );
 748|    BLex3_Engine_getPos( m, pos );
 749|    BLex3_Engine_setPos( m, &here );  /* ファイルポインタがずれる */
 750|  }
 751|  else {
 752|    if ( m->fp + n == m->buf_over )
 753|      BLex3_Engine_getFilePtr( m, n + 1 );
 754|
 755|    pos->pos = m->pos.pos + ( m->fp - m->buf ) + n;
 756|    pos->sjis_type = *( m->sjis_buf + (m->fp - m->buf) + n );
 757|  }
 758|}
 759|
 760| 
 761|/**************************************************************************
 762|*  29. <<< [BLex3_Engine_getEndPos] ファイルの最後のファイルアドレスを返す >>> 
 763|*【引数】
 764|*  ・BLex3_Engine*  m;  字句解析エンジン
 765|*  ・BLex3_Pos*  pos;      (出力)最後のファイルアドレス
 766|***************************************************************************/
 767|void  BLex3_Engine_getEndPos( BLex3_Engine* m, BLex3_Pos* pos )
 768|{
 769|  fseek( m->f, 0, SEEK_END );
 770|  pos->pos = ftell( m->f );
 771|  pos->sjis_type = BLex3_SJisUnknown;
 772|}
 773|
 774| 
 775|/**************************************************************************
 776|*  30. <<< [BLex3_Engine_setPos] ファイルポインタを指定のファイルアドレスに移動する >>> 
 777|*【引数】
 778|*  ・BLex3_Engine*  m;  字句解析エンジン
 779|*  ・BLex3_Pos*  pos;      ファイルアドレス
 780|*【補足】
 781|*・pos は、BLex3_Engine_getPos 関数から取得したものを指定します。
 782|*・本関数を使って移動した位置のファイルの内容は、BLex3_Engine_getFilePtr 関数
 783|*  を使って取得したファイルポインタを使って参照します。
 784|***************************************************************************/
 785|void  BLex3_Engine_setPos( BLex3_Engine* m, BLex3_Pos* pos )
 786|{
 787|  ASSERT( pos->pos != BLex3_nullPos.pos );
 788|
 789|  m->fp = m->buf + ( pos->pos - m->pos.pos );
 790|  m->pos.sjis_type = pos->sjis_type;
 791|}
 792|
 793| 
 794|/**************************************************************************
 795|*  31. <<< [BLex3_Engine_setPos2] ファイルポインタを移動する(相対位置指定) >>> 
 796|*【引数】
 797|*  ・BLex3_Engine*  m;  字句解析エンジン
 798|*  ・BLex3_Pos*  pos;      ファイルアドレス
 799|*  ・int  n;               pos からの相対位置(0以上)
 800|***************************************************************************/
 801|void  BLex3_Engine_setPos2( BLex3_Engine* m, BLex3_Pos* pos, int n )
 802|{
 803|  bool  f = ( pos->pos < m->pos.pos );
 804|
 805|  BLex3_Engine_setPos( m, pos );
 806|  if ( f &&  m->sjis_buf != NULL )
 807|    BLex3_Engine_getFilePtr( m, 0 );
 808|  BLex3_Engine_next( m, n );
 809|}
 810|
 811| 
 812|/**************************************************************************
 813|*  32. <<< [BLex3_Engine_copy] 入力ファイルの一部をそのままファイルに出力する >>> 
 814|*【引数】
 815|*  ・BLex3_Engine*  m;  字句解析エンジン
 816|*  ・FILE*  out;           出力ファイル
 817|*  ・BLex3_Pos*  start;    出力を開始する入力ファイルのアドレス
 818|*  ・BLex3_Pos*  over;     最後の出力をする入力ファイルのアドレスの次
 819|***************************************************************************/
 820|#if 0
 821|void  BLex3_Engine_copy( BLex3_Engine* m, FILE* out,
 822|  BLex3_Pos* start, BLex3_Pos* over )
 823|{
 824|  char*  p = m->buf + ( start->pos - m->pos.pos );
 825|  int    overPos = m->pos.pos + ( m->buf_over - m->buf );
 826|  int    c;
 827|  char*  cp;
 828|
 829|  ASSERT( start->pos <= over->pos );
 830|
 831|  BLex3_Engine_setPos( m, start );
 832|  while ( overPos < over->pos ) {
 833|    fputs( p, out );
 834|    BLex3_Engine_nextBuf( m );
 835|    p = BLex3_Engine_getFilePtr( m, 0 );
 836|    if ( p == NULL )  return;
 837|    overPos = m->pos.pos + ( m->buf_over - m->buf );
 838|  }
 839|  cp = m->buf + ( over->pos - m->pos.pos );
 840|  c = *cp;
 841|  *cp = '\0';
 842|  fputs( p, out );
 843|  *cp = c;
 844|}
 845|#endif
 846|
 847| 
 848|/*---------------------------------------------------------------------*/
 849|/* 33. <<<◆(BLex3_EngineU) 字句解析エンジン・ユーティリティ >>> */ 
 850|/*---------------------------------------------------------------------*/
 851|
 852|void  BLex3_EngineU_writeHTML_sub( char* data, char* data_over, int* iLine,
 853|  FILE* out );
 854|void  BLex3_EngineU_getStr_sub( char* fp, char* fp_over,
 855|  char** ps, int* ps_size );
 856| 
 857|/**************************************************************************
 858|*  34. <<< [BLex3_EngineU_readWord] 指定の区切り文字が現れるまで読み込む >>> 
 859|*【引数】
 860|*  ・BLex3_EngineU*  m;  字句解析エンジン・ユーティリティ
 861|*  ・char*  s;              読込んだデータを格納する領域の先頭アドレス
 862|*  ・int  s_size;           s の領域のサイズ
 863|*  ・char*  terms;          区切り文字の並び
 864|*  ・bool  bDQ;             ダブルクォーテーションで囲むものを有効にするかどうか
 865|*【補足】
 866|*・現在のファイルポインタの位置(BLex3_Engine_getFilePtr で取得できるアドレス)
 867|*  から区切り文字(またはファイルの最後、または s_size)までを s に読み込みます。
 868|*・s の最後は、'\0'文字が格納されます。
 869|*・現在のファイルポインタの位置が " のとき、かつ bDQ が true のとき、
 870|*  terms に関係無く、"" で囲まれた部分を読み込みます。
 871|*・本関数を実行したら、現在のファイルポインタの位置が、区切り文字のある
 872|*  位置(または、ファイルの最後)に移動します。
 873|***************************************************************************/
 874|void  BLex3_EngineU_readWord( BLex3_EngineU* m,
 875|  char* s, int s_size, const char* terms, bool bDQ )
 876|{
 877|  char*  fp;
 878|  char*  p;
 879|  const char*  dq = "\"";
 880|  ArrX_Buf  s_buf;
 881|
 882|  ArrX_Buf_init( &s_buf, s, s_size );
 883|  ArrX_Buf_addStr( &s_buf, "" );
 884|
 885|  fp = BLex3_Engine_getFilePtr( &m->inherit_BLex3_Engine, 0 );
 886|  if ( bDQ && *fp == '\"' ) {
 887|    terms = dq;
 888|    BLex3_Engine_next( &m->inherit_BLex3_Engine, 1 );
 889|    fp = BLex3_Engine_getFilePtr( &m->inherit_BLex3_Engine, 0 );
 890|  }
 891|
 892|  while ( fp != NULL ) {
 893|
 894|    p = StrX_strchrs( fp, terms );
 895|    for (;;) {
 896|
 897|      /* 次のバッファへ: to next buffer */
 898|      if ( p == NULL ) {
 899|        ArrX_Buf_addMem( &s_buf, fp,
 900|          BLex3_Engine_getOverPtr( &m->inherit_BLex3_Engine ) - fp );
 901|        BLex3_Engine_nextBuf( &m->inherit_BLex3_Engine );
 902|        fp = BLex3_Engine_getFilePtr( &m->inherit_BLex3_Engine, 0 );
 903|        break;
 904|      }
 905|
 906|      /* "" で囲まれた文字列中に " が連続していたとき: case of "" in "" */
 907|      else if ( terms == dq && *p == '\"' && *(p + 1) == '\"' )
 908|        p = StrX_strchrs( p + 2, terms );
 909|
 910|      /* 区切り文字が見つかったとき: case of find term char */
 911|      else
 912|        goto  exit_while;
 913|    }
 914|  }
 915| exit_while:
 916|
 917|  ArrX_Buf_addMem( &s_buf, fp, p - fp );
 918|  ArrX_Buf_addChr( &s_buf, '\0' );
 919|  if ( fp != NULL ) {
 920|    if ( terms == dq )  p++;
 921|    BLex3_Engine_nextByPtr( &m->inherit_BLex3_Engine, p );
 922|  }
 923|}
 924|
 925| 
 926|/**************************************************************************
 927|*  35. <<< [BLex3_EngineU_skip] 指定の文字をスキップし続ける >>> 
 928|*【引数】
 929|*  ・BLex3_EngineU*  m;  字句解析エンジン・ユーティリティ
 930|*  ・char*  skipChars;      スキップする文字を並べた文字列
 931|*【補足】
 932|*・現在のファイルポインタの位置(BLex3_Engine_getFilePtr で取得できるアドレス)
 933|*  から skipChars に含まれる(半角)文字をスキップして、現在のファイルポインタの
 934|*  位置を進めます。
 935|*【例】
 936|*  BLex3_EngineU_skip( &eng, " \t\r\n" );  // 空白とタブと改行をスキップ
 937|***************************************************************************/
 938|void  BLex3_EngineU_skip( BLex3_EngineU* m, const char* skipChars )
 939|{
 940|  BLex3_Engine*  eng = &m->inherit_BLex3_Engine;
 941|  char*  fp;
 942|  char*  p;
 943|
 944|  for (;;) {
 945|    fp = BLex3_Engine_getFilePtr( eng, 0 );
 946|    if ( fp == NULL )  return;
 947|    p = StrX_strchrs_not( fp, skipChars );
 948|    if ( p != NULL )  break;
 949|    BLex3_Engine_nextBuf( eng );
 950|  }
 951|  BLex3_Engine_nextByPtr( eng, p );
 952|}
 953|
 954| 
 955|/**************************************************************************
 956|*  36. <<< [BLex3_EngineU_skipTo] 指定の文字までスキップし続ける >>> 
 957|*【引数】
 958|*  ・BLex3_EngineU*  m;  字句解析エンジン・ユーティリティ
 959|*  ・char*  terms;          スキップを止める文字を並べた文字列
 960|*  ・int  plus;             terms に含まれる文字のある位置からずらす量
 961|*【補足】
 962|*・現在のファイルポインタの位置(BLex3_Engine_getFilePtr で取得できるアドレス)
 963|*  から terms に含まれる(半角)文字までスキップして、現在のファイルポインタの
 964|*  位置を進めます。
 965|*・plus に +1 を指定すると、terms に含まれる文字の次の位置に、現在の
 966|*  ファイルポインタの位置を進めます。
 967|*【例】
 968|*  BLex3_EngineU_skipTo( &eng, "\n", 1 );  // 次の行までスキップする
 969|***************************************************************************/
 970|void  BLex3_EngineU_skipTo( BLex3_EngineU* m, const char* terms, int plus )
 971|{
 972|  BLex3_Engine*  eng = &m->inherit_BLex3_Engine;
 973|  char*  fp;
 974|  char*  fp2;
 975|  char*  p;
 976|
 977|  for (;;) {
 978|    fp = BLex3_Engine_getFilePtr( eng, 2 );
 979|    if ( fp == NULL )  return;
 980|    fp2 = BLex3_Engine_getSJisPtr( eng );
 981|    if ( *fp2 == BLex3_SJisSecond )  fp++;
 982|    p = StrX_strchrs2( fp, terms );
 983|    if ( p != NULL )  break;
 984|    BLex3_Engine_nextBuf( eng );
 985|  }
 986|  BLex3_Engine_nextByPtr( eng, p + plus );
 987|}
 988|
 989| 
 990|/**************************************************************************
 991|*  37. <<< [BLex3_EngineU_skipToStr] 指定の文字列までスキップし続ける >>> 
 992|*【引数】
 993|*  ・BLex3_EngineU*  m;  字句解析エンジン・ユーティリティ
 994|*  ・char*  term;           スキップを止める文字を並べた文字列
 995|*  ・int  plus;             term に含まれる文字のある位置からずらす量
 996|*  ・bool  bCase;           大文字小文字を区別するかどうか
 997|*【補足】
 998|*・現在のファイルポインタの位置(BLex3_Engine_getFilePtr で取得できるアドレス)
 999|*  から term に一致する位置までスキップして、現在のファイルポインタの位置を進めます。
1000|*・plus に +1 を指定すると、term に一致する先頭の位置の次の位置に、現在の
1001|*  ファイルポインタの位置を進めます。
1002|*【例】
1003|*  BLex3_EngineU_skipToStr( &eng, "end", 3, false );  // end の次までスキップする
1004|***************************************************************************/
1005|void  BLex3_EngineU_skipToStr( BLex3_EngineU* m, const char* term, int plus,
1006|  bool bCase )
1007|{
1008|  BLex3_Engine*  eng = &m->inherit_BLex3_Engine;
1009|  const int    term_len = strlen( term );
1010|  char*  fp;
1011|  char*  p;
1012|  int    hittingCount = 0;
1013|
1014|  for (;;) {
1015|    fp = BLex3_Engine_getFilePtr( eng, term_len );
1016|    p = StrX_stristr3( fp, term, bCase, &hittingCount );
1017|    if ( p != NULL )  break;
1018|    BLex3_Engine_nextBuf( eng );
1019|  }
1020|  BLex3_Engine_nextByPtr( eng, p + plus );
1021|}
1022|
1023| 
1024|/**************************************************************************
1025|*  38. <<< [BLex3_EngineU_skipTag] HTML のタグをスキップする >>> 
1026|*【引数】
1027|*  ・BLex3_EngineU*  m;  字句解析エンジン・ユーティリティ
1028|***************************************************************************/
1029|void  BLex3_EngineU_skipTag( BLex3_EngineU* m )
1030|{
1031|  char*  fp;
1032|  char*  fp_over;
1033|
1034|  fp = BLex3_Engine_getFilePtr( &m->inherit_BLex3_Engine, 4 );
1035|  fp_over = BLex3_Engine_getOverPtr( &m->inherit_BLex3_Engine );
1036|
1037|  ASSERT( *fp == '<' );
1038|
1039|  if ( strncmp( fp + 1, "!--", 3 ) == 0 ) {
1040|    BLex3_EngineU_skipToStr( m, "-->", +3, true );
1041|  }
1042|  else {
1043|    BLex3_EngineU_skipTo( m, ">", +1 );
1044|  }
1045|}
1046| 
1047|/**************************************************************************
1048|*  39. <<< [BLex3_EngineU_write] 指定の範囲をファイルに出力する >>> 
1049|*【引数】
1050|*  ・BLex3_EngineU*  m;  字句解析エンジン・ユーティリティ
1051|*  ・BLex3_Pos*  firstPos;  出力開始位置
1052|*  ・BLex3_Pos*  overPos;   出力終了の次の位置
1053|*  ・FILE*  out;            出力ファイル
1054|*【補足】
1055|*・本関数を呼び出したら、BLex3_Engine_setPos 関数と BLex3_Engine_getFilePtr
1056|*  関数を呼び出して、ファイルポインタの位置を再取得してください。
1057|***************************************************************************/
1058|void  BLex3_EngineU_write( BLex3_EngineU* m, BLex3_Pos* firstPos,
1059|  BLex3_Pos* overPos, FILE* out )
1060|{
1061|  BLex3_Engine*  eng = &m->inherit_BLex3_Engine;
1062|  char*  fp;
1063|  char*  fp_over;
1064|  BLex3_Pos  pos;
1065|
1066|  ASSERT( firstPos->pos <= overPos->pos );
1067|
1068|  BLex3_Engine_setPos( eng, firstPos );
1069|  for (;;) {
1070|    fp = BLex3_Engine_getFilePtr( eng, 0 );
1071|    fp_over = BLex3_Engine_getOverPtr( eng );
1072|    BLex3_Engine_getPos2( eng, fp_over, &pos );
1073|    if ( overPos->pos > pos.pos ) {
1074|      fwrite( fp, fp_over - fp, 1, out );
1075|      BLex3_Engine_nextBuf( eng );
1076|    }
1077|    else {
1078|      fp_over = BLex3_Engine_getFilePtrByPos( eng, overPos->pos );
1079|      fwrite( fp, fp_over - fp, 1, out );
1080|      return;
1081|    }
1082|  }
1083|}
1084|
1085| 
1086|/**************************************************************************
1087|*  40. <<< [BLex3_EngineU_writeHTML] 指定の範囲のテキストを HTML ファイルに出力する >>> 
1088|*【引数】
1089|*  ・BLex3_EngineU*  m;  字句解析エンジン・ユーティリティ
1090|*  ・BLex3_Pos*  firstPos;  出力開始位置
1091|*  ・BLex3_Pos*  overPos;   出力終了の次の位置
1092|*  ・int  iLine;            出力開始位置の行番号(-1で行番号を出力しない)
1093|*  ・FILE*  out;            出力ファイル
1094|*【補足】
1095|*・<, >, & を &lt;, &gt;, &amp; に変換します。
1096|*・行番号を出力します。
1097|*・特定のタグをそのまま出力するときは、HtmlPars を使って特定のタグを判定し、
1098|*  BLex3_EngineU_write 関数でファイルに出力します。
1099|***************************************************************************/
1100|void  BLex3_EngineU_writeHTML( BLex3_EngineU* m, BLex3_Pos* firstPos,
1101|  BLex3_Pos* overPos, int iLine, FILE* out )
1102|{
1103|  BLex3_Engine*  eng = &m->inherit_BLex3_Engine;
1104|  char*  fp;
1105|  char*  fp_over;
1106|  BLex3_Pos  pos;
1107|
1108|  ASSERT( firstPos->pos <= overPos->pos );
1109|  if (  firstPos->pos == overPos->pos )  return;
1110|
1111|  BLex3_Engine_setPos( eng, firstPos );
1112|  for (;;) {
1113|    fp = BLex3_Engine_getFilePtr( eng, 0 );
1114|    fp_over = BLex3_Engine_getOverPtr( eng );
1115|    BLex3_Engine_getPos2( eng, fp_over, &pos );
1116|    if ( overPos->pos > pos.pos ) {
1117|      BLex3_EngineU_writeHTML_sub( fp, fp_over, &iLine, out );
1118|      BLex3_Engine_nextBuf( eng );
1119|    }
1120|    else {
1121|      fp_over = BLex3_Engine_getFilePtrByPos( eng, overPos->pos );
1122|      BLex3_EngineU_writeHTML_sub( fp, fp_over, &iLine, out );
1123|      return;
1124|    }
1125|  }
1126|}
1127|
1128| 
1129|/**************************************************************************
1130|*  41. <<< [BLex3_EngineU_writeHTML_sub] テキストデータを HTML ファイルに出力する >>> 
1131|*【引数】
1132|*  ・char*  data;       出力するテキストファイルの内容の先頭アドレス
1133|*  ・char*  data_over;  同、末尾の次のアドレス
1134|*  ・int*   piLine;     (入力)data の行番号、(出力)data_over の行番号
1135|*  ・FILE*  out;        出力ファイル
1136|*【補足】
1137|*・BLex3_EngineU_writeHTML のサブルーチンです。
1138|***************************************************************************/
1139|void  BLex3_EngineU_writeHTML_sub( char* data, char* data_over, int* piLine,
1140|  FILE* out )
1141|{
1142|  char*  p;
1143|  char*  tp = data;  /* そのまま出力する先頭 */
1144|  int  iLine = *piLine;
1145|
1146|  for ( p = data; p < data_over; p++ ) {
1147|    switch ( *p ) {
1148|      case '<':
1149|        fwrite( tp, p - tp, 1, out );  tp = p + 1;
1150|        fputs( "&lt;", out );
1151|        break;
1152|      case '>':
1153|        fwrite( tp, p - tp, 1, out );  tp = p + 1;
1154|        fputs( "&gt;", out );
1155|        break;
1156|      case '&':
1157|        fwrite( tp, p - tp, 1, out );  tp = p + 1;
1158|        fputs( "&amp;", out );
1159|        break;
1160|      case '\n':
1161|        if ( iLine != -1 ) {
1162|          fwrite( tp, p - tp, 1, out );  tp = p + 1;
1163|          iLine ++;
1164|          fprintf( out, "\n%4d|", iLine );
1165|        }
1166|        break;
1167|    }
1168|  }
1169|  fwrite( tp, p - tp, 1, out );
1170|  *piLine = iLine;
1171|}
1172| 
1173|/**************************************************************************
1174|*  42. <<< [BLex3_EngineU_writeNoTag] HTML タグを除いた HTML をテキストファイルに出力する >>> 
1175|*【引数】
1176|*  ・BLex3_EngineU*  m;  字句解析エンジン・ユーティリティ
1177|*  ・BLex3_Pos*  firstPos;  出力開始位置
1178|*  ・BLex3_Pos*  overPos;   出力終了の次の位置
1179|*  ・FILE*  out;            出力ファイル
1180|*【補足】
1181|*・firstPos から overPos までの HTML テキストから <, > で囲まれた HTML タグを
1182|*  カットして、テキストファイルに出力します。
1183|*・firstPos から overPos までの先頭または末尾の空白、タブ、改行もカットします。
1184|***************************************************************************/
1185|void  BLex3_EngineU_writeNoTag( BLex3_EngineU* m, BLex3_Pos* firstPos,
1186|  BLex3_Pos* overPos, FILE* out )
1187|{
1188|  BLex3_Engine*  eng = &m->inherit_BLex3_Engine;
1189|  char*  fp;
1190|  char*  fp_over;
1191|  char*  fp_writeOver;
1192|  bool   bSpc;   /* 空白、タブ、改行、HTML タグが続いているかどうか */
1193|  BLex3_Pos  topPos;
1194|  BLex3_Pos  pos;
1195|  int   c;
1196|
1197|  ASSERT( firstPos->pos <= overPos->pos );
1198|
1199|  /* 最初の空白や HTML タグをスキップする */
1200|  BLex3_Engine_setPos( eng, firstPos );
1201|  fp = BLex3_Engine_getFilePtr( eng, 0 );
1202|  fp_over = BLex3_Engine_getOverPtr( eng );
1203|
1204|  for (;;) {
1205|    c = *fp;
1206|    if ( c == ' ' || c == '\t' || c == '\r' || c == '\n' ) {
1207|      fp++;
1208|      if ( fp == fp_over ) {
1209|        BLex3_Engine_nextBuf( eng );
1210|        fp = BLex3_Engine_getFilePtr( eng, 0 );
1211|        fp_over = BLex3_Engine_getOverPtr( eng );
1212|      }
1213|    }
1214|    else if ( c == '<' ) {
1215|      BLex3_Engine_nextByPtr( eng, fp );
1216|      BLex3_EngineU_skipTag( m );
1217|      fp = BLex3_Engine_getFilePtr( eng, 0 );
1218|      fp_over = BLex3_Engine_getOverPtr( eng );
1219|    }
1220|    else
1221|      break;
1222|  }
1223|  fp_writeOver = BLex3_Engine_getFilePtrByPos2( eng, overPos->pos );
1224|  if ( fp_writeOver < fp_over )  fp_over = fp_writeOver;
1225|
1226|  /* 末尾の空白や HTML タグの前までファイルに出力する */
1227|  bSpc = false;
1228|  BLex3_Engine_getPos2( eng, fp, &topPos );
1229|
1230|  for (;;) {
1231|    c = *fp;
1232|    if ( c == ' ' || c == '\t' || c == '\r' || c == '\n' || c == '<' ) {
1233|
1234|      /* 空白などが始まったら、それまでを出力する */
1235|      if ( ! bSpc ) {
1236|        BLex3_Engine_getPos2( eng, fp, &pos );
1237|        BLex3_EngineU_write( m, &topPos, &pos, out );
1238|
1239|        BLex3_Engine_setPos( eng, &pos );
1240|        fp = BLex3_Engine_getFilePtr( eng, 0 );
1241|        fp_over = BLex3_Engine_getOverPtr( eng );
1242|        fp_writeOver = BLex3_Engine_getFilePtrByPos2( eng, overPos->pos );
1243|        if ( fp_writeOver < fp_over )  fp_over = fp_writeOver;
1244|
1245|        BLex3_Pos_copy( &topPos, &pos );
1246|        bSpc = true;
1247|      }
1248|
1249|      /* タグをスキップする */
1250|      if ( c == '<' ) {
1251|        BLex3_Engine_nextByPtr( eng, fp );
1252|        BLex3_EngineU_skipTag( m );
1253|        BLex3_Engine_getPos( eng, &topPos );
1254|        fp = BLex3_Engine_getFilePtr( eng, 0 );
1255|        fp_over = BLex3_Engine_getOverPtr( eng );
1256|        fp_writeOver = BLex3_Engine_getFilePtrByPos2( eng, overPos->pos );
1257|        if ( fp_writeOver < fp_over )  fp_over = fp_writeOver;
1258|      }
1259|      else
1260|        fp++;
1261|    }
1262|    else {
1263|      bSpc = false;
1264|      fp++;
1265|    }
1266|
1267|    /* fp が内部バッファを超えたら更新する */
1268|    if ( fp >= fp_over ) {
1269|      if ( fp >= fp_writeOver ) {
1270|        break;
1271|      }
1272|      BLex3_Engine_nextBuf( eng );
1273|      fp = BLex3_Engine_getFilePtr( eng, 0 );
1274|      fp_over = BLex3_Engine_getOverPtr( eng );
1275|      fp_writeOver = BLex3_Engine_getFilePtrByPos2( eng, overPos->pos );
1276|      if ( fp_writeOver < fp_over )  fp_over = fp_writeOver;
1277|    }
1278|  }
1279|
1280|  /* 最後が空白でなかったら、最後まで出力する */
1281|  if ( ! bSpc ) {
1282|    BLex3_EngineU_write( m, &topPos, overPos, out );
1283|  }
1284|}
1285|
1286| 
1287|/**************************************************************************
1288|*  43. <<< [BLex3_EngineU_getStr] 指定の範囲を文字列として取得する >>> 
1289|*【引数】
1290|*  ・BLex3_EngineU*  m;  字句解析エンジン・ユーティリティ
1291|*  ・BLex3_Pos*  firstPos;  出力開始位置
1292|*  ・BLex3_Pos*  overPos;   出力終了の次の位置
1293|*  ・char*  s;              文字列を格納する領域の先頭アドレス
1294|*  ・int  s_size;           s のサイズ
1295|***************************************************************************/
1296|void  BLex3_EngineU_getStr( BLex3_EngineU* m, BLex3_Pos* firstPos,
1297|  BLex3_Pos* overPos, char* s, int s_size )
1298|{
1299|  BLex3_Engine*  eng = &m->inherit_BLex3_Engine;
1300|  char*  fp;
1301|  char*  fp_over;
1302|  BLex3_Pos  pos;
1303|
1304|  ASSERT( firstPos->pos <= overPos->pos );
1305|
1306|  BLex3_Engine_setPos( eng, firstPos );
1307|  for (;;) {
1308|    fp = BLex3_Engine_getFilePtr( eng, 0 );
1309|    fp_over = BLex3_Engine_getOverPtr( eng );
1310|    BLex3_Engine_getPos2( eng, fp_over, &pos );
1311|    if ( overPos->pos > pos.pos ) {
1312|      BLex3_EngineU_getStr_sub( fp, fp_over, &s, &s_size );
1313|      if ( s_size <= 0 )  return;
1314|      BLex3_Engine_nextBuf( eng );
1315|    }
1316|    else {
1317|      fp_over = BLex3_Engine_getFilePtrByPos( eng, overPos->pos );
1318|      BLex3_EngineU_getStr_sub( fp, fp_over, &s, &s_size );
1319|      return;
1320|    }
1321|  }
1322|}
1323|
1324| 
1325|/**************************************************************************
1326|*  44. <<< [BLex3_EngineU_getStr_sub] テキストデータを文字列として取得する >>> 
1327|*【引数】
1328|*  ・char*  fp;       出力するテキストファイルの内容の先頭アドレス
1329|*  ・char*  fp_over;  同、末尾の次のアドレス
1330|*  ・char*  ps;       (入力)取得領域のアドレス、(出力)次の取得アドレス
1331|*  ・int*   ps_size;  (入力)取得領域のサイズ、(出力)残りのサイズ
1332|*【補足】
1333|*・BLex3_EngineU_getStr のサブルーチンです。
1334|***************************************************************************/
1335|void  BLex3_EngineU_getStr_sub( char* fp, char* fp_over,
1336|  char** ps, int* ps_size )
1337|{
1338|  char*  s = *ps;
1339|  int    s_size_1 = *ps_size - 1;
1340|  int    f_size = fp_over - fp;
1341|
1342|  if ( f_size < s_size_1 ) {
1343|    memcpy( s, fp, f_size );
1344|    s[f_size] = '\0';
1345|    *ps = s + f_size;
1346|    (*ps_size) -= f_size;
1347|  }
1348|  else {
1349|    memcpy( s, fp, s_size_1 );
1350|    s[s_size_1] = '\0';
1351|    *ps = s + s_size_1;
1352|    (*ps_size) -= s_size_1;
1353|  }
1354|}
1355| 
1356|/*---------------------------------------------------------------------*/
1357|/* 45. <<<◆(BLex3_Parser) パーサ >>> */ 
1358|/*---------------------------------------------------------------------*/
1359|
1360| 
1361|/***********************************************************************
1362|*  46. <<< BLex3_Parser インターフェイス・関数定義 >>> 
1363|************************************************************************/
1364|#ifndef  NDEBUG
1365|INF_FUNC_0( BLex3_Parser, finish, void, BLex3_Parser_finish, BLex3_Parser, t );
1366|INF_FUNC_1( BLex3_Parser, linkEngine, void, BLex3_Parser_setEngine, BLex3_Parser, BLex3_Engine*, t,a );
1367|INF_FUNC_0( BLex3_Parser, parse, void, BLex3_Parser_parse, BLex3_Parser, t );
1368|INF_FUNC_R0( BLex3_Parser, getTokenType, int, BLex3_Parser_getTokenType, BLex3_Parser, t );
1369|INF_FUNC_1( BLex3_Parser, getNextParsePos, void, BLex3_Parser_getNextParsePos, BLex3_Parser, BLex3_Pos*, t,a );
1370|INF_FUNC_0( BLex3_Parser, printLastMsg, void, BLex3_Parser_printLastMsg, BLex3_Parser, t );
1371|#endif
1372|
1373| 
1374|