143 lines
		
	
	
		
			2.4 KiB
		
	
	
	
		
			C++
		
	
	
		
			Executable File
		
	
	
	
	
			
		
		
	
	
			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;
 | |
| }
 |