160 lines
		
	
	
		
			2.8 KiB
		
	
	
	
		
			C++
		
	
	
		
			Executable File
		
	
	
	
	
			
		
		
	
	
			160 lines
		
	
	
		
			2.8 KiB
		
	
	
	
		
			C++
		
	
	
		
			Executable File
		
	
	
	
	
#include <ctype.h>
 | 
						|
#include <stdlib.h>
 | 
						|
 | 
						|
#include <scanner.h>
 | 
						|
 | 
						|
inline bool string_start(char c)
 | 
						|
{ return c == '"' || c == '\'' || c == '{'; }
 | 
						|
 | 
						|
inline char match(char c)
 | 
						|
{ return (c == '{') ? '}' : c; }
 | 
						|
 | 
						|
TScanner::TScanner(const char* filename)
 | 
						|
: _token(128), _key(2),
 | 
						|
  _tmp(1024*8), _pushed(FALSE), _line(0)
 | 
						|
{         
 | 
						|
#ifdef WIN32
 | 
						|
  open(filename, ios::in | ios::nocreate, filebuf::sh_read);
 | 
						|
#else
 | 
						|
  open(filename, ios::in);
 | 
						|
#endif
 | 
						|
  if (fail()) 
 | 
						|
    fatal_box("Impossibile leggere il file '%s'", filename);
 | 
						|
}
 | 
						|
 | 
						|
TScanner::~TScanner()
 | 
						|
{
 | 
						|
}
 | 
						|
 | 
						|
const TString& TScanner::pop()
 | 
						|
{
 | 
						|
  if (!_pushed) do
 | 
						|
  {
 | 
						|
    _token.read_from((ifstream&) *this);
 | 
						|
    if (_token[0] == '/' && _token[1] == '/')
 | 
						|
    {
 | 
						|
      line();
 | 
						|
      _token.cut(0);
 | 
						|
    }
 | 
						|
  } while (_token.empty() && good() && !eof());
 | 
						|
 | 
						|
  _pushed = FALSE;
 | 
						|
  _token.upper();
 | 
						|
  _key = _token.left(2);
 | 
						|
 | 
						|
  return _token;
 | 
						|
}
 | 
						|
 | 
						|
// @doc EXTERNAL
 | 
						|
 | 
						|
// @mfunc Ritorna la linea letta dal file
 | 
						|
//
 | 
						|
// @rdesc Ritorna una stringa contenente la linea letta dal file
 | 
						|
TString& TScanner::line(
 | 
						|
  char eol)  //@parm Carattere fino al quale leggere la riga (default EOL)
 | 
						|
{
 | 
						|
  do
 | 
						|
  {
 | 
						|
    if (!_pushed) _token.cut(0);
 | 
						|
    getline(_tmp.get_buffer(), _tmp.size(), eol);
 | 
						|
    _line++;
 | 
						|
    _token <<  _tmp;
 | 
						|
    _token.trim();
 | 
						|
  } while (_token.empty() && good() && !eof());
 | 
						|
 | 
						|
  _pushed = FALSE;
 | 
						|
 | 
						|
  return _token;
 | 
						|
}
 | 
						|
 | 
						|
const TString& TScanner::string()
 | 
						|
{
 | 
						|
  if (!_pushed)
 | 
						|
  {
 | 
						|
    char c;
 | 
						|
    while (isspace(c = get()));
 | 
						|
    if (string_start(c))
 | 
						|
    {
 | 
						|
      getline(_tmp.get_buffer(), _tmp.size(), match(c));
 | 
						|
      _token = _tmp;
 | 
						|
    }
 | 
						|
    else
 | 
						|
    {
 | 
						|
      error_box("Stringa non trovata: riga ignorata");
 | 
						|
      _token.cut(0);
 | 
						|
    }
 | 
						|
  }
 | 
						|
 | 
						|
  _pushed = FALSE;
 | 
						|
  return _token;
 | 
						|
}
 | 
						|
 | 
						|
void TScanner::rectangle(short& left, short& top, short& right, short& bottom)
 | 
						|
{
 | 
						|
  left = integer();
 | 
						|
  top = integer();
 | 
						|
  right  = integer();
 | 
						|
  bottom = integer();
 | 
						|
}
 | 
						|
 | 
						|
int TScanner::integer()
 | 
						|
{
 | 
						|
  int i = atoi(pop());
 | 
						|
  if (i == 0 && !isdigit(_token[0])) push();
 | 
						|
  return i;
 | 
						|
}
 | 
						|
 | 
						|
double TScanner::number()
 | 
						|
{
 | 
						|
  double d = atof(pop());
 | 
						|
  if (d == 0.0 && !isdigit(_token[0])) push();
 | 
						|
  return d;
 | 
						|
}
 | 
						|
 | 
						|
 | 
						|
const TString& TScanner::operand()
 | 
						|
{
 | 
						|
  if (!_pushed)
 | 
						|
  {
 | 
						|
    char c;
 | 
						|
    while (isspace(c = get()));
 | 
						|
    putback(c);
 | 
						|
    if (string_start(c))
 | 
						|
      return string();
 | 
						|
    else
 | 
						|
      return pop();
 | 
						|
  }
 | 
						|
 | 
						|
  _pushed = FALSE;
 | 
						|
  return _token;
 | 
						|
}
 | 
						|
 | 
						|
void TScanner::push(const char* s)
 | 
						|
{
 | 
						|
  CHECK(!_pushed, "You are pushing back two values to the parser");
 | 
						|
 | 
						|
  if (s != NULL) _token = s;
 | 
						|
  _pushed = TRUE;
 | 
						|
}
 | 
						|
 | 
						|
// Certified 100%
 | 
						|
// @doc EXTERNAL
 | 
						|
// @mfunc Va al paragrafo <p name>
 | 
						|
// @rdesc Ritorna TRUE se il paragrafo esiste
 | 
						|
bool TScanner::paragraph(const char* name)
 | 
						|
{
 | 
						|
  TString p = name;
 | 
						|
  if (p[0] != '[')
 | 
						|
  {
 | 
						|
    p.insert("[", 0);
 | 
						|
    p << ']';
 | 
						|
  }  
 | 
						|
 | 
						|
  clear();// resetta eof
 | 
						|
  seekg(0L);
 | 
						|
  while (line().not_empty())
 | 
						|
    if (token() == p) return TRUE;
 | 
						|
 | 
						|
  return FALSE;
 | 
						|
}
 |