campo-sirio/include/scanner.cpp

170 lines
3.1 KiB
C++
Executable File

#include <xvt.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)
{
open(filename, ios::in);
if (fail())
{
DIRECTORY dir; xvt_fsys_get_dir(&dir);
TFilename curdir; xvt_fsys_convert_dir_to_str(&dir, curdir.get_buffer(), curdir.size());
TString msg;
msg << "Impossibile leggere il file '" << filename << "'\n"
<< "Directory corrente '" << curdir << "'\n";
if (xvt_fsys_file_exists(filename))
msg << "Il file esite ma NON è leggibile!";
else
msg << "Il file NON esite!";
fatal_box(msg);
}
}
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)
{
TString256 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;
}