www.pudn.com > 12cocorc.zip > CR_SCAN.CPP


//********************************************************** 
//   CR_SCAN.CPP 
//   Coco/R C++ Support Library. 
//   Author: Frankie Arzu  
// 
//   Jun 12, 1996  Version 1.06 
//      Many fixes and suggestions thanks to 
//      Pat Terry  
//   Mar 13, 1998  Version 1.08 
//      Support for MS VC++ 5.0 
//   May 05, 1999  Version 1.12 
//      Added support to get String with a long pos. 
//********************************************************** 
 
#include "cr_scan.hpp" 
 
#if __MSDOS__ || MSDOS || WIN32 
#  include  
#else 
#  include  
#endif 
 
#ifdef NEXTSTEP   // NextStep 
#  include  
#  include  
#  include  
#  define L_SET     0  // set the seek pointer 
#  define L_INCR    1  // increment the seek pointer 
#  define L_XTND    2  // extend the file size 
#endif 
 
#include  
#include  
 
CRScanner::CRScanner(int ignoreCase) 
{ 
  Buffer = NULL; IgnoreCase = ignoreCase; 
} 
 
CRScanner::CRScanner(int SrcFile, int ignoreCase) 
{ 
  Buffer = NULL; 
  ReadFile(SrcFile); Reset(); IgnoreCase = ignoreCase; 
} 
 
CRScanner::~CRScanner() 
{ 
  if (Buffer) delete Buffer; 
} 
 
void CRScanner::Reset() 
{ 
  CurrLine = 1; LineStart = 0; BuffPos = -1; CurrCol = 0; 
  ComEols = 0; 
  NextSym.Init(); 
  NextCh(); 
} 
 
void CRScanner::ReadFile(int SrcFile) 
{ 
  long len; 
  int  n; 
 
  InputLen = len = lseek(SrcFile, 0L, SEEK_END); 
  (void) lseek(SrcFile, 0L, SEEK_SET); 
 
  Buffer = new unsigned char[len+1]; 
  n = read(SrcFile, (void *) Buffer, len); 
  Buffer[n] = EOF_CHAR; 
} 
 
int CRScanner::EqualStr(char *s) 
{ 
  long pos; char c; 
  if (NextSym.Len != strlen(s)) return 0; 
  pos = NextSym.Pos; 
  while (*s) { 
    c = CurrentCh(pos); pos++; 
    if (IgnoreCase) c = Upcase(c); 
    if (c != *s++) return 0; 
  } 
  return 1; 
} 
 
void CRScanner::NextCh() 
{ 
  BuffPos++; 
  Ch = CurrentCh(BuffPos); 
  if (IgnoreCase) Ch = Upcase(Ch); 
  if (Ch == TAB_CHAR) CurrCol += TAB_SIZE - (CurrCol % TAB_SIZE); 
  else if (Ch == LF_CHAR) { 
    CurrLine++; CurrCol = 0; 
    LineStart = BuffPos + 1; 
  } 
  CurrCol++; 
}; 
 
void CRScanner::GetString(long Pos, char *Buffer, int Max) 
{ 
  while (Max--) { *Buffer++ = CurrentCh(Pos); Pos++; } 
  *Buffer = '\0'; 
} 
 
void CRScanner::GetString(AbsToken *Sym, char *Buffer, int Max) 
{ 
  int Len = (Sym->Len < Max)? Sym->Len : Max; 
  GetString(Sym->Pos, Buffer, Len); 
} 
 
void CRScanner::GetName(AbsToken *Sym, char *Buffer, int Max) 
{ 
  int  Len = Sym->Len; 
  long Pos = Sym->Pos; 
 
  while (Len-- && Max--) { 
    *Buffer = CurrentCh(Pos); Pos++; 
    if (IgnoreCase) *Buffer = Upcase(*Buffer); 
    Buffer++; 
  } 
  *Buffer = '\0'; 
} 
 
long CRScanner::GetLine(long Pos, char *Line, int Max) 
{ 
  int  Col = 1, i; 
  char ch = CurrentCh(Pos); 
  Pos++; 
  while (ch && ch != LF_CHAR && ch != EOF_CHAR) { 
    if (ch == TAB_CHAR) { 
      i = TAB_SIZE - (Col % TAB_SIZE) + 1; 
      while (i-- && Max > 0) { *Line++ = ' '; Col++; Max--; } 
    } 
    else if (ch != CR_CHAR && Max > 0) { *Line++ = ch; Col++; Max--; } 
    ch = CurrentCh(Pos); Pos++; 
  } 
  *Line = 0; 
  if (ch != EOF_CHAR) return Pos; 
  return -1; 
} 
 
CRDosScanner::CRDosScanner(int ignoreCase) 
{ 
  BufferVec[0] = NULL; 
  IgnoreCase = ignoreCase; 
} 
 
CRDosScanner::CRDosScanner(int SrcFile, int ignoreCase) 
{ 
  ReadFile(SrcFile); Reset(); IgnoreCase = ignoreCase; 
} 
 
CRDosScanner::~CRDosScanner() 
{ 
  for (int i = 0; BufferVec[i]; i++) delete BufferVec[i]; 
} 
 
void CRDosScanner::ReadFile(int SrcFile) 
{ 
  long len; 
  int i = 0, n; 
 
  InputLen = len = lseek(SrcFile, 0L, SEEK_END); 
  (void) lseek(SrcFile, 0L, SEEK_SET); 
 
  while (len > BLKSIZE) { 
    BufferVec[i] = new unsigned char[BLKSIZE]; 
    n=read(SrcFile, (void *) BufferVec[i], BLKSIZE); 
    len -= n; 
    i++; 
  } 
  BufferVec[i] = new unsigned char[len + 1]; 
  n = read(SrcFile, (void *) BufferVec[i], (unsigned) len); 
  (BufferVec[i])[n] = EOF_CHAR; 
  BufferVec[i+1] = NULL; 
}