Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

source: code/trunk/src/core/Script.cc @ 2040

Last change on this file since 2040 was 1889, checked in by landauf, 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
RevLine 
[1505]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
[1889]36#include "util/String.h"
37
[1810]38#include "lua/lua.hpp"
[1505]39
[1555]40#include "tolua/tolua++.h"
[1505]41#include "tolua/tolua_bind.h"
42
43namespace orxonox
44{
45  Script* Script::singletonRef = NULL;
46
47  Script::Script()
48  {
49    luaState_ = lua_open();
50    luaSource_ = "";
51#if LUA_VERSION_NUM == 501
52    luaL_openlibs(luaState_);
53#else
54    luaopen_base(luaState_);
55    luaopen_string(luaState_);
56    luaopen_table(luaState_);
57    luaopen_math(luaState_);
58    luaopen_io(luaState_);
59    luaopen_debug(luaState_);
60#endif
[1755]61    tolua_Core_open(luaState_);
[1505]62    output_ = "";
63  }
64
65  void Script::luaPrint(std::string str)
66  {
67    output_ += str;
68//    COUT(4) << "Lua_output!:" << std::endl << str << std::endl << "***" << std::endl;
69    COUT(5) << str;
70  }
71
72  /**
73      @brief Loads the specified file line by line
74      @param filename The filename of the file
75      @param luaTags if true, the loaded file gets stripped off luaTags
76  */
77  void Script::loadFile(std::string filename, bool luaTags)
78  {
79    std::ifstream file;
80    file.open(filename.c_str(), std::fstream::in);
81
82    if (!file.is_open())
83    {
84      // some error msg
85    }
86
87    char line[1024];
88    std::string levelString = "";
89
90    while (file.good() && !file.eof())
91    {
92      file.getline(line, 1024);
93      levelString += line;
94      levelString += "\n";
95    }
96
97    file.close();
98    //std::string output;
99
100    if (luaTags) luaSource_ = replaceLuaTags(levelString);
101    COUT(5) << "ParsedSourceCode: " << luaSource_ << std::endl;
102  }
103
104#if LUA_VERSION_NUM != 501
105  const char * Script::lua_Chunkreader(lua_State *L, void *data, size_t *size)
106  {
107    LoadS* ls = ((LoadS*)data);
108    if (ls->size == 0) return NULL;
109    *size = ls->size;
110    ls->size = 0;
111    return ls->s;
112  }
113#endif
114  void Script::run()
115  {
116    int error = 0;
117    std::string init = "local scr = orxonox.Script:getInstance()\nprint = function(s)\nscr:luaPrint(s)\nend\n";
118    init += luaSource_;
119#if LUA_VERSION_NUM == 501
120    error = luaL_loadstring(luaState_, init.c_str());
121#else
122    LoadS ls;
123    ls.s = init.c_str();
124    ls.size = init.size();
125    error = lua_load(luaState_, &orxonox::Script::lua_Chunkreader, &ls, init.c_str());
126#endif
127    if (error == 0)
128      error = lua_pcall(luaState_, 0, 0, 0);
129    if (error != 0)
130    {
131      COUT(2) << "Error in Lua-script: " << lua_tostring(luaState_, -1) << std::endl;
132    }
133  }
134
135  std::string Script::replaceLuaTags(const std::string& text)
136  {
137    // chreate map with all Lua tags
[1889]138    std::map<size_t, bool> luaTags;
[1505]139    {
[1889]140      size_t pos = 0;
[1505]141      while ((pos = text.find("<?lua", pos)) != std::string::npos)
142        luaTags[pos++] = true;
143    }
144    {
[1889]145      size_t pos = 0;
[1505]146      while ((pos = text.find("?>", pos)) != std::string::npos)
147        luaTags[pos++] = false;
148    }
149
150    // erase all tags from the map that are between two quotes
151    {
[1889]152      std::map<size_t, bool>::iterator it = luaTags.begin();
153      std::map<size_t, bool>::iterator it2 = it;
[1505]154      bool bBetweenQuotes = false;
[1889]155      size_t pos = 0;
[1505]156      while ((pos = getNextQuote(text, pos)) != std::string::npos)
157      {
158        while ((it != luaTags.end()) && (it->first < pos))
159        {
160          if (bBetweenQuotes) {
161            it2++;
162            if(it->second && !(it2->second) && it2->first < pos)
163              it = ++it2;
164            else
165              luaTags.erase(it++);
166          }
167          else
168            ++it;
169        }
170        bBetweenQuotes = !bBetweenQuotes;
171        pos++;
172      }
173    }
174
175    // check whether on every opening <?lua tag a closing ?> tag follows
176    {
177      bool expectedValue = true;
[1889]178      for (std::map<size_t, bool>::iterator it = luaTags.begin(); it != luaTags.end(); ++it)
[1505]179      {
[1755]180        if (it->second == expectedValue)
[1505]181          expectedValue = !expectedValue;
182        else
183        {
184          expectedValue = false;
185          break;
186        }
187      }
188      if (!expectedValue) {
189        // todo: errorhandling
190        return "";
191      }
192    }
193
194    // cut the original string into pieces and put them together with print() instead of lua tags
195    std::string output;
196    {
[1889]197      std::map<size_t, bool>::iterator it = luaTags.begin();
[1505]198      bool bInPrintFunction = true;
[1889]199      size_t start = 0;
200      size_t end = 0;
[1505]201
202      do
203      {
204        if (it != luaTags.end())
205          end = (*(it++)).first;
206        else
207          end = std::string::npos;
208
209        unsigned int equalSignCounter = 0;
210
211        if (bInPrintFunction)
212        {
213          // count ['='[ and ]'='] and replace tags with print([[ and ]])
214          std::string temp = text.substr(start, end - start);
215          {
[1889]216            size_t pos = 0;
[1505]217            while ((pos = temp.find('[', pos)) != std::string::npos)
218            {
219              unsigned int tempCounter = 1;
[1889]220              size_t tempPos = pos++;
[1505]221              while(temp[++tempPos] == '=') {
222                tempCounter++;
223              }
224              if(temp[tempPos] != '[') {
225                tempCounter = 0;
226              }
227              else if(tempCounter == 0) {
228                tempCounter = 1;
229              }
230              if (tempCounter > equalSignCounter)
231                equalSignCounter = tempCounter;
232            }
233          }
234          {
[1889]235            size_t pos = 0;
[1505]236            while ((pos = temp.find(']', pos)) != std::string::npos)
237            {
238              unsigned int tempCounter = 1;
[1889]239              size_t tempPos = pos++;
[1505]240              while(temp[++tempPos] == '=') {
241                tempCounter++;
242              }
243              if(temp[tempPos] != ']') {
244                tempCounter = 0;
245              }
246              else if(tempCounter == 0) {
247                tempCounter = 1;
248              }
249              if (tempCounter > equalSignCounter)
250                equalSignCounter = tempCounter;
251            }
252          }
253          std::string equalSigns = "";
254          for(unsigned int i = 0; i < equalSignCounter; i++) {
255            equalSigns += "=";
256          }
257          output += "print([" + equalSigns + "[" + temp + "]" + equalSigns +"])";
258          start = end + 5;
259        }
260        else
261        {
262          output += text.substr(start, end - start);
263          start = end + 2;
264        }
265
266        bInPrintFunction = !bInPrintFunction;
267      }
268      while (end != std::string::npos);
269    }
270
271    return output;
272  }
273
274}
Note: See TracBrowser for help on using the repository browser.