2b68cb81ae
Files correlati : ve0.exe Ricompilazione Demo : [ ] Commento : form.cpp Aggiunto supporto per custom/bitamp realtion.cpp Semplici sostituzioni di cose ripetute n volte con una singola variabile scanner.cpp Aggiunti apici in segnalazione di errore strings.cpp Corretta lettura di una stringa da file ad EOF tree.cpp Corretto disegno linee in presenza di header (Elaborazioni differite) git-svn-id: svn://10.65.10.50/trunk@11226 c028cbd2-c16b-5b4b-a496-9718f37d4682
156 lines
2.7 KiB
C++
Executable File
156 lines
2.7 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)
|
|
: _pushed(FALSE), _line(0),
|
|
_token(128), _key(2), _tmp(1024*8)
|
|
{
|
|
open(filename, ios::in | ios::nocreate, filebuf::sh_read);
|
|
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;
|
|
}
|