hello all,
at last i managed to send the patch for the command macros. i added a recursive call prevention and
created a patch for the latest revision.
and here is my problem:
after updating trunk msvc cannot compile lyx any longer. i get around 180 error messages for the
projects 'frontend_qt4' and 'lyx' about missing pch files:
GuiEmbeddedFiles.cpp
..\..\..\..\trunk\src\frontends\qt4\GuiEmbeddedFiles.cpp(11) : fatal error C1083: Cannot open
precompiled header file: 'frontend_qt4.dir\Debug/config.pch': No such file or directory
LengthCombo.cpp
..\..\..\..\trunk\src\frontends\qt4\LengthCombo.cpp(12) : fatal error C1083: Cannot open precompiled
header file: 'frontend_qt4.dir\Debug/config.pch': No such file or directory
i use the following commands for generation of the project files and it allways
worked until now:
set PATH=d:\lyx\trunk\lyx-windows-deps-msvc-qt4\qt-4\bin;%PATH%
cmake ..\trunk\development\cmake -DWINDEPS=1
thus i was not able to test the patch in the latest trunk.
bernhard
Index: src/frontends/qt4/GuiToolbar.cpp
===================================================================
--- src/frontends/qt4/GuiToolbar.cpp (revision 20821)
+++ src/frontends/qt4/GuiToolbar.cpp (working copy)
@@ -446,6 +446,9 @@
case LFUN_MATH_BIGDELIM:
fullname = find_png(to_utf8(f.argument()));
break;
+ case LFUN_CALL:
+ fullname = libFileSearch("images", to_utf8(f.argument()),
"png").absFilename();
+ break;
default:
string const name = lyxaction.getActionName(f.action);
string png_name = name;
Index: src/KeyMap.cpp
===================================================================
--- src/KeyMap.cpp (revision 20821)
+++ src/KeyMap.cpp (working copy)
@@ -77,12 +77,14 @@
enum BindTags {
BN_BIND,
- BN_BINDFILE
+ BN_BINDFILE,
+ BN_DEFINE
};
keyword_item bindTags[] = {
{ "\\bind", BN_BIND },
- { "\\bind_file", BN_BINDFILE }
+ { "\\bind_file", BN_BINDFILE },
+ { "\\define", BN_DEFINE }
};
}
@@ -115,6 +117,42 @@
continue;
case Lexer::LEX_FEOF:
continue;
+ case BN_DEFINE:
+ {
+ string name, def;
+
+ if (lexrc.next()) {
+ name = lexrc.getString();
+ } else {
+ lexrc.printError("BN_DEFINE: Missing macro
name");
+ error = true;
+ break;
+ }
+
+ if (lexrc.next(true)) {
+ def = lexrc.getString();
+ } else {
+ lexrc.printError("BN_DEFINE: missing macro
definition");
+ error = true;
+ break;
+ }
+
+ LyXAction::new_macro_error e = lyxaction.newMacro(name,
def);
+ switch (e) {
+ case LyXAction::MacroNameEmpty:
+ lexrc.printError("BN_DEFINE: Macro name
is empty");
+ error = true;
+ case LyXAction::MacroExists:
+ lexrc.printError("BN_DEFINE: Macro
already defined");
+ error = true;
+ case LyXAction::MacroDefInvalid:
+ lexrc.printError("BN_DEFINE: Macro
definition is not valid");
+ error = true;
+ break;
+ }
+
+ break;
+ }
case BN_BIND:
{
string seq, cmd;
Index: src/lfuns.h
===================================================================
--- src/lfuns.h (revision 20821)
+++ src/lfuns.h (working copy)
@@ -403,9 +403,10 @@
LFUN_LAYOUT_MODULES_CLEAR, // rgh, 20070825
LFUN_LAYOUT_MODULE_ADD, // rgh, 20070825
LFUN_LAYOUT_RELOAD, // rgh, 20070903
- LFUN_MASTER_BUFFER_VIEW, // Tommaso, 20070920
+ LFUN_MASTER_BUFFER_VIEW, // Tommaso, 20070920
// 295
LFUN_MASTER_BUFFER_UPDATE, // Tommaso, 20070920
+ LFUN_CALL, // broider, 20071002
LFUN_LASTACTION // end of the table
};
Index: src/LyXAction.cpp
===================================================================
--- src/LyXAction.cpp (revision 20821)
+++ src/LyXAction.cpp (working copy)
@@ -53,6 +53,38 @@
LyXAction lyxaction;
+/// information for a macro
+struct LyXAction::macro_info {
+ /// the expanded FuncRequest
+ FuncRequest func;
+ /// to avoid recursive calls
+ bool locked;
+};
+
+LyXAction::new_macro_error LyXAction::newMacro(string const & name, string
const & def)
+{
+ string const name2 = trim(name);
+
+ if (!name2.length()) return MacroNameEmpty;
+
+ if (lyx_macro_map.find(name) != lyx_macro_map.end()) {
+ return MacroExists;
+ }
+
+ FuncRequest func = lookupFunc(def);
+ if (func.action == LFUN_NOACTION ||
+ func.action == LFUN_UNKNOWN_ACTION) {
+ return MacroDefInvalid;
+ }
+
+ macro_info * info = new macro_info;
+ info->func = func;
+ info->locked = false;
+ lyx_macro_map[name] = info;
+ return MacroOk;
+}
+
+
void LyXAction::newFunc(kb_action action, string const & name,
unsigned int attrib)
{
@@ -145,6 +177,7 @@
{ LFUN_COMMAND_EXECUTE, "command-execute", NoBuffer },
{ LFUN_COMMAND_PREFIX, "command-prefix", NoBuffer },
{ LFUN_COMMAND_SEQUENCE, "command-sequence", NoBuffer },
+ { LFUN_CALL, "call", NoBuffer | ReadOnly},
{ LFUN_COPY, "copy", ReadOnly },
{ LFUN_CUT, "cut", Noop },
{ LFUN_DATE_INSERT, "date-insert", Noop },
@@ -395,6 +428,16 @@
}
+LyXAction::~LyXAction()
+{
+ macro_map::iterator pos = lyx_macro_map.begin();
+ while (pos != lyx_macro_map.end()) {
+ delete pos->second;
+ ++pos;
+ }
+}
+
+
// Returns an action tag from a string.
FuncRequest LyXAction::lookupFunc(string const & func) const
{
@@ -413,6 +456,53 @@
}
+// lock a macro and get the associated action
+bool LyXAction::lockMacro(string const & name, FuncRequest &func)
+{
+ string const name2 = trim(name);
+
+ if (name2.empty()) {
+ func = FuncRequest(LFUN_NOACTION);
+ return true;
+ }
+
+ macro_map::const_iterator mit = lyx_macro_map.find(name2);
+
+ if (mit == lyx_macro_map.end()) {
+ func = FuncRequest(LFUN_UNKNOWN_ACTION);
+ return true;
+ }
+
+ if (mit->second->locked) {
+ func = FuncRequest(LFUN_NOACTION);
+ return false;
+ }
+
+ mit->second->locked = true;
+ func = mit->second->func;
+ return true;
+}
+
+
+// release a macro lock
+void LyXAction::releaseMacro(string const & name)
+{
+ string const name2 = trim(name);
+
+ if (name2.empty()) {
+ return;
+ }
+
+ macro_map::const_iterator mit = lyx_macro_map.find(name2);
+
+ if (mit == lyx_macro_map.end()) {
+ return;
+ }
+
+ mit->second->locked = false;
+}
+
+
string const LyXAction::getActionName(kb_action action) const
{
info_map::const_iterator const it = lyx_info_map.find(action);
Index: src/LyXAction.h
===================================================================
--- src/LyXAction.h (revision 20821)
+++ src/LyXAction.h (working copy)
@@ -42,6 +42,11 @@
unsigned int attrib;
};
+ /// information for a macro
+ struct macro_info;
+
+ /// type for map between a macro name and its info
+ typedef std::map<std::string, macro_info*> macro_map;
public:
/// type for map between a function name and its action
typedef std::map<std::string, kb_action> func_map;
@@ -58,7 +63,16 @@
SingleParUpdate = 16 //< Usually only requires this par updated
};
+ /// possible reasons for not allowed macros
+ enum new_macro_error {
+ MacroOk,
+ MacroNameEmpty,
+ MacroDefInvalid,
+ MacroExists
+ };
+
LyXAction();
+ ~LyXAction();
/**
* Returns an pseudoaction from a string
@@ -67,6 +81,11 @@
*/
FuncRequest lookupFunc(std::string const & func_name) const;
+ /// lock and retieve the macro
+ bool lockMacro(std::string const & macro_name, FuncRequest &func);
+ /// release the macro
+ void releaseMacro(std::string const & macro_name);
+
/// Return the name (and argument) associated with the given (pseudo)
action
std::string const getActionName(kb_action action) const;
@@ -82,6 +101,9 @@
/// return an iterator to the end of all real actions
const_func_iterator func_end() const;
+ /// add a new macro
+ new_macro_error newMacro(std::string const & name, std::string const &
def);
+
private:
/// populate the action container with our actions
void init();
@@ -101,6 +123,9 @@
* command attributes (ro)
*/
info_map lyx_info_map;
+
+ /// This is a list of all the macros with the coresponding expansion.
+ macro_map lyx_macro_map;
};
/// singleton instance
Index: src/LyXFunc.cpp
===================================================================
--- src/LyXFunc.cpp (revision 20821)
+++ src/LyXFunc.cpp (working copy)
@@ -701,8 +701,25 @@
FuncRequest func(lyxaction.lookupFunc(firstcmd));
func.origin = cmd.origin;
flag = getStatus(func);
+ break;
}
+ case LFUN_CALL: {
+ FuncRequest func;
+ std::string name(to_utf8(cmd.argument()));
+ if (lyxaction.lockMacro(name, func)) {
+ func.origin = cmd.origin;
+ flag = getStatus(func);
+ lyxaction.releaseMacro(name);
+ } else {
+ // catch recursion
+ // all operations until the recursion occures are
performed, so
+ // set the state to enabled
+ enable = true;
+ }
+ break;
+ }
+
case LFUN_BUFFER_NEW:
case LFUN_BUFFER_NEW_TEMPLATE:
case LFUN_WORD_FIND_FORWARD:
@@ -1632,6 +1649,21 @@
break;
}
+ case LFUN_CALL: {
+ FuncRequest func;
+ if (lyxaction.lockMacro(argument, func)) {
+ func.origin = cmd.origin;
+ dispatch(func);
+ lyxaction.releaseMacro(argument);
+ } else {
+ // recursion detected
+ lyxerr << "Warning: Recursion in the macro '"
+ << argument << " detected"
+ << endl;
+ }
+ break;
+ }
+
case LFUN_PREFERENCES_SAVE: {
lyxrc.write(makeAbsPath("preferences",
package().user_support().absFilename()),