]> git.lyx.org Git - lyx.git/blob - src/CmdDef.cpp
ed7cdbb08767f71e11ae9ef0844af4a583924887
[lyx.git] / src / CmdDef.cpp
1 /**
2  * \file CmdDef.cpp
3  * This file is part of LyX, the document processor.
4  * Licence details can be found in the file COPYING.
5  *
6  * \author Bernhard Roider
7  *
8  * Full author contact details are available in file CREDITS.
9  */
10
11 #include <config.h>
12
13 #include "CmdDef.h"
14
15 #include "LyXAction.h"
16 #include "Lexer.h"
17
18 #include "support/debug.h"
19 #include "support/filetools.h"
20 #include "support/lstrings.h"
21
22 #include <ostream>
23
24 using std::endl;
25 using std::string;
26
27 namespace lyx {
28
29 using support::FileName;
30 using support::i18nLibFileSearch;
31 using support::trim;
32
33
34 namespace {
35
36 enum CmdDefTags {
37         BN_DEFFILE,
38         BN_DEFINE
39 };
40
41 keyword_item cmdDefTags[] = {
42         { "\\def_file", BN_DEFFILE },
43         { "\\define", BN_DEFINE }
44 };
45
46 }
47
48
49 bool CmdDef::read(string const & def_file)
50 {
51         const int cmdDefCount = sizeof(cmdDefTags) / sizeof(keyword_item);
52
53         Lexer lexrc(cmdDefTags, cmdDefCount);
54         if (lyxerr.debugging(Debug::PARSER))
55                 lexrc.printTable(lyxerr);
56
57         FileName const tmp(i18nLibFileSearch("commands", def_file, "def"));
58         lexrc.setFile(tmp);
59         if (!lexrc.isOK()) {
60                 lyxerr << "CmdDef::read: cannot open def file:"
61                        << tmp << endl;
62                 return false;
63         }
64
65         //LYXERR(Debug::KBMAP, "Reading def file:" << tmp);
66
67         bool error = false;
68         while (lexrc.isOK()) {
69                 switch (lexrc.lex()) {
70                 case Lexer::LEX_UNDEF:
71                         lexrc.printError("Unknown tag `$$Token'");
72                         error = true;
73                         continue;
74                 case Lexer::LEX_FEOF:
75                         continue;
76                 case BN_DEFINE:
77                 {
78                         string name, def;
79
80                         if (lexrc.next()) {
81                                 name = lexrc.getString();
82                         } else {
83                                 lexrc.printError("BN_DEFINE: Missing command name");
84                                 error = true;
85                                 break;
86                         }
87
88                         if (lexrc.next(true)) {
89                                 def = lexrc.getString();
90                         } else {
91                                 lexrc.printError("BN_DEFINE: missing command definition");
92                                 error = true;
93                                 break;
94                         }
95
96                         newCmdDefResult e = newCmdDef(name, def);
97                         switch (e) {
98                                 case CmdDefNameEmpty:
99                                         lexrc.printError("BN_DEFINE: Command name is empty");
100                                         error = true;
101                                         break;
102                                 case CmdDefExists:
103                                         lexrc.printError("BN_DEFINE: Command `" + name + "' already defined");
104                                         error = true;
105                                         break;
106                                 case CmdDefInvalid:
107                                         lexrc.printError("BN_DEFINE: Command definition for `" + name + "' is not valid");
108                                         error = true;
109                         }
110
111                         break;
112                 }
113                 case BN_DEFFILE:
114                         if (lexrc.next()) {
115                                 string const tmp(lexrc.getString());
116                                 error |= !read(tmp);
117                         } else {
118                                 lexrc.printError("BN_DEFFILE: Missing file name");
119                                 error = true;
120                                 break;
121
122                         }
123                         break;
124                 }
125         }
126
127         if (error)
128                 lyxerr << "CmdDef::read: error while reading def file:"
129                        << tmp << endl;
130         return !error;
131 }
132
133
134 bool CmdDef::lock(string const & name, FuncRequest & func)
135 {
136         if (cmdDefMap.empty())
137         {
138                 func = FuncRequest::unknown;
139                 return false;
140         }
141
142         string const name2 = trim(name);
143
144         CmdDefMap::const_iterator pos = cmdDefMap.find(name2);
145
146         if (pos == cmdDefMap.end()) 
147         {
148                 func = FuncRequest::unknown;
149                 return false;
150         }
151
152         if (pos->second->locked)
153         {
154                 func = FuncRequest::noaction;
155                 return false;
156         }
157
158         pos->second->locked = true;
159         func = pos->second->func;
160         return true;
161 }
162
163
164 void CmdDef::release(string const & name)
165 {
166         if (cmdDefMap.empty()) 
167                 return;
168
169         string const name2 = trim(name);
170
171         CmdDefMap::const_iterator pos = cmdDefMap.find(name2);
172
173         if (pos == cmdDefMap.end()) 
174                 return;
175
176         pos->second->locked = false;
177 }
178
179 CmdDef::newCmdDefResult CmdDef::newCmdDef(string const & name, 
180                                                                                   string const & def)
181 {
182         string const name2 = trim(name);
183
184         if (name2.empty()) 
185                 return CmdDefNameEmpty;
186
187         if (cmdDefMap.find(name) != cmdDefMap.end())
188                 return CmdDefExists;
189
190         FuncRequest     func = lyxaction.lookupFunc(def);
191         if (func.action == LFUN_NOACTION ||
192                 func.action == LFUN_UNKNOWN_ACTION) {
193                         return CmdDefInvalid;
194         }
195
196         boost::shared_ptr<CmdDefInfo> info;
197         info.reset(new CmdDefInfo(func));
198         cmdDefMap[name2] = info;
199
200         return CmdDefOk;
201 }
202
203
204 } // namespace lyx