mirror of https://github.com/KLayout/klayout.git
WIP: allow breakpoints for files with includes and inside includes
This commit is contained in:
parent
77a9253273
commit
9c2914f016
|
|
@ -44,6 +44,7 @@
|
|||
#include "tlClassRegistry.h"
|
||||
#include "tlExceptions.h"
|
||||
#include "tlFileUtils.h"
|
||||
#include "tlInclude.h"
|
||||
|
||||
#include <cstdio>
|
||||
#include <limits>
|
||||
|
|
@ -2781,6 +2782,9 @@ MacroEditorDialog::start_exec (gsi::Interpreter *ec)
|
|||
}
|
||||
|
||||
m_file_to_widget.clear ();
|
||||
m_include_expanders.clear ();
|
||||
m_include_paths_to_ids.clear ();
|
||||
m_include_file_id_cache.clear ();
|
||||
|
||||
m_last_process_events = tl::Clock::current ();
|
||||
|
||||
|
|
@ -2825,6 +2829,7 @@ MacroEditorDialog::end_exec (gsi::Interpreter *ec)
|
|||
do_update_ui_to_run_mode ();
|
||||
}
|
||||
|
||||
const size_t pseudo_file_offset = std::numeric_limits<size_t>::max () / 2;
|
||||
|
||||
size_t
|
||||
MacroEditorDialog::id_for_path (gsi::Interpreter *, const std::string &path)
|
||||
|
|
@ -2840,8 +2845,66 @@ MacroEditorDialog::id_for_path (gsi::Interpreter *, const std::string &path)
|
|||
if (macro) {
|
||||
m_file_to_widget.push_back (std::make_pair (macro, (MacroEditorPage *) 0));
|
||||
return m_file_to_widget.size ();
|
||||
} else {
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (! path.empty () && path[0] == '@') {
|
||||
m_include_expanders.push_back (tl::IncludeExpander::from_string (path));
|
||||
return pseudo_file_offset + m_include_expanders.size () - 1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
void
|
||||
MacroEditorDialog::translate_pseudo_id (size_t &file_id, int &line)
|
||||
{
|
||||
if (file_id >= pseudo_file_offset) {
|
||||
|
||||
file_id -= pseudo_file_offset;
|
||||
|
||||
std::pair<size_t, int> ck (file_id, line);
|
||||
|
||||
std::map<std::pair<size_t, int>, std::pair<size_t, int> >::iterator ic = m_include_file_id_cache.find (ck);
|
||||
if (ic != m_include_file_id_cache.end ()) {
|
||||
|
||||
file_id = ic->second.first;
|
||||
line = ic->second.second;
|
||||
|
||||
} else {
|
||||
|
||||
if (file_id < m_include_expanders.size ()) {
|
||||
|
||||
std::pair<std::string, int> fp = m_include_expanders [file_id].translate_to_original (line);
|
||||
line = fp.second;
|
||||
|
||||
std::map<std::string, size_t>::const_iterator i = m_include_paths_to_ids.find (fp.first);
|
||||
if (i == m_include_paths_to_ids.end ()) {
|
||||
|
||||
size_t new_id = id_for_path (0, fp.first);
|
||||
if (new_id < pseudo_file_offset) {
|
||||
file_id = new_id;
|
||||
} else {
|
||||
file_id = 0;
|
||||
}
|
||||
|
||||
m_include_paths_to_ids.insert (std::make_pair (fp.first, file_id));
|
||||
|
||||
} else {
|
||||
file_id = i->second;
|
||||
}
|
||||
|
||||
} else {
|
||||
|
||||
// give up.
|
||||
file_id = 0;
|
||||
line = 0;
|
||||
|
||||
}
|
||||
|
||||
m_include_file_id_cache.insert (std::make_pair (ck, std::make_pair (file_id, line)));
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -2862,6 +2925,9 @@ MacroEditorDialog::exception_thrown (gsi::Interpreter *interpreter, size_t file_
|
|||
return;
|
||||
}
|
||||
|
||||
// translate the pseudo file ID and line to the real one (include file processing)
|
||||
translate_pseudo_id (file_id, line);
|
||||
|
||||
try {
|
||||
|
||||
// If the exception is thrown in code that is inside a file managed by the macro collection,
|
||||
|
|
@ -2958,6 +3024,9 @@ MacroEditorDialog::trace (gsi::Interpreter *interpreter, size_t file_id, int lin
|
|||
m_current_stack_depth = stack_trace_provider->stack_depth ();
|
||||
}
|
||||
|
||||
// translate the pseudo file ID and line to the real one (include file processing)
|
||||
translate_pseudo_id (file_id, line);
|
||||
|
||||
// Note: only scripts running in the context of the execution controller (the one who called start_exec)
|
||||
// can be interrupted and single-stepped, but breakpoints can make the debugger stop in other interpreters.
|
||||
if (file_id > 0 && ((interpreter == mp_exec_controller && m_stop_stack_depth >= 0 && stack_trace_provider->stack_depth () <= m_stop_stack_depth) ||
|
||||
|
|
|
|||
|
|
@ -35,6 +35,7 @@
|
|||
#include "tlFileSystemWatcher.h"
|
||||
#include "tlDeferredExecution.h"
|
||||
#include "tlScriptError.h"
|
||||
#include "tlInclude.h"
|
||||
#include "lymMacro.h"
|
||||
#include "gsiInterpreter.h"
|
||||
|
||||
|
|
@ -290,6 +291,7 @@ private:
|
|||
void select_trace (size_t index);
|
||||
bool configure (const std::string &name, const std::string &value);
|
||||
void config_finalize ();
|
||||
void translate_pseudo_id (size_t &file_id, int &line);
|
||||
|
||||
lay::Dispatcher *mp_plugin_root;
|
||||
lym::MacroCollection *mp_root;
|
||||
|
|
@ -312,6 +314,9 @@ private:
|
|||
QTextCharFormat m_stderr_format;
|
||||
MacroEditorHighlighters m_highlighters;
|
||||
std::vector<std::pair<lym::Macro *, MacroEditorPage *> > m_file_to_widget;
|
||||
std::vector<tl::IncludeExpander> m_include_expanders;
|
||||
std::map<std::string, size_t> m_include_paths_to_ids;
|
||||
std::map<std::pair<size_t, int>, std::pair<size_t, int> > m_include_file_id_cache;
|
||||
std::vector<lay::MacroEditorTree *> m_macro_trees;
|
||||
bool m_in_exec, m_in_breakpoint;
|
||||
gsi::Interpreter *mp_exec_controller, *mp_current_interpreter;
|
||||
|
|
|
|||
|
|
@ -30,6 +30,7 @@
|
|||
|
||||
#include "tlClassRegistry.h"
|
||||
#include "tlFileUtils.h"
|
||||
#include "tlInclude.h"
|
||||
|
||||
#include <cstdio>
|
||||
|
||||
|
|
@ -101,7 +102,7 @@ class MacroInterpreter
|
|||
public:
|
||||
MacroInterpreter ()
|
||||
: lym::MacroInterpreter (),
|
||||
mp_registration (0)
|
||||
mp_registration (0), m_supports_include_expansion (true)
|
||||
{
|
||||
m_suffix = lym::MacroInterpreter::suffix ();
|
||||
m_description = lym::MacroInterpreter::description ();
|
||||
|
|
@ -120,6 +121,15 @@ public:
|
|||
m_templates.clear ();
|
||||
}
|
||||
|
||||
std::pair<std::string, std::string> include_expansion (const lym::Macro *macro)
|
||||
{
|
||||
if (m_supports_include_expansion) {
|
||||
return MacroInterpreter::include_expansion (macro);
|
||||
} else {
|
||||
return std::pair<std::string, std::string> (macro->path (), macro->text ());
|
||||
}
|
||||
}
|
||||
|
||||
void register_gsi (const char *name)
|
||||
{
|
||||
// makes the object owned by the C++ side
|
||||
|
|
@ -139,6 +149,16 @@ public:
|
|||
}
|
||||
}
|
||||
|
||||
void set_supports_include_expansion (bool f)
|
||||
{
|
||||
m_supports_include_expansion = f;
|
||||
}
|
||||
|
||||
virtual bool supports_include_expansion () const
|
||||
{
|
||||
return m_supports_include_expansion;
|
||||
}
|
||||
|
||||
void set_storage_scheme (int scheme)
|
||||
{
|
||||
m_storage_scheme = lym::Macro::Format (scheme);
|
||||
|
|
@ -231,6 +251,7 @@ private:
|
|||
lym::Macro::Interpreter m_debugger_scheme;
|
||||
std::string m_suffix;
|
||||
std::string m_description;
|
||||
bool m_supports_include_expansion;
|
||||
};
|
||||
|
||||
int const_PlainTextFormat ()
|
||||
|
|
@ -294,6 +315,14 @@ Class<gsi::MacroInterpreter> decl_MacroInterpreter ("lay", "MacroInterpreter",
|
|||
"\n"
|
||||
"This method must be called after \\register has called.\n"
|
||||
) +
|
||||
gsi::method ("supports_include_expansion=", &MacroInterpreter::set_supports_include_expansion, gsi::arg ("flag"),
|
||||
"@brief Sets a value indicating whether this interpreter supports the default include file expansion scheme.\n"
|
||||
"If this value is set to true (the default), lines like '# %include ...' will be substituted by the "
|
||||
"content of the file following the '%include' keyword.\n"
|
||||
"Set this value to false if you don't want to support this feature.\n"
|
||||
"\n"
|
||||
"This attribute has been introduced in version 0.27.\n"
|
||||
) +
|
||||
gsi::method ("syntax_scheme=", &gsi::MacroInterpreter::set_syntax_scheme, gsi::arg ("scheme"),
|
||||
"@brief Sets a string indicating the syntax highlighter scheme\n"
|
||||
"\n"
|
||||
|
|
|
|||
|
|
@ -8,7 +8,6 @@ DEFINES += MAKE_LYM_LIBRARY
|
|||
|
||||
SOURCES = \
|
||||
gsiDeclLymMacro.cc \
|
||||
lymInclude.cpp \
|
||||
lymMacroInterpreter.cc \
|
||||
lymMacro.cc \
|
||||
|
||||
|
|
|
|||
|
|
@ -33,6 +33,7 @@
|
|||
#include "tlLog.h"
|
||||
#include "tlXMLParser.h"
|
||||
#include "tlGlobPattern.h"
|
||||
#include "tlInclude.h"
|
||||
|
||||
#include "rba.h"
|
||||
#include "pya.h"
|
||||
|
|
@ -1020,20 +1021,28 @@ int Macro::run () const
|
|||
}
|
||||
|
||||
try {
|
||||
|
||||
gsi::Interpreter *ip = script_interpreter (interpreter ());
|
||||
if (ip) {
|
||||
|
||||
if (! prolog ().empty ()) {
|
||||
ip->eval_string (prolog ().c_str ());
|
||||
}
|
||||
ip->eval_string (text ().c_str (), path ().c_str (), 1);
|
||||
|
||||
std::string expanded_text;
|
||||
tl::IncludeExpander ie = tl::IncludeExpander::expand (path (), text (), expanded_text);
|
||||
ip->eval_string (expanded_text.c_str (), ie.to_string ().c_str (), 1);
|
||||
|
||||
if (! epilog ().empty ()) {
|
||||
ip->eval_string (epilog ().c_str ());
|
||||
}
|
||||
|
||||
} else if (interpreter () == lym::Macro::DSLInterpreter) {
|
||||
lym::MacroInterpreter::execute_macro (this);
|
||||
} else {
|
||||
throw tl::Exception (tl::to_string (tr ("Can't run macro (no interpreter): ")) + path ());
|
||||
}
|
||||
|
||||
} catch (tl::ExitException &ex) {
|
||||
return ex.status ();
|
||||
}
|
||||
|
|
|
|||
|
|
@ -27,6 +27,7 @@
|
|||
#include "tlInternational.h"
|
||||
#include "tlException.h"
|
||||
#include "tlClassRegistry.h"
|
||||
#include "tlInclude.h"
|
||||
|
||||
namespace lym
|
||||
{
|
||||
|
|
@ -48,13 +49,39 @@ MacroInterpreter::can_run (const lym::Macro *macro)
|
|||
return false;
|
||||
}
|
||||
|
||||
std::pair<std::string, std::string>
|
||||
MacroInterpreter::include_expansion (const lym::Macro *macro)
|
||||
{
|
||||
std::pair<std::string, std::string> res;
|
||||
res.first = tl::IncludeExpander::expand (macro->path (), macro->text (), res.second).to_string ();
|
||||
return res;
|
||||
}
|
||||
|
||||
void
|
||||
MacroInterpreter::execute_macro (const lym::Macro *macro)
|
||||
{
|
||||
for (tl::Registrar<lym::MacroInterpreter>::iterator cls = tl::Registrar<lym::MacroInterpreter>::begin (); cls != tl::Registrar<lym::MacroInterpreter>::end (); ++cls) {
|
||||
|
||||
if (cls.current_name () == macro->dsl_interpreter ()) {
|
||||
cls->execute (macro);
|
||||
|
||||
std::pair<std::string, std::string> et = cls->include_expansion (macro);
|
||||
if (et.first.empty () || et.first == macro->path ()) {
|
||||
|
||||
cls->execute (macro);
|
||||
|
||||
} else {
|
||||
|
||||
// provide a copy which takes the include-expanded version
|
||||
lym::Macro tmp_macro;
|
||||
tmp_macro.assign (*macro);
|
||||
tmp_macro.set_text (et.second);
|
||||
tmp_macro.set_file_path (et.first);
|
||||
cls->execute (&tmp_macro);
|
||||
|
||||
}
|
||||
|
||||
return;
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -138,6 +138,18 @@ public:
|
|||
// .. nothing yet ..
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Provides generic include file expansion
|
||||
*
|
||||
* This method takes a given macro and substitutes include statements of the form '# %include ...' by the
|
||||
* content of the respective file. Recursive include is supported.
|
||||
* The return value of this method is a two-element array with two strings: the first one is a path string which
|
||||
* holds the encoded information for translating back path/line number information into the original paths and
|
||||
* line numbers. This first string needs to be passed to the actual script interpreter as the 'file path'. The
|
||||
* second component of the returned array is the text of the macro with the include files substituted.
|
||||
*/
|
||||
virtual std::pair<std::string, std::string> include_expansion (const lym::Macro *macro);
|
||||
|
||||
/**
|
||||
* @brief Runs the script for the DSL interpreter with the given name
|
||||
*
|
||||
|
|
|
|||
|
|
@ -0,0 +1,31 @@
|
|||
|
||||
/*
|
||||
|
||||
KLayout Layout Viewer
|
||||
Copyright (C) 2006-2018 Matthias Koefferlein
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
|
||||
*/
|
||||
|
||||
|
||||
#include "tlUnitTest.h"
|
||||
|
||||
TEST(1)
|
||||
{
|
||||
// TODO: add tests for lym specific things
|
||||
throw tl::CancelException (); // skip this test to indicate that there is nothing yet
|
||||
}
|
||||
|
||||
|
|
@ -7,7 +7,7 @@ TARGET = lym_tests
|
|||
include($$PWD/../../lib_ut.pri)
|
||||
|
||||
SOURCES = \
|
||||
lymIncludeTests.cc
|
||||
lymBasicTests.cc
|
||||
|
||||
INCLUDEPATH += $$LYM_INC $$TL_INC $$GSI_INC
|
||||
DEPENDPATH += $$LYM_INC $$TL_INC $$GSI_INC
|
||||
|
|
|
|||
|
|
@ -20,6 +20,7 @@ SOURCES = \
|
|||
tlGlobPattern.cc \
|
||||
tlHeap.cc \
|
||||
tlHttpStream.cc \
|
||||
tlInclude.cc \
|
||||
tlInternational.cc \
|
||||
tlLog.cc \
|
||||
tlObject.cc \
|
||||
|
|
@ -63,6 +64,7 @@ HEADERS = \
|
|||
tlGlobPattern.h \
|
||||
tlHeap.h \
|
||||
tlHttpStream.h \
|
||||
tlInclude.h \
|
||||
tlInternational.h \
|
||||
tlIntervalMap.h \
|
||||
tlIntervalSet.h \
|
||||
|
|
|
|||
|
|
@ -20,7 +20,7 @@
|
|||
|
||||
*/
|
||||
|
||||
#include "lymInclude.h"
|
||||
#include "tlInclude.h"
|
||||
|
||||
#include "tlAssert.h"
|
||||
#include "tlString.h"
|
||||
|
|
@ -29,7 +29,7 @@
|
|||
#include "tlExpression.h"
|
||||
#include "tlUri.h"
|
||||
|
||||
namespace lym
|
||||
namespace tl
|
||||
{
|
||||
|
||||
static const char *valid_fn_chars = "@_:,.\\/-+";
|
||||
|
|
@ -44,16 +44,27 @@ IncludeExpander::expand (const std::string &path, std::string &expanded_text)
|
|||
{
|
||||
IncludeExpander ie;
|
||||
int lc = 1;
|
||||
read (path, expanded_text, ie, lc);
|
||||
tl::InputStream is (path);
|
||||
ie.read (path, is, expanded_text, ie, lc);
|
||||
return ie;
|
||||
}
|
||||
|
||||
IncludeExpander
|
||||
IncludeExpander::expand (const std::string &path, const std::string &original_text, std::string &expanded_text)
|
||||
{
|
||||
IncludeExpander ie;
|
||||
int lc = 1;
|
||||
tl::InputMemoryStream ms (original_text.c_str (), original_text.size ());
|
||||
tl::InputStream is (ms);
|
||||
ie.read (path, is, expanded_text, ie, lc);
|
||||
return ie;
|
||||
}
|
||||
|
||||
void
|
||||
IncludeExpander::read (const std::string &path, std::string &expanded_text, IncludeExpander &ie, int &line_counter)
|
||||
IncludeExpander::read (const std::string &path, tl::InputStream &is, std::string &expanded_text, IncludeExpander &ie, int &line_counter)
|
||||
{
|
||||
ie.m_sections [line_counter] = std::make_pair (path, 1 - line_counter);
|
||||
|
||||
tl::InputStream is (path);
|
||||
tl::TextInputStream text (is);
|
||||
|
||||
int lnum = 0;
|
||||
|
|
@ -83,7 +94,8 @@ IncludeExpander::read (const std::string &path, std::string &expanded_text, Incl
|
|||
include_path = current_uri.resolved (new_uri).to_string ();
|
||||
}
|
||||
|
||||
read (include_path, expanded_text, ie, line_counter);
|
||||
tl::InputStream is (include_path);
|
||||
read (include_path, is, expanded_text, ie, line_counter);
|
||||
|
||||
emit_section = true;
|
||||
|
||||
|
|
@ -125,7 +137,7 @@ IncludeExpander::to_string () const
|
|||
|
||||
for (std::map<int, std::pair<std::string, int> >::const_iterator m = m_sections.begin (); m != m_sections.end (); ++m) {
|
||||
res += tl::to_string (m->first);
|
||||
res += ":";
|
||||
res += "*";
|
||||
res += tl::to_word_or_quoted_string (m->second.first, valid_fn_chars);
|
||||
res += "*";
|
||||
res += tl::to_string (m->second.second);
|
||||
|
|
@ -153,7 +165,7 @@ IncludeExpander::from_string (const std::string &s)
|
|||
|
||||
std::pair<std::string, int> &si = ie.m_sections [ln];
|
||||
|
||||
ex.expect (":");
|
||||
ex.expect ("*");
|
||||
ex.read_word_or_quoted (si.first, valid_fn_chars);
|
||||
ex.expect ("*");
|
||||
ex.read (si.second);
|
||||
|
|
@ -21,17 +21,19 @@
|
|||
*/
|
||||
|
||||
|
||||
#ifndef HDR_lymInclude
|
||||
#define HDR_lymInclude
|
||||
#ifndef HDR_tlInclude
|
||||
#define HDR_tlInclude
|
||||
|
||||
#include "lymCommon.h"
|
||||
#include "tlCommon.h"
|
||||
|
||||
#include <string>
|
||||
#include <map>
|
||||
|
||||
namespace lym
|
||||
namespace tl
|
||||
{
|
||||
|
||||
class InputStream;
|
||||
|
||||
/**
|
||||
* @brief Provide the basic include expansion and file/line mapping mechanism
|
||||
*
|
||||
|
|
@ -44,7 +46,7 @@ namespace lym
|
|||
* The file path is expression-interpolated, hence can access environment variables
|
||||
* through $(env("HOME")) for example.
|
||||
*/
|
||||
class LYM_PUBLIC IncludeExpander
|
||||
class TL_PUBLIC IncludeExpander
|
||||
{
|
||||
public:
|
||||
/**
|
||||
|
|
@ -59,6 +61,14 @@ public:
|
|||
*/
|
||||
static IncludeExpander expand (const std::string &path, std::string &expanded_text);
|
||||
|
||||
/**
|
||||
* @brief Provides include expansion
|
||||
*
|
||||
* This method will deliver the expanded text and the include expander object.
|
||||
* This version also takes the actual text of the original file.
|
||||
*/
|
||||
static IncludeExpander expand (const std::string &path, const std::string &original_text, std::string &expanded_text);
|
||||
|
||||
/**
|
||||
* @brief Serializes the include expander information into a string
|
||||
*
|
||||
|
|
@ -82,15 +92,13 @@ public:
|
|||
*/
|
||||
static std::pair<std::string, int> translate_to_original (const std::string &file, int line_number)
|
||||
{
|
||||
IncludeExpander ie;
|
||||
ie.from_string (file);
|
||||
return ie.translate_to_original (line_number);
|
||||
return IncludeExpander::from_string (file).translate_to_original (line_number);
|
||||
}
|
||||
|
||||
public:
|
||||
private:
|
||||
std::map<int, std::pair<std::string, int> > m_sections;
|
||||
|
||||
static void read (const std::string &path, std::string &expanded_text, IncludeExpander &ie, int &line_counter);
|
||||
void read (const std::string &path, tl::InputStream &is, std::string &expanded_text, IncludeExpander &ie, int &line_counter);
|
||||
};
|
||||
|
||||
}
|
||||
|
|
@ -22,6 +22,7 @@
|
|||
|
||||
#include "tlScriptError.h"
|
||||
#include "tlString.h"
|
||||
#include "tlInclude.h"
|
||||
|
||||
namespace tl
|
||||
{
|
||||
|
|
@ -32,13 +33,13 @@ namespace tl
|
|||
BacktraceElement::BacktraceElement (const std::string &_file, int _line)
|
||||
: file (_file), line (_line)
|
||||
{
|
||||
// .. nothing yet ..
|
||||
translate_includes ();
|
||||
}
|
||||
|
||||
BacktraceElement::BacktraceElement (const std::string &_file, int _line, const std::string _more_info)
|
||||
: file (_file), line (_line), more_info (_more_info)
|
||||
{
|
||||
// .. nothing yet ..
|
||||
translate_includes ();
|
||||
}
|
||||
|
||||
BacktraceElement::BacktraceElement ()
|
||||
|
|
@ -47,6 +48,20 @@ BacktraceElement::BacktraceElement ()
|
|||
// .. nothing yet ..
|
||||
}
|
||||
|
||||
void
|
||||
BacktraceElement::translate_includes ()
|
||||
{
|
||||
if (line < 1) {
|
||||
return;
|
||||
}
|
||||
|
||||
std::pair<std::string, int> fl = tl::IncludeExpander::translate_to_original (file, line);
|
||||
if (fl.second > 0) {
|
||||
file = fl.first;
|
||||
line = fl.second;
|
||||
}
|
||||
}
|
||||
|
||||
std::string
|
||||
BacktraceElement::to_string() const
|
||||
{
|
||||
|
|
@ -64,20 +79,38 @@ BacktraceElement::to_string() const
|
|||
// -------------------------------------------------------------------
|
||||
// ScriptError implementation
|
||||
|
||||
ScriptError::ScriptError (const char *msg, const char *cls, const std::vector<BacktraceElement> &backtrace)
|
||||
: tl::Exception (msg), m_line (-1), m_cls (cls), m_backtrace (backtrace)
|
||||
{
|
||||
// .. nothing yet ..
|
||||
}
|
||||
|
||||
ScriptError::ScriptError (const char *msg, const char *sourcefile, int line, const char *cls, const std::vector<BacktraceElement> &backtrace)
|
||||
: tl::Exception (msg), m_sourcefile (sourcefile), m_line (line), m_cls (cls), m_backtrace (backtrace)
|
||||
{
|
||||
translate_includes ();
|
||||
}
|
||||
|
||||
ScriptError::ScriptError (const ScriptError &d)
|
||||
: tl::Exception (d), m_sourcefile (d.m_sourcefile), m_line (d.m_line), m_cls (d.m_cls), m_context (d.m_context), m_backtrace (d.m_backtrace)
|
||||
{
|
||||
// .. nothing yet ..
|
||||
}
|
||||
|
||||
std::string
|
||||
ScriptError::basic_msg () const
|
||||
{
|
||||
return tl::Exception::msg ();
|
||||
}
|
||||
|
||||
std::string
|
||||
std::string
|
||||
ScriptError::msg () const
|
||||
{
|
||||
std::string m = basic_msg ();
|
||||
|
||||
if (! m_context.empty ()) {
|
||||
m += tl::to_string (tr (" in ")) + m_context;
|
||||
}
|
||||
m += tl::to_string (tr (" in ")) + m_context;
|
||||
}
|
||||
|
||||
for (std::vector<BacktraceElement>::const_iterator bt = backtrace ().begin (); bt != backtrace ().end (); ++bt) {
|
||||
m += "\n ";
|
||||
|
|
@ -87,6 +120,20 @@ ScriptError::msg () const
|
|||
return m;
|
||||
}
|
||||
|
||||
void
|
||||
ScriptError::translate_includes ()
|
||||
{
|
||||
if (m_line < 1) {
|
||||
return;
|
||||
}
|
||||
|
||||
std::pair<std::string, int> fl = tl::IncludeExpander::translate_to_original (m_sourcefile, m_line);
|
||||
if (fl.second > 0) {
|
||||
m_sourcefile = fl.first;
|
||||
m_line = fl.second;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -60,6 +60,9 @@ struct TL_PUBLIC BacktraceElement
|
|||
std::string file;
|
||||
int line;
|
||||
std::string more_info;
|
||||
|
||||
private:
|
||||
void translate_includes ();
|
||||
};
|
||||
|
||||
/**
|
||||
|
|
@ -69,17 +72,11 @@ class TL_PUBLIC ScriptError
|
|||
: public tl::Exception
|
||||
{
|
||||
public:
|
||||
ScriptError (const char *msg, const char *cls, const std::vector <BacktraceElement> &backtrace)
|
||||
: tl::Exception (msg), m_line (-1), m_cls (cls), m_backtrace (backtrace)
|
||||
{ }
|
||||
ScriptError (const char *msg, const char *cls, const std::vector <BacktraceElement> &backtrace);
|
||||
|
||||
ScriptError (const char *msg, const char *sourcefile, int line, const char *cls, const std::vector <BacktraceElement> &backtrace)
|
||||
: tl::Exception (msg), m_sourcefile (sourcefile), m_line (line), m_cls (cls), m_backtrace (backtrace)
|
||||
{ }
|
||||
ScriptError (const char *msg, const char *sourcefile, int line, const char *cls, const std::vector <BacktraceElement> &backtrace);
|
||||
|
||||
ScriptError (const ScriptError &d)
|
||||
: tl::Exception (d), m_sourcefile (d.m_sourcefile), m_line (d.m_line), m_cls (d.m_cls), m_context (d.m_context), m_backtrace (d.m_backtrace)
|
||||
{ }
|
||||
ScriptError (const ScriptError &d);
|
||||
|
||||
virtual ~ScriptError ()
|
||||
{ }
|
||||
|
|
@ -139,6 +136,8 @@ private:
|
|||
std::string m_cls;
|
||||
std::string m_context;
|
||||
std::vector<BacktraceElement> m_backtrace;
|
||||
|
||||
void translate_includes ();
|
||||
};
|
||||
|
||||
/**
|
||||
|
|
|
|||
|
|
@ -23,17 +23,18 @@
|
|||
|
||||
#include "tlUnitTest.h"
|
||||
#include "tlFileUtils.h"
|
||||
#include "lymInclude.h"
|
||||
#include "tlStream.h"
|
||||
#include "tlInclude.h"
|
||||
|
||||
TEST(1_simple)
|
||||
{
|
||||
std::string fn = tl::testsrc () + "/testdata/lym/x.txt";
|
||||
std::string fn = tl::testsrc () + "/testdata/tl/x.txt";
|
||||
|
||||
std::string et;
|
||||
lym::IncludeExpander ie = lym::IncludeExpander::expand (fn, et);
|
||||
tl::IncludeExpander ie = tl::IncludeExpander::expand (fn, et);
|
||||
EXPECT_EQ (et, "A line\nAnother line\n");
|
||||
EXPECT_EQ (ie.to_string (), fn);
|
||||
EXPECT_EQ (lym::IncludeExpander::from_string (ie.to_string ()).to_string (), ie.to_string ());
|
||||
EXPECT_EQ (tl::IncludeExpander::from_string (ie.to_string ()).to_string (), ie.to_string ());
|
||||
|
||||
EXPECT_EQ (ie.translate_to_original (2).first, fn);
|
||||
EXPECT_EQ (ie.translate_to_original (2).second, 2);
|
||||
|
|
@ -41,18 +42,18 @@ TEST(1_simple)
|
|||
|
||||
TEST(2_single_include)
|
||||
{
|
||||
std::string fn = tl::testsrc () + "/testdata/lym/x_inc1.txt";
|
||||
std::string fn = tl::testsrc () + "/testdata/tl/x_inc1.txt";
|
||||
|
||||
std::string et;
|
||||
lym::IncludeExpander ie = lym::IncludeExpander::expand (fn, et);
|
||||
tl::IncludeExpander ie = tl::IncludeExpander::expand (fn, tl::InputStream (fn).read_all (), et);
|
||||
EXPECT_EQ (et, "A line\nincluded.1\nAnother line\n");
|
||||
|
||||
EXPECT_EQ (ie.to_string (), "@1:" + tl::testsrc () + "/testdata/lym/x_inc1.txt*0;2:" + tl::testsrc () + "/testdata/lym/inc1.txt*-1;3:" + tl::testsrc () + "/testdata/lym/x_inc1.txt*0;");
|
||||
EXPECT_EQ (lym::IncludeExpander::from_string (ie.to_string ()).to_string (), ie.to_string ());
|
||||
EXPECT_EQ (ie.to_string (), "@1*" + tl::testsrc () + "/testdata/tl/x_inc1.txt*0;2*" + tl::testsrc () + "/testdata/tl/inc1.txt*-1;3*" + tl::testsrc () + "/testdata/tl/x_inc1.txt*0;");
|
||||
EXPECT_EQ (tl::IncludeExpander::from_string (ie.to_string ()).to_string (), ie.to_string ());
|
||||
|
||||
EXPECT_EQ (ie.translate_to_original (1).first, fn);
|
||||
EXPECT_EQ (ie.translate_to_original (1).second, 1);
|
||||
EXPECT_EQ (ie.translate_to_original (2).first, tl::testsrc () + "/testdata/lym/inc1.txt");
|
||||
EXPECT_EQ (ie.translate_to_original (2).first, tl::testsrc () + "/testdata/tl/inc1.txt");
|
||||
EXPECT_EQ (ie.translate_to_original (2).second, 1);
|
||||
EXPECT_EQ (ie.translate_to_original (3).first, fn);
|
||||
EXPECT_EQ (ie.translate_to_original (3).second, 3);
|
||||
|
|
@ -60,21 +61,21 @@ TEST(2_single_include)
|
|||
|
||||
TEST(3_multi_include)
|
||||
{
|
||||
std::string fn = tl::testsrc () + "/testdata/lym/x_inc3.txt";
|
||||
std::string fn = tl::testsrc () + "/testdata/tl/x_inc3.txt";
|
||||
|
||||
std::string et;
|
||||
lym::IncludeExpander ie = lym::IncludeExpander::expand (fn, et);
|
||||
tl::IncludeExpander ie = tl::IncludeExpander::expand (fn, et);
|
||||
EXPECT_EQ (et, "A line\ninclude.3a\nincluded.2a\nincluded.2b\ninclude.3b\nAnother line\n");
|
||||
|
||||
EXPECT_EQ (lym::IncludeExpander::from_string (ie.to_string ()).to_string (), ie.to_string ());
|
||||
EXPECT_EQ (tl::IncludeExpander::from_string (ie.to_string ()).to_string (), ie.to_string ());
|
||||
|
||||
EXPECT_EQ (ie.translate_to_original (1).first, fn);
|
||||
EXPECT_EQ (ie.translate_to_original (1).second, 1);
|
||||
EXPECT_EQ (ie.translate_to_original (2).first, tl::testsrc () + "/testdata/lym/inc3.txt");
|
||||
EXPECT_EQ (ie.translate_to_original (2).first, tl::testsrc () + "/testdata/tl/inc3.txt");
|
||||
EXPECT_EQ (ie.translate_to_original (2).second, 1);
|
||||
EXPECT_EQ (ie.translate_to_original (3).first, tl::testsrc () + "/testdata/lym/inc2.txt");
|
||||
EXPECT_EQ (ie.translate_to_original (3).first, tl::testsrc () + "/testdata/tl/inc2.txt");
|
||||
EXPECT_EQ (ie.translate_to_original (3).second, 1);
|
||||
EXPECT_EQ (ie.translate_to_original (5).first, tl::testsrc () + "/testdata/lym/inc3.txt");
|
||||
EXPECT_EQ (ie.translate_to_original (5).first, tl::testsrc () + "/testdata/tl/inc3.txt");
|
||||
EXPECT_EQ (ie.translate_to_original (5).second, 3);
|
||||
EXPECT_EQ (ie.translate_to_original (6).first, fn);
|
||||
EXPECT_EQ (ie.translate_to_original (6).second, 3);
|
||||
|
|
@ -82,21 +83,21 @@ TEST(3_multi_include)
|
|||
|
||||
TEST(4_multi_include_interpolate)
|
||||
{
|
||||
std::string fn = tl::testsrc () + "/testdata/lym/x_inc3_ip.txt";
|
||||
std::string fn = tl::testsrc () + "/testdata/tl/x_inc3_ip.txt";
|
||||
|
||||
std::string et;
|
||||
lym::IncludeExpander ie = lym::IncludeExpander::expand (fn, et);
|
||||
tl::IncludeExpander ie = tl::IncludeExpander::expand (fn, et);
|
||||
EXPECT_EQ (et, "A line\ninclude.3a\nincluded.2a\nincluded.2b\ninclude.3b\nAnother line\n");
|
||||
|
||||
EXPECT_EQ (lym::IncludeExpander::from_string (ie.to_string ()).to_string (), ie.to_string ());
|
||||
EXPECT_EQ (tl::IncludeExpander::from_string (ie.to_string ()).to_string (), ie.to_string ());
|
||||
|
||||
EXPECT_EQ (ie.translate_to_original (1).first, fn);
|
||||
EXPECT_EQ (ie.translate_to_original (1).second, 1);
|
||||
EXPECT_EQ (ie.translate_to_original (2).first, tl::testsrc () + "/testdata/lym/inc3.txt");
|
||||
EXPECT_EQ (ie.translate_to_original (2).first, tl::testsrc () + "/testdata/tl/inc3.txt");
|
||||
EXPECT_EQ (ie.translate_to_original (2).second, 1);
|
||||
EXPECT_EQ (ie.translate_to_original (3).first, tl::testsrc () + "/testdata/lym/inc2.txt");
|
||||
EXPECT_EQ (ie.translate_to_original (3).first, tl::testsrc () + "/testdata/tl/inc2.txt");
|
||||
EXPECT_EQ (ie.translate_to_original (3).second, 1);
|
||||
EXPECT_EQ (ie.translate_to_original (5).first, tl::testsrc () + "/testdata/lym/inc3.txt");
|
||||
EXPECT_EQ (ie.translate_to_original (5).first, tl::testsrc () + "/testdata/tl/inc3.txt");
|
||||
EXPECT_EQ (ie.translate_to_original (5).second, 3);
|
||||
EXPECT_EQ (ie.translate_to_original (6).first, fn);
|
||||
EXPECT_EQ (ie.translate_to_original (6).second, 3);
|
||||
|
|
@ -15,6 +15,7 @@ SOURCES = \
|
|||
tlEvents.cc \
|
||||
tlExpression.cc \
|
||||
tlFileUtils.cc \
|
||||
tlIncludeTests.cc \
|
||||
tlIntervalMap.cc \
|
||||
tlIntervalSet.cc \
|
||||
tlKDTree.cc \
|
||||
|
|
|
|||
Binary file not shown.
Loading…
Reference in New Issue