blex3.c

C:\home\SVGCats_src\src\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;  ディスクのセクタサイズ
 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|
 375|    m->pos.pos += (m->fp - offset) - m->buf;
 376|    ASSERT( m->pos.pos >= 0 );
 377|    fseek( m->f, m->pos.pos, SEEK_SET );
 378|
 379|    readAdr = m->buf;
 380|    count = (m->buf_over - m->buf) >> m->sec_sft;
 381|    result = fread( readAdr, m->sec_size, count, m->f );
 382|    if ( result == 0 ) {
 383|      fseek( m->f, m->pos.pos + offset, SEEK_SET );  /* for next feof */
 384|      fgetc( m->f );  /* for next feof */
 385|    }
 386|    if ( result == 0 && feof( m->f ) ) {
 387|      m->fp = m->buf + offset;
 388|      m->eof_first = m->buf + offset;
 389|      return  NULL;
 390|    }
 391|    else if ( result < count ) {
 392|      fseek( m->f, 0, SEEK_END );
 393|      m->eof_first = m->buf + ( ftell( m->f ) - m->pos.pos );
 394|      if ( m->sjis_buf != NULL ) {
 395|        BLex3_Engine_fillSJisBuf( m, readAdr, m->eof_first,
 396|          m->pos.sjis_type );
 397|      }
 398|    }
 399|    else {
 400|      m->eof_first = m->buf_over;
 401|      if ( m->sjis_buf != NULL  /*&& result > 0*/ ) {  /* BLEX3_USES_OLD_010831 */
 402|        BLex3_Engine_fillSJisBuf( m, readAdr,
 403|          readAdr + (result << m->sec_sft), m->pos.sjis_type );
 404|      }
 405|    }
 406|    m->fp = m->buf + offset;
 407|    ASSERT( m->fp + offsetOver <= m->buf_over );
 408|
 409|    if ( offsetOver == 0 )  m->offset_over = m->buf_over;
 410|    else  m->offset_over = m->fp + offsetOver;
 411|    return  m->fp;
 412|  }
 413|
 414|  /* offsetOver までアクセスできないときは、内部バッファをスクロールする */
 415|  if ( m->fp + offsetOver > m->buf_over || m->fp >= m->buf_over ) {
 416|    char*  fp0 = m->fp - offset;
 417|    int   sjis_type = BLex3_Ascii;
 418|    int   seekPos;
 419|
 420|    /* 内部バッファの外を読みこむとき */
 421|    if ( fp0 >= m->buf_over ) {
 422|      seekPos = (fp0 - m->buf) + m->pos.pos;
 423|      fseek( m->f, seekPos, SEEK_SET );
 424|      if ( fp0 >= m->buf_over + m->sec_size ) {
 425|        sjis_type = m->pos.sjis_type;
 426|      }
 427|      else {
 428|        if ( m->sjis_buf != NULL )
 429|          sjis_type = *( m->sjis_buf + (m->buf_over - m->buf) - 1 );
 430|      }
 431|      readAdr = m->buf;
 432|      count = (m->buf_over - m->buf) >> m->sec_sft;
 433|    }
 434|    /* 内部バッファの一部をスクロールするとき */
 435|    else {
 436|      memmove( m->buf, fp0, m->buf_over - fp0 );
 437|      memmove( m->sjis_buf, m->sjis_buf + (fp0 - m->buf), m->buf_over - fp0 );
 438|      seekPos = m->pos.pos + (m->buf_over - m->buf);
 439|      fseek( m->f, seekPos, SEEK_SET );
 440|      readAdr = m->buf + (m->buf_over - fp0);
 441|      count = (fp0 - m->buf) >> m->sec_sft;
 442|      if ( m->sjis_buf != NULL )
 443|        sjis_type = *( m->sjis_buf + (fp0 - m->buf) - 1 );
 444|    }
 445|
 446|    /* 読みこむ */
 447|    result = fread( readAdr, m->sec_size, count, m->f );
 448|    if ( result == 0 ) {
 449|      fseek( m->f, seekPos, SEEK_SET );  fgetc( m->f );  /* for next feof */
 450|    }
 451|    if ( m->sjis_buf != NULL &&  ! feof(m->f) ) {
 452|      if ( sjis_type != BLex3_SJisUnknown ) {
 453|        if ( sjis_type == BLex3_SJisFirst )
 454|          sjis_type = BLex3_SJisSecond;
 455|        else
 456|          sjis_type = _ismbblead( *readAdr ) ? BLex3_SJisFirst : BLex3_Ascii;
 457|      }
 458|      BLex3_Engine_fillSJisBuf( m, readAdr,
 459|        readAdr + (result << m->sec_sft), sjis_type );
 460|    }
 461|    m->pos.pos += fp0 - m->buf;
 462|
 463|    /* EOF より後は、'\0' を埋め、m->eof_first を設定する */
 464|    if ( result < count ) {
 465|      int  fSizeOfs;
 466|
 467|      if ( m->eof_first < m->buf_over ) {
 468|        m->eof_first -= m->fp - offset - m->buf;
 469|        memset( readAdr, 0, m->buf_over - readAdr );
 470|      }
 471|      else {
 472|        fseek( m->f, 0, SEEK_END );
 473|        fSizeOfs = ftell( m->f ) % m->sec_size;
 474|        m->eof_first = readAdr + (result << m->sec_sft) + fSizeOfs;
 475|        BLex3_Engine_fillSJisBuf( m, readAdr, m->eof_first, sjis_type );
 476|        memset( m->eof_first, 0, m->sec_size - fSizeOfs );
 477|      }
 478|    }
 479|    else
 480|      m->eof_first = m->buf_over;
 481|
 482|    m->fp = m->buf + offset;
 483|    if ( offsetOver == 0 )  m->offset_over = m->buf_over;
 484|    else  m->offset_over = m->fp + offsetOver;
 485|    return  ( m->fp >= m->eof_first ) ? NULL : m->fp;
 486|  }
 487|
 488|  /* 読みこむ必要が無いとき */
 489|  else {
 490|    if ( offsetOver == 0 )  m->offset_over = m->buf_over;
 491|    else  m->offset_over = m->fp + offsetOver;
 492|    return  ( m->fp >= m->eof_first ) ? NULL : m->fp;
 493|  }
 494|}
 495|
 496| 
 497|/**************************************************************************
 498|*  17. <<< [BLex3_Engine_getFilePtrByPos] アクセス用ファイルポインタを取得する >>> 
 499|*【引数】
 500|*  ・BLex3_Engine*  m;  字句解析エンジン
 501|*  ・long  pos;            ファイル・アドレス
 502|*  ・char*  返り値;        ファイルポインタ
 503|*【補足】
 504|*・pos に内部バッファの外(末尾の次を除く)に相当するアドレスは指定できません。
 505|***************************************************************************/
 506|char*  BLex3_Engine_getFilePtrByPos( BLex3_Engine* m, long pos )
 507|{
 508|  char*  fp = m->buf + ( pos - m->pos.pos );
 509|
 510|  ASSERT( fp >= m->buf && fp <= m->buf_over );
 511|
 512|  return  fp;
 513|}
 514| 
 515|/**************************************************************************
 516|*  18. <<< [BLex3_Engine_getFilePtrByPos2] アクセス用ファイルポインタを取得する >>> 
 517|*【補足】
 518|*・pos に内部バッファの外が指定できる BLex3_Engine_getFilePtrByPos 関数です。
 519|*  ただし、ASSERT に引っかからないだけで、内部バッファの外の場合、
 520|*  返り値のファイルポインタを使って、ファイルの内容にアクセスできません。
 521|*  ファイルポインタの位置の比較のために使います。
 522|***************************************************************************/
 523|char*  BLex3_Engine_getFilePtrByPos2( BLex3_Engine* m, long pos )
 524|{
 525|  return  m->buf + ( pos - m->pos.pos );
 526|}
 527| 
 528|/**************************************************************************
 529|*  19. <<< [BLex3_Engine_getOverPtr] 内部バッファに入っている最後のデータの次のアドレスを返す >>> 
 530|*【引数】
 531|*  ・BLex3_Engine*  m;  字句解析エンジン
 532|*  ・char*  返り値;        アクセスできる領域の次のアドレス
 533|*【補足】
 534|*・返り値は、内部バッファのサイズや、ファイルの末尾を考慮しています。
 535|*・EOF(EndOfFile)かどうかは、BLex3_Engine_getFilePtr 関数か、
 536|*  BLex3_Engine_isPtrEOF 関数で判定できます。
 537|***************************************************************************/
 538|char*  BLex3_Engine_getOverPtr( BLex3_Engine* m )
 539|{
 540|  #if 0
 541|    return  m->eof_first < m->offset_over ? m->eof_first : m->offset_over;
 542|  #endif
 543|
 544|  return  m->eof_first < m->buf_over ? m->eof_first : m->buf_over;
 545|}
 546|
 547| 
 548|/**************************************************************************
 549|*  20. <<< [BLex3_Engine_isPtrEOF] 指定のファイルポインタの位置は EOF かを返す >>> 
 550|*【引数】
 551|*  ・BLex3_Engine*  m;  字句解析エンジン
 552|*  ・char*  fp;            ファイルポインタ
 553|*  ・bool  返り値;         fp は EOF(End of File)かどうか
 554|***************************************************************************/
 555|bool  BLex3_Engine_isPtrEOF( BLex3_Engine* m, char* fp )
 556|{
 557|  return  m->eof_first < m->buf_over && fp >= m->eof_first;
 558|}
 559|
 560| 
 561|/**************************************************************************
 562|*  21. <<< [BLex3_Engine_getSJisPtr] Shift Jis 判定バッファにアクセスするポインタを返す >>> 
 563|*【引数】
 564|*  ・BLex3_Engine*  m;  字句解析エンジン
 565|*  ・char*  返り値;        Shift Jis 判定バッファにアクセスするポインタ
 566|*【補足】
 567|*・本関数を呼び出す前に、BLex3_Engine_getFiltPtr 関数を呼び出してください。
 568|*・返り値を p とすると、*p で現在のファイルポインタの位置のコードタイプ
 569|*  (BLex3_Ascii など)を参照することができます。*(p+1) で次の位置の
 570|*  コードタイプを参照することができます。
 571|***************************************************************************/
 572|char*  BLex3_Engine_getSJisPtr( BLex3_Engine* m )
 573|{
 574|  char*  fp2;
 575|
 576|  ASSERT( m->sjis_buf != NULL );
 577|
 578|  fp2 = m->sjis_buf + ( m->fp - m->buf );
 579|
 580|  #if ! ERRORS_DEBUG_FALSE
 581|    ASSERT( *fp2 != BLex3_SJisUnknown );
 582|  #endif
 583|
 584|  return  fp2;
 585|}
 586|
 587| 
 588|/**************************************************************************
 589|*  22. <<< [BLex3_Engine_next] ファイルポインタを進める(バイト数指定) >>> 
 590|*【引数】
 591|*  ・BLex3_Engine*  m;  字句解析エンジン
 592|*  ・int  n;               進めるバイト数(負の数も可)
 593|*【補足】
 594|*・本関数を呼び出したら、前に BLex3_Engine_getFilePtr 関数から取得したファイル
 595|*  ポインタは使えなくなります。再び、BLex3_Engine_getFilePtr 関数を呼び出して、
 596|*  新しいファイルポインタを取得してください。
 597|***************************************************************************/
 598|void  BLex3_Engine_next( BLex3_Engine* m, int n )
 599|{
 600|  m->fp += n;
 601|  m->pos.sjis_type = BLex3_SJisUnknown;  /* BLex3_Engine_getFilePtr で本設定 */
 602|}
 603| 
 604|/**************************************************************************
 605|*  23. <<< [BLex3_Engine_nextBuf] 内部バッファの次の位置にファイルポインタを移動する >>> 
 606|*【引数】
 607|*  ・BLex3_Engine*  m;  字句解析エンジン
 608|***************************************************************************/
 609|void  BLex3_Engine_nextBuf( BLex3_Engine* m )
 610|{
 611|  m->fp = m->buf_over;
 612|}
 613| 
 614|/**************************************************************************
 615|*  24. <<< [BLex3_Engine_nextByPtr] ファイルポインタを進める(アドレス指定) >>> 
 616|*【引数】
 617|*  ・BLex3_Engine*  m;  字句解析エンジン
 618|*  ・char*  next_fp;       ファイルポインタ(→補足)
 619|*【補足】
 620|*・本関数は、BLex3_Engine_getFilePtr 関数で取得したポインタ fp を進めた
 621|*  アドレス next_fp = fp + n に m のファイルポインタを合わせます。
 622|*・next_fp は、BLex3_Engine_getFilePtr 関数から取得できる内部バッファの
 623|*  アドレスを指定します。内部バッファの外(前後)を指定しても、その位置に相当する
 624|*  ファイルアドレスに正しく設定します。
 625|***************************************************************************/
 626|void  BLex3_Engine_nextByPtr( BLex3_Engine* m, char* next_fp )
 627|{
 628|  m->fp = next_fp;
 629|  m->pos.sjis_type = BLex3_SJisUnknown;
 630|}
 631| 
 632|/**************************************************************************
 633|*  25. <<< [BLex3_Engine_getPos] ファイルポインタのある位置のファイルアドレスを返す >>> 
 634|*【引数】
 635|*  ・BLex3_Engine*  m;  字句解析エンジン
 636|*  ・BLex3_Pos*  pos;      (出力)ファイルアドレス
 637|*【補足】
 638|*・BLex3_Engine_getPos2 関数の fp 引数に、BLex3_Engine_getFilePtr 関数の返り値を
 639|*  そのまま指定したものと同じです。
 640|***************************************************************************/
 641|void  BLex3_Engine_getPos( BLex3_Engine* m, BLex3_Pos* pos )
 642|{
 643|  if ( m->fp - m->buf < 0 )
 644|    BLex3_Engine_getFilePtr( m, 0 );
 645|  pos->pos = m->pos.pos + (m->fp - m->buf);
 646|  if ( m->sjis_buf != NULL )
 647|    pos->sjis_type = *( m->sjis_buf + (m->fp - m->buf) );
 648|}
 649|
 650| 
 651|/**************************************************************************
 652|*  26. <<< [BLex3_Engine_getPos0] ファイルポインタのある位置のファイルアドレスを返す >>> 
 653|*【引数】
 654|*  ・BLex3_Engine*  m;  字句解析エンジン
 655|*  ・int  返り値;          ファイルアドレス
 656|*【補足】
 657|*・本関数の返り値では、BLex3_Engine_setPos 関数が使えませんが、
 658|*  BLex3_Pos::pos とファイルアドレスの大小比較ができます。
 659|***************************************************************************/
 660|int  BLex3_Engine_getPos0( BLex3_Engine* m )
 661|{
 662|  return  m->pos.pos + (m->fp - m->buf);
 663|}
 664|
 665| 
 666|/**************************************************************************
 667|*  27. <<< [BLex3_Engine_getPos2] ファイルアドレスを返す >>> 
 668|*【引数】
 669|*  ・BLex3_Engine*  m;  字句解析エンジン
 670|*  ・char*  fp;            ファイルポインタ(→補足)
 671|*  ・BLex3_Pos*  pos;      (出力)ファイルアドレス
 672|*【補足】
 673|*・fp は、BLex3_Engine_getFilePtr 関数から取得できる内部バッファの
 674|*  アドレスを指定します。
 675|*・fp の位置に対応するファイルアドレス(ファイルの先頭を0としたオフセット)
 676|*  を pos に格納します。取得したファイルアドレスは、BLex3_Engine_setPos 関数に使います。
 677|***************************************************************************/
 678|void  BLex3_Engine_getPos2( BLex3_Engine* m, char* fp, BLex3_Pos* pos )
 679|{
 680|  ASSERT( fp >= m->buf );
 681|
 682|  pos->pos = m->pos.pos + ( fp - m->buf );
 683|  if ( fp < m->buf_over ) {
 684|    pos->sjis_type = *( m->sjis_buf + (fp - m->buf) );
 685|  }
 686|
 687|  /* 内部バッファより後のアドレスを返すとき、sjis_type を求める */
 688|  else {
 689|    char*  p = m->sjis_buf + (m->buf_over - m->buf) - 1;
 690|    int  n;
 691|    int  c;
 692|
 693|    if ( *p == BLex3_SJisUnknown )  return;
 694|
 695|    /* 内部バッファの直後の文字について */
 696|    if ( *p == BLex3_SJisFirst ) {
 697|      if ( fp == m->buf_over ) {
 698|        pos->sjis_type = BLex3_SJisSecond;
 699|        return;
 700|      }
 701|      fseek( m->f, pos->pos + 1, SEEK_SET );
 702|      n = fp - m->buf_over - 1;
 703|    }
 704|    else {
 705|      fseek( m->f, pos->pos, SEEK_SET );
 706|      n = fp - m->buf_over;
 707|    }
 708|
 709|    /* 内部バッファの直後より後の文字について */
 710|    for(;;) {
 711|      c = fgetc( m->f );
 712|      if ( _ismbblead( c ) ) {
 713|        if ( n == 0 )
 714|          { pos->sjis_type = BLex3_SJisFirst;  return; }
 715|        else if ( n == 1 )
 716|          { pos->sjis_type = BLex3_SJisSecond;  return; }
 717|        fgetc( m->f );
 718|        n--;
 719|      }
 720|      else {
 721|        if ( n == 0 )
 722|          { pos->sjis_type = BLex3_Ascii;  return; }
 723|      }
 724|      n--;
 725|    }
 726|  }
 727|}
 728|
 729| 
 730|/**************************************************************************
 731|*  28. <<< [BLex3_Engine_getPos3] ファイルアドレスを返す >>> 
 732|*【引数】
 733|*  ・BLex3_Engine*  m;  字句解析エンジン
 734|*  ・int  n;               現在のファイルポインタの位置からの相対位置
 735|*  ・BLex3_Pos*  pos;      (出力)ファイルアドレス
 736|*【補足】
 737|*・相対位置が内部バッファの外でも構いません。
 738|***************************************************************************/
 739|void  BLex3_Engine_getPos3( BLex3_Engine* m, int n, BLex3_Pos* pos )
 740|{
 741|  ASSERT( n >= 0 && n < m->buf_over - m->buf );
 742|
 743|  if ( m->fp + n > m->buf_over ) {
 744|    BLex3_Pos  here;
 745|
 746|    Errors_notSupport();
 747|    BLex3_Engine_getPos( m, &here );
 748|    BLex3_Engine_next( m, n );
 749|    BLex3_Engine_getPos( m, pos );
 750|    BLex3_Engine_setPos( m, &here );  /* ファイルポインタがずれる */
 751|  }
 752|  else {
 753|    if ( m->fp + n == m->buf_over )
 754|      BLex3_Engine_getFilePtr( m, n + 1 );
 755|
 756|    pos->pos = m->pos.pos + ( m->fp - m->buf ) + n;
 757|    pos->sjis_type = *( m->sjis_buf + (m->fp - m->buf) + n );
 758|  }
 759|}
 760|
 761| 
 762|/**************************************************************************
 763|*  29. <<< [BLex3_Engine_getEndPos] ファイルの最後のファイルアドレスを返す >>> 
 764|*【引数】
 765|*  ・BLex3_Engine*  m;  字句解析エンジン
 766|*  ・BLex3_Pos*  pos;      (出力)最後のファイルアドレス
 767|***************************************************************************/
 768|void  BLex3_Engine_getEndPos( BLex3_Engine* m, BLex3_Pos* pos )
 769|{
 770|  fseek( m->f, 0, SEEK_END );
 771|  pos->pos = ftell( m->f );
 772|  pos->sjis_type = BLex3_SJisUnknown;
 773|}
 774|
 775| 
 776|/**************************************************************************
 777|*  30. <<< [BLex3_Engine_setPos] ファイルポインタを指定のファイルアドレスに移動する >>> 
 778|*【引数】
 779|*  ・BLex3_Engine*  m;  字句解析エンジン
 780|*  ・BLex3_Pos*  pos;      ファイルアドレス
 781|*【補足】
 782|*・pos は、BLex3_Engine_getPos 関数から取得したものを指定します。
 783|*・本関数を使って移動した位置のファイルの内容は、BLex3_Engine_getFilePtr 関数
 784|*  を使って取得したファイルポインタを使って参照します。
 785|***************************************************************************/
 786|void  BLex3_Engine_setPos( BLex3_Engine* m, BLex3_Pos* pos )
 787|{
 788|  ASSERT( pos->pos != BLex3_nullPos.pos );
 789|
 790|  m->fp = m->buf + ( pos->pos - m->pos.pos );
 791|  m->pos.sjis_type = pos->sjis_type;
 792|}
 793|
 794| 
 795|/**************************************************************************
 796|*  31. <<< [BLex3_Engine_setPos2] ファイルポインタを移動する(相対位置指定) >>> 
 797|*【引数】
 798|*  ・BLex3_Engine*  m;  字句解析エンジン
 799|*  ・BLex3_Pos*  pos;      ファイルアドレス
 800|*  ・int  n;               pos からの相対位置(0以上)
 801|***************************************************************************/
 802|void  BLex3_Engine_setPos2( BLex3_Engine* m, BLex3_Pos* pos, int n )
 803|{
 804|  bool  f = ( pos->pos < m->pos.pos );
 805|
 806|  BLex3_Engine_setPos( m, pos );
 807|  if ( f &&  m->sjis_buf != NULL )
 808|    BLex3_Engine_getFilePtr( m, 0 );
 809|  BLex3_Engine_next( m, n );
 810|}
 811|
 812| 
 813|/**************************************************************************
 814|*  32. <<< [BLex3_Engine_copy] 入力ファイルの一部をそのままファイルに出力する >>> 
 815|*【引数】
 816|*  ・BLex3_Engine*  m;  字句解析エンジン
 817|*  ・FILE*  out;           出力ファイル
 818|*  ・BLex3_Pos*  start;    出力を開始する入力ファイルのアドレス
 819|*  ・BLex3_Pos*  over;     最後の出力をする入力ファイルのアドレスの次
 820|***************************************************************************/
 821|#if 0
 822|void  BLex3_Engine_copy( BLex3_Engine* m, FILE* out,
 823|  BLex3_Pos* start, BLex3_Pos* over )
 824|{
 825|  char*  p = m->buf + ( start->pos - m->pos.pos );
 826|  int    overPos = m->pos.pos + ( m->buf_over - m->buf );
 827|  int    c;
 828|  char*  cp;
 829|
 830|  ASSERT( start->pos <= over->pos );
 831|
 832|  BLex3_Engine_setPos( m, start );
 833|  while ( overPos < over->pos ) {
 834|    fputs( p, out );
 835|    BLex3_Engine_nextBuf( m );
 836|    p = BLex3_Engine_getFilePtr( m, 0 );
 837|    if ( p == NULL )  return;
 838|    overPos = m->pos.pos + ( m->buf_over - m->buf );
 839|  }
 840|  cp = m->buf + ( over->pos - m->pos.pos );
 841|  c = *cp;
 842|  *cp = '\0';
 843|  fputs( p, out );
 844|  *cp = c;
 845|}
 846|#endif
 847|
 848| 
 849|/*---------------------------------------------------------------------*/
 850|/* 33. <<<◆(BLex3_EngineU) 字句解析エンジン・ユーティリティ >>> */ 
 851|/*---------------------------------------------------------------------*/
 852|
 853|void  BLex3_EngineU_writeHTML_sub( char* data, char* data_over, int* iLine,
 854|  FILE* out );
 855|void  BLex3_EngineU_getStr_sub( char* fp, char* fp_over,
 856|  char** ps, int* ps_size );
 857| 
 858|/**************************************************************************
 859|*  34. <<< [BLex3_EngineU_readWord] 指定の区切り文字が現れるまで読み込む >>> 
 860|*【引数】
 861|*  ・BLex3_EngineU*  m;  字句解析エンジン・ユーティリティ
 862|*  ・char*  s;              読込んだデータを格納する領域の先頭アドレス
 863|*  ・int  s_size;           s の領域のサイズ
 864|*  ・char*  terms;          区切り文字の並び
 865|*  ・bool  bDQ;             ダブルクォーテーションで囲むものを有効にするかどうか
 866|*【補足】
 867|*・現在のファイルポインタの位置(BLex3_Engine_getFilePtr で取得できるアドレス)
 868|*  から区切り文字(またはファイルの最後、または s_size)までを s に読み込みます。
 869|*・s の最後は、'\0'文字が格納されます。
 870|*・現在のファイルポインタの位置が " のとき、かつ bDQ が true のとき、
 871|*  terms に関係無く、"" で囲まれた部分を読み込みます。
 872|*・本関数を実行したら、現在のファイルポインタの位置が、区切り文字のある
 873|*  位置(または、ファイルの最後)に移動します。
 874|***************************************************************************/
 875|void  BLex3_EngineU_readWord( BLex3_EngineU* m,
 876|  char* s, int s_size, const char* terms, bool bDQ )
 877|{
 878|  char*  fp;
 879|  char*  p;
 880|  const char*  dq = "\"";
 881|  ArrX_Buf  s_buf;
 882|
 883|  ArrX_Buf_init( &s_buf, s, s_size );
 884|  ArrX_Buf_addStr( &s_buf, "" );
 885|
 886|  fp = BLex3_Engine_getFilePtr( &m->inherit_BLex3_Engine, 0 );
 887|  if ( bDQ && *fp == '\"' ) {
 888|    terms = dq;
 889|    BLex3_Engine_next( &m->inherit_BLex3_Engine, 1 );
 890|    fp = BLex3_Engine_getFilePtr( &m->inherit_BLex3_Engine, 0 );
 891|  }
 892|
 893|  while ( fp != NULL ) {
 894|
 895|    p = StrX_strchrs( fp, terms );
 896|    for (;;) {
 897|
 898|      /* 次のバッファへ: to next buffer */
 899|      if ( p == NULL ) {
 900|        ArrX_Buf_addMem( &s_buf, fp,
 901|          BLex3_Engine_getOverPtr( &m->inherit_BLex3_Engine ) - fp );
 902|        BLex3_Engine_nextBuf( &m->inherit_BLex3_Engine );
 903|        fp = BLex3_Engine_getFilePtr( &m->inherit_BLex3_Engine, 0 );
 904|        break;
 905|      }
 906|
 907|      /* "" で囲まれた文字列中に " が連続していたとき: case of "" in "" */
 908|      else if ( terms == dq && *p == '\"' && *(p + 1) == '\"' )
 909|        p = StrX_strchrs( p + 2, terms );
 910|
 911|      /* 区切り文字が見つかったとき: case of find term char */
 912|      else
 913|        goto  exit_while;
 914|    }
 915|  }
 916| exit_while:
 917|
 918|  ArrX_Buf_addMem( &s_buf, fp, p - fp );
 919|  ArrX_Buf_addChr( &s_buf, '\0' );
 920|  if ( fp != NULL ) {
 921|    if ( terms == dq )  p++;
 922|    BLex3_Engine_nextByPtr( &m->inherit_BLex3_Engine, p );
 923|  }
 924|}
 925|
 926| 
 927|/**************************************************************************
 928|*  35. <<< [BLex3_EngineU_skip] 指定の文字をスキップし続ける >>> 
 929|*【引数】
 930|*  ・BLex3_EngineU*  m;  字句解析エンジン・ユーティリティ
 931|*  ・char*  skipChars;      スキップする文字を並べた文字列
 932|*【補足】
 933|*・現在のファイルポインタの位置(BLex3_Engine_getFilePtr で取得できるアドレス)
 934|*  から skipChars に含まれる(半角)文字をスキップして、現在のファイルポインタの
 935|*  位置を進めます。
 936|*【例】
 937|*  BLex3_EngineU_skip( &eng, " \t\r\n" );  // 空白とタブと改行をスキップ
 938|***************************************************************************/
 939|void  BLex3_EngineU_skip( BLex3_EngineU* m, const char* skipChars )
 940|{
 941|  BLex3_Engine*  eng = &m->inherit_BLex3_Engine;
 942|  char*  fp;
 943|  char*  p;
 944|
 945|  for (;;) {
 946|    fp = BLex3_Engine_getFilePtr( eng, 0 );
 947|    if ( fp == NULL )  return;
 948|    p = StrX_strchrs_not( fp, skipChars );
 949|    if ( p != NULL )  break;
 950|    BLex3_Engine_nextBuf( eng );
 951|  }
 952|  BLex3_Engine_nextByPtr( eng, p );
 953|}
 954|
 955| 
 956|/**************************************************************************
 957|*  36. <<< [BLex3_EngineU_skipTo] 指定の文字までスキップし続ける >>> 
 958|*【引数】
 959|*  ・BLex3_EngineU*  m;  字句解析エンジン・ユーティリティ
 960|*  ・char*  terms;          スキップを止める文字を並べた文字列
 961|*  ・int  plus;             terms に含まれる文字のある位置からずらす量
 962|*【補足】
 963|*・現在のファイルポインタの位置(BLex3_Engine_getFilePtr で取得できるアドレス)
 964|*  から terms に含まれる(半角)文字までスキップして、現在のファイルポインタの
 965|*  位置を進めます。
 966|*・plus に +1 を指定すると、terms に含まれる文字の次の位置に、現在の
 967|*  ファイルポインタの位置を進めます。
 968|*【例】
 969|*  BLex3_EngineU_skipTo( &eng, "\n", 1 );  // 次の行までスキップする
 970|***************************************************************************/
 971|void  BLex3_EngineU_skipTo( BLex3_EngineU* m, const char* terms, int plus )
 972|{
 973|  BLex3_Engine*  eng = &m->inherit_BLex3_Engine;
 974|  char*  fp;
 975|  char*  fp2;
 976|  char*  p;
 977|
 978|  for (;;) {
 979|    fp = BLex3_Engine_getFilePtr( eng, 2 );
 980|    if ( fp == NULL )  return;
 981|    fp2 = BLex3_Engine_getSJisPtr( eng );
 982|    if ( *fp2 == BLex3_SJisSecond )  fp++;
 983|    p = StrX_strchrs2( fp, terms );
 984|    if ( p != NULL )  break;
 985|    BLex3_Engine_nextBuf( eng );
 986|  }
 987|  BLex3_Engine_nextByPtr( eng, p + plus );
 988|}
 989|
 990| 
 991|/**************************************************************************
 992|*  37. <<< [BLex3_EngineU_skipToStr] 指定の文字列までスキップし続ける >>> 
 993|*【引数】
 994|*  ・BLex3_EngineU*  m;  字句解析エンジン・ユーティリティ
 995|*  ・char*  term;           スキップを止める文字を並べた文字列
 996|*  ・int  plus;             term に含まれる文字のある位置からずらす量
 997|*  ・bool  bCase;           大文字小文字を区別するかどうか
 998|*【補足】
 999|*・現在のファイルポインタの位置(BLex3_Engine_getFilePtr で取得できるアドレス)
1000|*  から term に一致する位置までスキップして、現在のファイルポインタの位置を進めます。
1001|*・plus に +1 を指定すると、term に一致する先頭の位置の次の位置に、現在の
1002|*  ファイルポインタの位置を進めます。
1003|*【例】
1004|*  BLex3_EngineU_skipToStr( &eng, "end", 3, false );  // end の次までスキップする
1005|***************************************************************************/
1006|void  BLex3_EngineU_skipToStr( BLex3_EngineU* m, const char* term, int plus,
1007|  bool bCase )
1008|{
1009|  BLex3_Engine*  eng = &m->inherit_BLex3_Engine;
1010|  const int    term_len = strlen( term );
1011|  char*  fp;
1012|  char*  p;
1013|  int    hittingCount = 0;
1014|
1015|  for (;;) {
1016|    fp = BLex3_Engine_getFilePtr( eng, term_len );
1017|    p = StrX_stristr3( fp, term, bCase, &hittingCount );
1018|    if ( p != NULL )  break;
1019|    BLex3_Engine_nextBuf( eng );
1020|  }
1021|  BLex3_Engine_nextByPtr( eng, p + plus );
1022|}
1023|
1024| 
1025|/**************************************************************************
1026|*  38. <<< [BLex3_EngineU_skipTag] HTML のタグをスキップする >>> 
1027|*【引数】
1028|*  ・BLex3_EngineU*  m;  字句解析エンジン・ユーティリティ
1029|***************************************************************************/
1030|void  BLex3_EngineU_skipTag( BLex3_EngineU* m )
1031|{
1032|  char*  fp;
1033|  char*  fp_over;
1034|
1035|  fp = BLex3_Engine_getFilePtr( &m->inherit_BLex3_Engine, 4 );
1036|  fp_over = BLex3_Engine_getOverPtr( &m->inherit_BLex3_Engine );
1037|
1038|  ASSERT( *fp == '<' );
1039|
1040|  if ( strncmp( fp + 1, "!--", 3 ) == 0 ) {
1041|    BLex3_EngineU_skipToStr( m, "-->", +3, true );
1042|  }
1043|  else {
1044|    BLex3_EngineU_skipTo( m, ">", +1 );
1045|  }
1046|}
1047| 
1048|/**************************************************************************
1049|*  39. <<< [BLex3_EngineU_write] 指定の範囲をファイルに出力する >>> 
1050|*【引数】
1051|*  ・BLex3_EngineU*  m;  字句解析エンジン・ユーティリティ
1052|*  ・BLex3_Pos*  firstPos;  出力開始位置
1053|*  ・BLex3_Pos*  overPos;   出力終了の次の位置
1054|*  ・FILE*  out;            出力ファイル
1055|*【補足】
1056|*・本関数を呼び出したら、BLex3_Engine_setPos 関数と BLex3_Engine_getFilePtr
1057|*  関数を呼び出して、ファイルポインタの位置を再取得してください。
1058|***************************************************************************/
1059|void  BLex3_EngineU_write( BLex3_EngineU* m, BLex3_Pos* firstPos,
1060|  BLex3_Pos* overPos, FILE* out )
1061|{
1062|  BLex3_Engine*  eng = &m->inherit_BLex3_Engine;
1063|  char*  fp;
1064|  char*  fp_over;
1065|  BLex3_Pos  pos;
1066|
1067|  ASSERT( firstPos->pos <= overPos->pos );
1068|
1069|  BLex3_Engine_setPos( eng, firstPos );
1070|  for (;;) {
1071|    fp = BLex3_Engine_getFilePtr( eng, 0 );
1072|    fp_over = BLex3_Engine_getOverPtr( eng );
1073|    BLex3_Engine_getPos2( eng, fp_over, &pos );
1074|    if ( overPos->pos > pos.pos ) {
1075|      fwrite( fp, fp_over - fp, 1, out );
1076|      BLex3_Engine_nextBuf( eng );
1077|    }
1078|    else {
1079|      fp_over = BLex3_Engine_getFilePtrByPos( eng, overPos->pos );
1080|      fwrite( fp, fp_over - fp, 1, out );
1081|      return;
1082|    }
1083|  }
1084|}
1085|
1086| 
1087|/**************************************************************************
1088|*  40. <<< [BLex3_EngineU_writeHTML] 指定の範囲のテキストを HTML ファイルに出力する >>> 
1089|*【引数】
1090|*  ・BLex3_EngineU*  m;  字句解析エンジン・ユーティリティ
1091|*  ・BLex3_Pos*  firstPos;  出力開始位置
1092|*  ・BLex3_Pos*  overPos;   出力終了の次の位置
1093|*  ・int  iLine;            出力開始位置の行番号(-1で行番号を出力しない)
1094|*  ・FILE*  out;            出力ファイル
1095|*【補足】
1096|*・<, >, & を &lt;, &gt;, &amp; に変換します。
1097|*・行番号を出力します。
1098|*・特定のタグをそのまま出力するときは、HtmlPars を使って特定のタグを判定し、
1099|*  BLex3_EngineU_write 関数でファイルに出力します。
1100|***************************************************************************/
1101|void  BLex3_EngineU_writeHTML( BLex3_EngineU* m, BLex3_Pos* firstPos,
1102|  BLex3_Pos* overPos, int iLine, FILE* out )
1103|{
1104|  BLex3_Engine*  eng = &m->inherit_BLex3_Engine;
1105|  char*  fp;
1106|  char*  fp_over;
1107|  BLex3_Pos  pos;
1108|
1109|//COUNT(12469)
1110|//BK
1111|
1112|  ASSERT( firstPos->pos <= overPos->pos );
1113|  if (  firstPos->pos == overPos->pos )  return;
1114|
1115|  BLex3_Engine_setPos( eng, firstPos );
1116|  for (;;) {
1117|    fp = BLex3_Engine_getFilePtr( eng, 0 );
1118|    fp_over = BLex3_Engine_getOverPtr( eng );
1119|    BLex3_Engine_getPos2( eng, fp_over, &pos );
1120|    if ( overPos->pos > pos.pos ) {
1121|      BLex3_EngineU_writeHTML_sub( fp, fp_over, &iLine, out );
1122|      BLex3_Engine_nextBuf( eng );
1123|    }
1124|    else {
1125|      fp_over = BLex3_Engine_getFilePtrByPos( eng, overPos->pos );
1126|      BLex3_EngineU_writeHTML_sub( fp, fp_over, &iLine, out );
1127|      return;
1128|    }
1129|  }
1130|}
1131|
1132| 
1133|/**************************************************************************
1134|*  41. <<< [BLex3_EngineU_writeHTML_sub] テキストデータを HTML ファイルに出力する >>> 
1135|*【引数】
1136|*  ・char*  data;       出力するテキストファイルの内容の先頭アドレス
1137|*  ・char*  data_over;  同、末尾の次のアドレス
1138|*  ・int*   piLine;     (入力)data の行番号、(出力)data_over の行番号
1139|*  ・FILE*  out;        出力ファイル
1140|*【補足】
1141|*・BLex3_EngineU_writeHTML のサブルーチンです。
1142|***************************************************************************/
1143|void  BLex3_EngineU_writeHTML_sub( char* data, char* data_over, int* piLine,
1144|  FILE* out )
1145|{
1146|  char*  p;
1147|  char*  tp = data;  /* そのまま出力する先頭 */
1148|  int  iLine = *piLine;
1149|
1150|  for ( p = data; p < data_over; p++ ) {
1151|    switch ( *p ) {
1152|      case '<':
1153|        fwrite( tp, p - tp, 1, out );  tp = p + 1;
1154|        fputs( "&lt;", out );
1155|        break;
1156|      case '>':
1157|        fwrite( tp, p - tp, 1, out );  tp = p + 1;
1158|        fputs( "&gt;", out );
1159|        break;
1160|      case '&':
1161|        fwrite( tp, p - tp, 1, out );  tp = p + 1;
1162|        fputs( "&amp;", out );
1163|        break;
1164|      case '\n':
1165|        if ( iLine != -1 ) {
1166|          fwrite( tp, p - tp, 1, out );  tp = p + 1;
1167|          iLine ++;
1168|          fprintf( out, "\n%4d|", iLine );
1169|        }
1170|        break;
1171|    }
1172|  }
1173|  fwrite( tp, p - tp, 1, out );
1174|  *piLine = iLine;
1175|}
1176| 
1177|/**************************************************************************
1178|*  42. <<< [BLex3_EngineU_writeNoTag] HTML タグを除いた HTML をテキストファイルに出力する >>> 
1179|*【引数】
1180|*  ・BLex3_EngineU*  m;  字句解析エンジン・ユーティリティ
1181|*  ・BLex3_Pos*  firstPos;  出力開始位置
1182|*  ・BLex3_Pos*  overPos;   出力終了の次の位置
1183|*  ・FILE*  out;            出力ファイル
1184|*【補足】
1185|*・firstPos から overPos までの HTML テキストから <, > で囲まれた HTML タグを
1186|*  カットして、テキストファイルに出力します。
1187|*・firstPos から overPos までの先頭または末尾の空白、タブ、改行もカットします。
1188|***************************************************************************/
1189|void  BLex3_EngineU_writeNoTag( BLex3_EngineU* m, BLex3_Pos* firstPos,
1190|  BLex3_Pos* overPos, FILE* out )
1191|{
1192|  BLex3_Engine*  eng = &m->inherit_BLex3_Engine;
1193|  char*  fp;
1194|  char*  fp_over;
1195|  char*  fp_writeOver;
1196|  bool   bSpc;   /* 空白、タブ、改行、HTML タグが続いているかどうか */
1197|  BLex3_Pos  topPos;
1198|  BLex3_Pos  pos;
1199|  int   c;
1200|
1201|  ASSERT( firstPos->pos <= overPos->pos );
1202|
1203|  /* 最初の空白や HTML タグをスキップする */
1204|  BLex3_Engine_setPos( eng, firstPos );
1205|  fp = BLex3_Engine_getFilePtr( eng, 0 );
1206|  fp_over = BLex3_Engine_getOverPtr( eng );
1207|
1208|  for (;;) {
1209|    c = *fp;
1210|    if ( c == ' ' || c == '\t' || c == '\r' || c == '\n' ) {
1211|      fp++;
1212|      if ( fp == fp_over ) {
1213|        BLex3_Engine_nextBuf( eng );
1214|        fp = BLex3_Engine_getFilePtr( eng, 0 );
1215|        fp_over = BLex3_Engine_getOverPtr( eng );
1216|      }
1217|    }
1218|    else if ( c == '<' ) {
1219|      BLex3_Engine_nextByPtr( eng, fp );
1220|      BLex3_EngineU_skipTag( m );
1221|      fp = BLex3_Engine_getFilePtr( eng, 0 );
1222|      fp_over = BLex3_Engine_getOverPtr( eng );
1223|    }
1224|    else
1225|      break;
1226|  }
1227|  fp_writeOver = BLex3_Engine_getFilePtrByPos2( eng, overPos->pos );
1228|  if ( fp_writeOver < fp_over )  fp_over = fp_writeOver;
1229|
1230|  /* 末尾の空白や HTML タグの前までファイルに出力する */
1231|  bSpc = false;
1232|  BLex3_Engine_getPos2( eng, fp, &topPos );
1233|
1234|  for (;;) {
1235|    c = *fp;
1236|    if ( c == ' ' || c == '\t' || c == '\r' || c == '\n' || c == '<' ) {
1237|
1238|      /* 空白などが始まったら、それまでを出力する */
1239|      if ( ! bSpc ) {
1240|        BLex3_Engine_getPos2( eng, fp, &pos );
1241|        BLex3_EngineU_write( m, &topPos, &pos, out );
1242|
1243|        BLex3_Engine_setPos( eng, &pos );
1244|        fp = BLex3_Engine_getFilePtr( eng, 0 );
1245|        fp_over = BLex3_Engine_getOverPtr( eng );
1246|        fp_writeOver = BLex3_Engine_getFilePtrByPos2( eng, overPos->pos );
1247|        if ( fp_writeOver < fp_over )  fp_over = fp_writeOver;
1248|
1249|        BLex3_Pos_copy( &topPos, &pos );
1250|        bSpc = true;
1251|      }
1252|
1253|      /* タグをスキップする */
1254|      if ( c == '<' ) {
1255|        BLex3_Engine_nextByPtr( eng, fp );
1256|        BLex3_EngineU_skipTag( m );
1257|        BLex3_Engine_getPos( eng, &topPos );
1258|        fp = BLex3_Engine_getFilePtr( eng, 0 );
1259|        fp_over = BLex3_Engine_getOverPtr( eng );
1260|        fp_writeOver = BLex3_Engine_getFilePtrByPos2( eng, overPos->pos );
1261|        if ( fp_writeOver < fp_over )  fp_over = fp_writeOver;
1262|      }
1263|      else
1264|        fp++;
1265|    }
1266|    else {
1267|      bSpc = false;
1268|      fp++;
1269|    }
1270|
1271|    /* fp が内部バッファを超えたら更新する */
1272|    if ( fp >= fp_over ) {
1273|      if ( fp >= fp_writeOver ) {
1274|        break;
1275|      }
1276|      BLex3_Engine_nextBuf( eng );
1277|      fp = BLex3_Engine_getFilePtr( eng, 0 );
1278|      fp_over = BLex3_Engine_getOverPtr( eng );
1279|      fp_writeOver = BLex3_Engine_getFilePtrByPos2( eng, overPos->pos );
1280|      if ( fp_writeOver < fp_over )  fp_over = fp_writeOver;
1281|    }
1282|  }
1283|
1284|  /* 最後が空白でなかったら、最後まで出力する */
1285|  if ( ! bSpc ) {
1286|    BLex3_EngineU_write( m, &topPos, overPos, out );
1287|  }
1288|}
1289|
1290| 
1291|/**************************************************************************
1292|*  43. <<< [BLex3_EngineU_getStr] 指定の範囲を文字列として取得する >>> 
1293|*【引数】
1294|*  ・BLex3_EngineU*  m;  字句解析エンジン・ユーティリティ
1295|*  ・BLex3_Pos*  firstPos;  出力開始位置
1296|*  ・BLex3_Pos*  overPos;   出力終了の次の位置
1297|*  ・char*  s;              文字列を格納する領域の先頭アドレス
1298|*  ・int  s_size;           s のサイズ
1299|***************************************************************************/
1300|void  BLex3_EngineU_getStr( BLex3_EngineU* m, BLex3_Pos* firstPos,
1301|  BLex3_Pos* overPos, char* s, int s_size )
1302|{
1303|  BLex3_Engine*  eng = &m->inherit_BLex3_Engine;
1304|  char*  fp;
1305|  char*  fp_over;
1306|  BLex3_Pos  pos;
1307|
1308|  ASSERT( firstPos->pos <= overPos->pos );
1309|
1310|  BLex3_Engine_setPos( eng, firstPos );
1311|  for (;;) {
1312|    fp = BLex3_Engine_getFilePtr( eng, 0 );
1313|    fp_over = BLex3_Engine_getOverPtr( eng );
1314|    BLex3_Engine_getPos2( eng, fp_over, &pos );
1315|    if ( overPos->pos > pos.pos ) {
1316|      BLex3_EngineU_getStr_sub( fp, fp_over, &s, &s_size );
1317|      if ( s_size <= 0 )  return;
1318|      BLex3_Engine_nextBuf( eng );
1319|    }
1320|    else {
1321|      fp_over = BLex3_Engine_getFilePtrByPos( eng, overPos->pos );
1322|      BLex3_EngineU_getStr_sub( fp, fp_over, &s, &s_size );
1323|      return;
1324|    }
1325|  }
1326|}
1327|
1328| 
1329|/**************************************************************************
1330|*  44. <<< [BLex3_EngineU_getStr_sub] テキストデータを文字列として取得する >>> 
1331|*【引数】
1332|*  ・char*  fp;       出力するテキストファイルの内容の先頭アドレス
1333|*  ・char*  fp_over;  同、末尾の次のアドレス
1334|*  ・char*  ps;       (入力)取得領域のアドレス、(出力)次の取得アドレス
1335|*  ・int*   ps_size;  (入力)取得領域のサイズ、(出力)残りのサイズ
1336|*【補足】
1337|*・BLex3_EngineU_getStr のサブルーチンです。
1338|***************************************************************************/
1339|void  BLex3_EngineU_getStr_sub( char* fp, char* fp_over,
1340|  char** ps, int* ps_size )
1341|{
1342|  char*  s = *ps;
1343|  int    s_size_1 = *ps_size - 1;
1344|  int    f_size = fp_over - fp;
1345|
1346|  if ( f_size < s_size_1 ) {
1347|    memcpy( s, fp, f_size );
1348|    s[f_size] = '\0';
1349|    *ps = s + f_size;
1350|    (*ps_size) -= f_size;
1351|  }
1352|  else {
1353|    memcpy( s, fp, s_size_1 );
1354|    s[s_size_1] = '\0';
1355|    *ps = s + s_size_1;
1356|    (*ps_size) -= s_size_1;
1357|  }
1358|}
1359| 
1360|/*---------------------------------------------------------------------*/
1361|/* 45. <<<◆(BLex3_Parser) パーサ >>> */ 
1362|/*---------------------------------------------------------------------*/
1363|
1364| 
1365|/***********************************************************************
1366|*  46. <<< BLex3_Parser インターフェイス・関数定義 >>> 
1367|************************************************************************/
1368|#ifndef  NDEBUG
1369|INF_FUNC_0( BLex3_Parser, finish, void, BLex3_Parser_finish, BLex3_Parser, t );
1370|INF_FUNC_1( BLex3_Parser, linkEngine, void, BLex3_Parser_setEngine, BLex3_Parser, BLex3_Engine*, t,a );
1371|INF_FUNC_0( BLex3_Parser, parse, void, BLex3_Parser_parse, BLex3_Parser, t );
1372|INF_FUNC_R0( BLex3_Parser, getTokenType, int, BLex3_Parser_getTokenType, BLex3_Parser, t );
1373|INF_FUNC_1( BLex3_Parser, getNextParsePos, void, BLex3_Parser_getNextParsePos, BLex3_Parser, BLex3_Pos*, t,a );
1374|INF_FUNC_0( BLex3_Parser, printLastMsg, void, BLex3_Parser_printLastMsg, BLex3_Parser, t );
1375|#endif
1376|
1377| 
1378|