00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015 #include "Core/precomp.h"
00016 #include "resource_tokenizer.h"
00017 #include <API/Core/IOData/inputsource.h>
00018 #include <API/Core/System/cl_assert.h>
00019 #include <API/Core/System/clanstring.h>
00020
00021 CL_ResourceTokenizer::CL_ResourceTokenizer(std::string filename, CL_InputSource *input)
00022 {
00023 this->filename = filename;
00024
00025 cur_pos = 0;
00026 cur_line = 1;
00027 in_remark = false;
00028
00029 cl_assert(input != NULL);
00030
00031 total_size = input->size();
00032 config_file_data = new unsigned char[total_size];
00033 input->read(config_file_data, total_size);
00034 }
00035
00036 CL_ResourceTokenizer::~CL_ResourceTokenizer()
00037 {
00038 delete[] config_file_data;
00039 }
00040
00041 bool CL_ResourceTokenizer::is_operator(char c)
00042 {
00043 return
00044 c == ',' ||
00045 c == '=' ||
00046 c == '(' ||
00047 c == ')' ||
00048 c == ';' ||
00049 c == '{' ||
00050 c == '}';
00051 }
00052
00053 bool CL_ResourceTokenizer::is_space(char c)
00054 {
00055 return
00056 c == ' ' ||
00057 c == '\t' ||
00058 c == 13 ||
00059 c == 10;
00060 }
00061
00062 bool CL_ResourceTokenizer::is_remark(char c, int position)
00063 {
00064 if (in_remark)
00065 {
00066 if (c == '\n')
00067 {
00068 in_remark = false;
00069 }
00070 return true;
00071 }
00072 else
00073 {
00074 if (c == '/')
00075 {
00076 if (
00077 position+1 < total_size &&
00078 config_file_data[position+1] == '/')
00079 {
00080 in_remark = true;
00081 return true;
00082 }
00083 }
00084 else if (c == '#')
00085 {
00086 in_remark = true;
00087 return true;
00088 }
00089 }
00090 return false;
00091 }
00092
00093 std::string CL_ResourceTokenizer::get_next_token()
00094 {
00095 while (
00096 cur_pos < total_size &&
00097 (
00098 is_remark(config_file_data[cur_pos], cur_pos) ||
00099 is_space(config_file_data[cur_pos])
00100 ))
00101 {
00102 if (config_file_data[cur_pos] == '\n') cur_line++;
00103 cur_pos++;
00104 }
00105 if (cur_pos == total_size) return "";
00106
00107 if (is_operator(config_file_data[cur_pos]))
00108 {
00109 char temp[2];
00110 temp[0] = config_file_data[cur_pos];
00111 temp[1] = 0;
00112 std::string ret(temp);
00113 cur_pos++;
00114
00115 return ret;
00116 }
00117 else
00118 {
00119 int temp_pos = cur_pos;
00120 if (config_file_data[temp_pos] == '"')
00121 {
00122 int num_chars = 0;
00123 temp_pos++;
00124 while (temp_pos < total_size)
00125 {
00126 if (config_file_data[temp_pos] == '"')
00127 {
00128 if (temp_pos+1>=total_size || config_file_data[temp_pos+1] != '"') break;
00129 else
00130 {
00131 temp_pos++;
00132 }
00133 }
00134 temp_pos++;
00135 num_chars++;
00136 }
00137 if (temp_pos == total_size)
00138 {
00139 write_error("Missing '""' following '""'-begin");
00140 return "";
00141 }
00142
00143 char *temp = new char[num_chars+1];
00144 temp[num_chars] = 0;
00145 int ofs = 1;
00146 for (int i=0;i<num_chars;i++)
00147 {
00148 temp[i] = config_file_data[cur_pos+ofs+i];
00149 if (config_file_data[cur_pos+ofs+i] == '"')
00150 {
00151 ofs++;
00152 }
00153 }
00154 cur_pos = temp_pos+1;
00155
00156 std::string ret(temp);
00157 delete temp;
00158
00159 return ret;
00160 }
00161 else
00162 {
00163 while (temp_pos < total_size &&
00164 !is_space(config_file_data[temp_pos]) &&
00165 !is_operator(config_file_data[temp_pos]) &&
00166 !is_remark(config_file_data[temp_pos], cur_pos))
00167 {
00168 temp_pos++;
00169 }
00170 int tok_size = temp_pos-cur_pos;
00171 char *temp = new char[tok_size+1];
00172 temp[tok_size] = 0;
00173 memcpy(temp, &config_file_data[cur_pos], tok_size);
00174 cur_pos += tok_size;
00175
00176 std::string ret(temp);
00177 delete temp;
00178
00179 return ret;
00180 }
00181 }
00182 }
00183
00184 std::string CL_ResourceTokenizer::write_error(std::string err_msg)
00185 {
00186 CL_String err;
00187 err << "Error occured during read of config file '" <<
00188 filename.c_str() << "' (line " << cur_line << "): " << err_msg.c_str();
00189
00190 return err;
00191 }