campo-sirio/include/scanner.cpp

143 lines
2.4 KiB
C++
Executable File

#include <ctype.h>
#include <stdlib.h>
#include <utility.h>
#include <scanner.h>
HIDDEN const char* strlwr (const char* str)
{
for (char* s = __tmp_string; *str; s++, str++) *s = tolower(*str);
*s = '\0';
return __tmp_string;
}
inline bool string_start(char c)
{ return c == '"' || c == '\'' || c == '{' || c == '\''; }
inline char match(char c)
{ return (c == '{') ? '}' : c; }
TScanner::TScanner(const char* filename)
: ifstream(strlwr(filename)), _token(128), _key(2), _pushed(FALSE), _line(0)
{
if (bad()) fatal_box("Impossibile aprire %s", filename);
}
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());
_pushed = FALSE;
_token.upper();
_key = _token.left(2);
return _token;
}
TString& TScanner::line(char eol)
{
do
{
if (!_pushed) _token = "";
getline(__tmp_string, sizeof(__tmp_string), eol);
_line++;
_token << __tmp_string;
_token.trim();
} while (_token.empty() && good());
_pushed = FALSE;
return _token;
}
const TString& TScanner::string()
{
if (!_pushed)
{
char c;
while (isspace(c = get()));
if (string_start(c))
{
getline(__tmp_string, sizeof(__tmp_string), match(c));
_token = __tmp_string;
}
else
{
error_box("Stringa non trovata: riga ignorata");
_token.cut(0);
}
}
_pushed = FALSE;
return _token;
}
void TScanner::rectangle(RCT& rect)
{
rect.left = integer();
rect.top = integer();
rect.right = integer();
rect.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;
}
bool TScanner::paragraph(const char* name)
{
TString80 p;
p << '[' << name << ']';
seekg(0L);
while (line().not_empty())
if (token() == p) return TRUE;
return FALSE;
}