Main Page   Namespace List   Class Hierarchy   Compound List   File List   Compound Members   File Members  

component_tokenizer.cpp

Go to the documentation of this file.
00001 /*
00002         ClanGUI, copyrights by various people. Have a look in the CREDITS file.
00003         
00004         This sourcecode is distributed using the Library GNU Public Licence,
00005         version 2 or (at your option) any later version. Please read LICENSE
00006         for details.
00007 */
00008 
00009 #include "precomp.h"
00010 #include "API/Core/System/clanstring.h"
00011 #include "API/Core/System/error.h"
00012 #include "component_tokenizer.h"
00013 
00014 CL_ComponentTokenizer::CL_ComponentTokenizer(const std::string &_data, const std::string &_filename)
00015 {
00016         filename = _filename;
00017         string_data = _data;
00018         data = (char *) string_data.c_str();
00019         total_size = string_data.size();
00020 
00021         peek_pos = 0;
00022         last_line = 0;
00023         in_remark = false;
00024         tokenize();
00025 }
00026 
00027 CL_ComponentTokenizer::~CL_ComponentTokenizer()
00028 {
00029 }
00030 
00031 bool CL_ComponentTokenizer::is_operator(char c)
00032 {
00033         return
00034                 c == ',' ||
00035                 c == '=' ||
00036                 c == '(' ||
00037                 c == ')' ||
00038                 c == ';' ||
00039                 c == '{' ||
00040                 c == '}' ||
00041                 c == '<' ||
00042                 c == '+' ||
00043                 c == '-' ||
00044                 c == '*' ||
00045                 c == '/' ||
00046                 c == '>';
00047 }
00048 
00049 bool CL_ComponentTokenizer::is_space(char c)
00050 {
00051         return
00052                 c == ' ' ||
00053                 c == '\t' ||
00054                 c == 13 ||
00055                 c == 10;
00056 }
00057 
00058 bool CL_ComponentTokenizer::is_remark(char c, int position)
00059 {
00060         if (in_remark)
00061         {
00062                 if (c == '\n') 
00063                 {       
00064                         in_remark = false;
00065                 }
00066                 return true;
00067         }
00068         else
00069         {
00070                 if (c == '/')
00071                 {
00072                         if (
00073                                 position+1 < total_size &&
00074                                 data[position+1] == '/')
00075                         {
00076                                 in_remark = true;
00077                                 return true;
00078                         }
00079                 }
00080                 else if (c == '#')
00081                 {
00082                         in_remark = true;
00083                         return true;
00084                 }
00085         }
00086         return false;
00087 }
00088 
00089 void CL_ComponentTokenizer::tokenize()
00090 {
00091         int cur_pos = 0;
00092         int cur_line = 0;
00093         while (cur_pos < total_size)
00094         {
00095                 while (
00096                         cur_pos < total_size && 
00097                         (
00098                                 is_remark(data[cur_pos], cur_pos) ||
00099                                 is_space(data[cur_pos])
00100                         ))
00101                 {
00102                         if (data[cur_pos] == '\n') cur_line++;
00103                         cur_pos++;
00104                 }
00105                 if (cur_pos == total_size) break;
00106 
00107                 if (is_operator(data[cur_pos]))
00108                 {
00109                         tokens.push_back(CL_Token(std::string(&data[cur_pos], 1), cur_pos, cur_line));
00110                         cur_pos++;
00111                 }
00112                 else
00113                 {
00114                         int temp_pos = cur_pos;
00115                         if (data[temp_pos] == '"')
00116                         {
00117                                 int num_chars = 0;
00118                                 temp_pos++;
00119                                 while (temp_pos < total_size)
00120                                 {
00121                                         if (data[temp_pos] == '"')
00122                                         {
00123                                                 if (temp_pos+1>=total_size || data[temp_pos+1] != '"') break;
00124                                                 else
00125                                                 {
00126                                                         temp_pos++;
00127                                                 }
00128                                         }
00129                                         temp_pos++;
00130                                         num_chars++;
00131                                 }
00132                                 if (temp_pos == total_size)
00133                                 {
00134                                         write_error("Missing '""' following '""'-begin");
00135                                         break;
00136                                 }
00137 
00138                                 char *temp = new char[num_chars+1];
00139                                 temp[num_chars] = 0;
00140                                 int ofs = 1;
00141                                 for (int i=0;i<num_chars;i++)
00142                                 {
00143                                         temp[i] = data[cur_pos+ofs+i];
00144                                         if (data[cur_pos+ofs+i] == '"') 
00145                                         {
00146                                                 ofs++;
00147                                         }
00148                                 }
00149                                 cur_pos = temp_pos+1;
00150 
00151                                 tokens.push_back(CL_Token(std::string(temp), cur_pos, cur_line));
00152                                 delete temp;
00153                         }
00154                         else
00155                         {
00156                                 while (temp_pos < total_size &&
00157                                         !is_space(data[temp_pos]) &&
00158                                         !is_operator(data[temp_pos]) &&
00159                                         !is_remark(data[temp_pos], cur_pos))
00160                                 {
00161                                         temp_pos++;
00162                                 }
00163                                 int tok_size = temp_pos-cur_pos;
00164                                 tokens.push_back(CL_Token(std::string(&data[cur_pos], tok_size), cur_pos, cur_line));
00165                                 cur_pos += tok_size;
00166                         }
00167                 }
00168         }
00169 }
00170 
00171 std::string CL_ComponentTokenizer::get_next_token(int *offset)
00172 {
00173         peek_pos = 0;
00174         last_line = tokens[0].line;
00175         std::string token = tokens[0].token;
00176         if (offset != NULL) *offset = tokens[0].offset;
00177 
00178         tokens.pop_front();
00179 
00180         return token;
00181 }
00182 
00183 std::string CL_ComponentTokenizer::peek_next_token(int *offset)
00184 {
00185         if (peek_pos >= (int) tokens.size())
00186         {
00187                 return "";
00188         }
00189         if (offset != NULL) *offset = tokens[peek_pos].offset;
00190         return tokens[peek_pos++].token;
00191 }
00192 
00193 void CL_ComponentTokenizer::pop_to_peek()
00194 {
00195         while (peek_pos > 0)
00196         {
00197                 peek_pos--;
00198                 tokens.pop_front();
00199         }
00200 }
00201 
00202 std::string CL_ComponentTokenizer::write_error(std::string err_msg)
00203 {
00204         CL_String err;
00205         err << "Error occured during read of config file '" <<
00206                 filename.c_str() << "' (line " << last_line << "): " << err_msg.c_str();
00207 
00208         return err;
00209 }

Generated at Wed Apr 4 19:53:59 2001 for ClanLib by doxygen1.2.6 written by Dimitri van Heesch, © 1997-2001