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()),

Reply via email to