Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

source: code/branches/buildsystem/src/core/Script.cc @ 2490

Last change on this file since 2490 was 2278, checked in by adrfried, 16 years ago

unsigned int → size_t for std::string related functions

I hope this fixes some problems on 64bit systems

  • Property svn:eol-style set to native
File size: 7.1 KB
Line 
1/*
2 *   ORXONOX - the hottest 3D action shooter ever to exist
3 *                    > www.orxonox.net <
4 *
5 *
6 *   License notice:
7 *
8 *   This program is free software; you can redistribute it and/or
9 *   modify it under the terms of the GNU General Public License
10 *   as published by the Free Software Foundation; either version 2
11 *   of the License, or (at your option) any later version.
12 *
13 *   This program is distributed in the hope that it will be useful,
14 *   but WITHOUT ANY WARRANTY; without even the implied warranty of
15 *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16 *   GNU General Public License for more details.
17 *
18 *   You should have received a copy of the GNU General Public License
19 *   along with this program; if not, write to the Free Software
20 *   Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
21 *
22 *   Author:
23 *      Benjamin Knecht
24 *   Co-authors:
25 *      ...
26 *
27 */
28
29#include "Script.h"
30
31#include <fstream>
32#include <map>
33
34#include "CoreIncludes.h"
35
36extern "C" {
37#include "lua.h"
38#include "lualib.h"
39}
40
41#include "tolua++.h"
42#include "core/ToluaBindCore.h"
43
44namespace orxonox
45{
46  Script* Script::singletonRef = NULL;
47
48  Script::Script()
49  {
50    luaState_ = lua_open();
51    luaSource_ = "";
52#if LUA_VERSION_NUM == 501
53    luaL_openlibs(luaState_);
54#else
55    luaopen_base(luaState_);
56    luaopen_string(luaState_);
57    luaopen_table(luaState_);
58    luaopen_math(luaState_);
59    luaopen_io(luaState_);
60    luaopen_debug(luaState_);
61#endif
62    tolua_Core_open(luaState_);
63    output_ = "";
64  }
65
66  void Script::luaPrint(std::string str)
67  {
68    output_ += str;
69//    COUT(4) << "Lua_output!:" << std::endl << str << std::endl << "***" << std::endl;
70    COUT(5) << str;
71  }
72
73  /**
74      @brief Loads the specified file line by line
75      @param filename The filename of the file
76      @param luaTags if true, the loaded file gets stripped off luaTags
77  */
78  void Script::loadFile(std::string filename, bool luaTags)
79  {
80    std::ifstream file;
81    file.open(filename.c_str(), std::fstream::in);
82
83    if (!file.is_open())
84    {
85      // some error msg
86    }
87
88    char line[1024];
89    std::string levelString = "";
90
91    while (file.good() && !file.eof())
92    {
93      file.getline(line, 1024);
94      levelString += line;
95      levelString += "\n";
96    }
97
98    file.close();
99    //std::string output;
100
101    if (luaTags) luaSource_ = replaceLuaTags(levelString);
102    COUT(5) << "ParsedSourceCode: " << luaSource_ << std::endl;
103  }
104
105#if LUA_VERSION_NUM != 501
106  const char * Script::lua_Chunkreader(lua_State *L, void *data, size_t *size)
107  {
108    LoadS* ls = ((LoadS*)data);
109    if (ls->size == 0) return NULL;
110    *size = ls->size;
111    ls->size = 0;
112    return ls->s;
113  }
114#endif
115  void Script::run()
116  {
117    int error = 0;
118    std::string init = "local scr = orxonox.Script:getInstance()\nprint = function(s)\nscr:luaPrint(s)\nend\n";
119    init += luaSource_;
120#if LUA_VERSION_NUM == 501
121    error = luaL_loadstring(luaState_, init.c_str());
122#else
123    LoadS ls;
124    ls.s = init.c_str();
125    ls.size = init.size();
126    error = lua_load(luaState_, &orxonox::Script::lua_Chunkreader, &ls, init.c_str());
127#endif
128    if (error == 0)
129      error = lua_pcall(luaState_, 0, 0, 0);
130    if (error != 0)
131    {
132      COUT(2) << "Error in Lua-script: " << lua_tostring(luaState_, -1) << std::endl;
133    }
134  }
135
136  std::string Script::replaceLuaTags(const std::string& text)
137  {
138    // chreate map with all Lua tags
139    std::map<size_t, bool> luaTags;
140    {
141      size_t pos = 0;
142      while ((pos = text.find("<?lua", pos)) != std::string::npos)
143        luaTags[pos++] = true;
144    }
145    {
146      size_t pos = 0;
147      while ((pos = text.find("?>", pos)) != std::string::npos)
148        luaTags[pos++] = false;
149    }
150
151    // erase all tags from the map that are between two quotes
152    {
153      std::map<size_t, bool>::iterator it = luaTags.begin();
154      std::map<size_t, bool>::iterator it2 = it;
155      bool bBetweenQuotes = false;
156      size_t pos = 0;
157      while ((pos = getNextQuote(text, pos)) != std::string::npos)
158      {
159        while ((it != luaTags.end()) && (it->first < pos))
160        {
161          if (bBetweenQuotes) {
162            it2++;
163            if(it->second && !(it2->second) && it2->first < pos)
164              it = ++it2;
165            else
166              luaTags.erase(it++);
167          }
168          else
169            ++it;
170        }
171        bBetweenQuotes = !bBetweenQuotes;
172        pos++;
173      }
174    }
175
176    // check whether on every opening <?lua tag a closing ?> tag follows
177    {
178      bool expectedValue = true;
179      for (std::map<size_t, bool>::iterator it = luaTags.begin(); it != luaTags.end(); ++it)
180      {
181        if (it->second == expectedValue)
182          expectedValue = !expectedValue;
183        else
184        {
185          expectedValue = false;
186          break;
187        }
188      }
189      if (!expectedValue) {
190        // todo: errorhandling
191        return "";
192      }
193    }
194
195    // cut the original string into pieces and put them together with print() instead of lua tags
196    std::string output;
197    {
198      std::map<size_t, bool>::iterator it = luaTags.begin();
199      bool bInPrintFunction = true;
200      size_t start = 0;
201      size_t end = 0;
202
203      do
204      {
205        if (it != luaTags.end())
206          end = (*(it++)).first;
207        else
208          end = std::string::npos;
209
210        unsigned int equalSignCounter = 0;
211
212        if (bInPrintFunction)
213        {
214          // count ['='[ and ]'='] and replace tags with print([[ and ]])
215          std::string temp = text.substr(start, end - start);
216          {
217            size_t pos = 0;
218            while ((pos = temp.find('[', pos)) != std::string::npos)
219            {
220              unsigned int tempCounter = 1;
221              size_t tempPos = pos++;
222              while(temp[++tempPos] == '=') {
223                tempCounter++;
224              }
225              if(temp[tempPos] != '[') {
226                tempCounter = 0;
227              }
228              else if(tempCounter == 0) {
229                tempCounter = 1;
230              }
231              if (tempCounter > equalSignCounter)
232                equalSignCounter = tempCounter;
233            }
234          }
235          {
236            size_t pos = 0;
237            while ((pos = temp.find(']', pos)) != std::string::npos)
238            {
239              unsigned int tempCounter = 1;
240              size_t tempPos = pos++;
241              while(temp[++tempPos] == '=') {
242                tempCounter++;
243              }
244              if(temp[tempPos] != ']') {
245                tempCounter = 0;
246              }
247              else if(tempCounter == 0) {
248                tempCounter = 1;
249              }
250              if (tempCounter > equalSignCounter)
251                equalSignCounter = tempCounter;
252            }
253          }
254          std::string equalSigns = "";
255          for(unsigned int i = 0; i < equalSignCounter; i++) {
256            equalSigns += "=";
257          }
258          output += "print([" + equalSigns + "[" + temp + "]" + equalSigns +"])";
259          start = end + 5;
260        }
261        else
262        {
263          output += text.substr(start, end - start);
264          start = end + 2;
265        }
266
267        bInPrintFunction = !bInPrintFunction;
268      }
269      while (end != std::string::npos);
270    }
271
272    return output;
273  }
274
275}
Note: See TracBrowser for help on using the repository browser.