Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

Ignore:
Timestamp:
Feb 11, 2015, 10:56:26 AM (9 years ago)
Author:
muemart
Message:

Various fixes and improvements in the Loader (and LuaState)

  • When there's lua code in the xml, the error message now says where exactly the error is coming from (file and line)
  • When there's an error in the loader when reading xml, the full xml file gets dumped to the temporary directory for inspection
  • Fix and simplify detection of lua tags
  • Make sure the reported line in an xml parsing error is useful
File:
1 edited

Legend:

Unmodified
Added
Removed
  • code/trunk/src/libraries/core/Loader.cc

    r9667 r10264  
    3232#include <tinyxml/ticpp.h>
    3333#include <boost/scoped_ptr.hpp>
     34#include <boost/filesystem.hpp>
     35#include <boost/filesystem/fstream.hpp>
    3436
    3537#include "util/Output.h"
     
    157159
    158160        std::string xmlInput;
     161
     162        shared_ptr<std::vector<std::vector<std::pair<std::string, size_t>>>> lineTrace(new std::vector<std::vector<std::pair<std::string, size_t>>>());
     163        lineTrace->reserve(1000); //arbitrary number
     164
     165
    159166        if (file->getLuaSupport() && !bRemoveLuaTags)
    160167        {
    161168            // Use the LuaState to replace the XML tags (calls our function)
    162169            scoped_ptr<LuaState> luaState(new LuaState());
     170            luaState->setTraceMap(lineTrace);
    163171            luaState->setIncludeParser(&Loader::replaceLuaTags);
    164172            luaState->includeFile(file->getFilename());
     
    231239            orxout(user_error, context::loader) << ex.what() << endl;
    232240            orxout(user_error, context::loader) << "Loading aborted." << endl;
    233             return false;
     241            if (lineTrace->size() > 0)
     242            {
     243                //Extract the line number from the exception
     244                std::string tempstring(ex.what());
     245                std::string::size_type pos = tempstring.find("\nLine: ");
     246                if (pos != std::string::npos)
     247                {
     248                    std::istringstream istr(tempstring.substr(pos + 7));
     249                    size_t line;
     250                    istr >> line;
     251                    if (line <= lineTrace->size())
     252                    {
     253                        std::vector<std::pair<std::string, size_t>> linesources = lineTrace->at(line - 1);
     254                        orxout(user_error, context::loader) << "Line contains data from:" << endl;
     255                        for (std::vector<std::pair<std::string, size_t>>::iterator it = linesources.begin(); it != linesources.end(); ++it)
     256                        {
     257                            orxout(user_error, context::loader) << it->first << " , Line " << it->second << endl;
     258                        }                       
     259                    }
     260                }
     261            }
    234262        }
    235263        catch (Exception& ex)
     
    239267            orxout(user_error, context::loader) << ex.what() << endl;
    240268            orxout(user_error, context::loader) << "Loading aborted." << endl;
    241             return false;
    242269        }
    243270        catch (...)
     
    247274            orxout(user_error, context::loader) << Exception::handleMessage() << endl;
    248275            orxout(user_error, context::loader) << "Loading aborted." << endl;
    249             return false;
    250         }
     276        }
     277        //The Tardis' version of boost is too old...
     278#if BOOST_VERSION >= 104600
     279        boost::filesystem::path temppath = boost::filesystem::temp_directory_path() / "orxonoxml.xml";
     280        //Need binary mode, because xmlInput already has \r\n for windows
     281        boost::filesystem::ofstream outfile(temppath, std::ios_base::binary | std::ios_base::out);
     282        outfile << xmlInput;
     283        outfile.flush();
     284        outfile.close();
     285        orxout(user_error, context::loader) << "The complete xml file has been saved to " << temppath << endl;
     286#endif
     287        return false;
    251288    }
    252289
     
    299336        {
    300337            std::map<size_t, bool>::iterator it = luaTags.begin();
    301             std::map<size_t, bool>::iterator it2 = it;
    302             bool bBetweenQuotes = false;
    303             size_t pos = 0;
    304             while ((pos = getNextQuote(text, pos)) != std::string::npos)
    305             {
    306                 while ((it != luaTags.end()) && (it->first < pos))
     338            while(it != luaTags.end())
     339            {
     340                if (isBetweenQuotes(text, it->first))
    307341                {
    308                     if (bBetweenQuotes)
    309                     {
    310                         it2++;
    311                         if (it->second && !(it2->second) && it2->first < pos)
    312                             it = ++it2;
    313                         else
    314                             luaTags.erase(it++);
    315                     }
    316                     else
    317                         ++it;
     342                    luaTags.erase(it++);
    318343                }
    319                 bBetweenQuotes = !bBetweenQuotes;
    320                 pos++;
     344                else
     345                {
     346                    ++it;
     347                }
    321348            }
    322349        }
     
    337364            if (!expectedValue)
    338365            {
    339                 orxout(internal_error, context::loader) << "Error in level file" << endl;
     366                orxout(internal_error, context::loader) << "Error parsing file: lua tags not matching" << endl;
    340367                // TODO: error handling
    341368                return false;
     
    425452                        equalSigns += '=';
    426453                    }
    427                     output << "print([" + equalSigns + '[' + temp + ']' + equalSigns +"])";
     454                    //A newline directly after square brackets is ignored. To make sure that the string is printed
     455                    //exactly as it is, including newlines at the beginning, insert a space after the brackets.
     456                    output << "print([" + equalSigns + "[ " + temp + ']' + equalSigns +"])";
    428457                    start = end + 5;
    429458                }
     
    471500            }
    472501            else
     502            {
     503                //Preserve the amount of lines, otherwise the linenumber from the xml parse error is useless
     504                std::string tempstring = text.substr(start, end - start);
     505                output << std::string(std::count(tempstring.begin(), tempstring.end(), '\n'), '\n');
    473506                start = end + 2;
     507            }
    474508
    475509            bLuaCode = !bLuaCode;
Note: See TracChangeset for help on using the changeset viewer.