diff options
author | Robin Haberkorn <robin.haberkorn@googlemail.com> | 2012-11-24 17:56:29 +0100 |
---|---|---|
committer | Robin Haberkorn <robin.haberkorn@googlemail.com> | 2012-11-24 17:56:29 +0100 |
commit | fad826dcfe095d57aa5faf6cc8a863069f65b0d6 (patch) | |
tree | 729df2493b9a56a023ac04868bb5069451e27f45 /parser.cpp | |
parent | 0e536bd36250419698fe884d01d5997581241d93 (diff) | |
download | sciteco-fad826dcfe095d57aa5faf6cc8a863069f65b0d6.tar.gz |
allow symbolic names (symbols) being specified for the scintilla (ES) command
* new syntax is <[lParam,[wParam,[msg]]]>ES[msg[,wParam[,lParam]]]$[lParam string]$
* symbols are matched case-insensitive, the leading SCI_ for message symbols may be omitted
* added support for more multiple string arguments (for commands in general)
* fixed "C conditional: succeeds for every alpanumeric character, dot, dollar or underscore
* added SCLEX_ and SCE_ constants as symbols
* updated teco.ini: using symbolic names is preferred since that way code does not depend on the current Scintilla version
Diffstat (limited to 'parser.cpp')
-rw-r--r-- | parser.cpp | 111 |
1 files changed, 88 insertions, 23 deletions
@@ -12,6 +12,7 @@ #include "goto.h" #include "qbuffers.h" #include "parser.h" +#include "symbols.h" //#define DEBUG @@ -23,7 +24,8 @@ namespace States { StateFlowCommand flowcommand; StateCondCommand condcommand; StateECommand ecommand; - StateScintilla scintilla; + StateScintilla_symbols scintilla_symbols; + StateScintilla_lParam scintilla_lparam; StateInsert insert; StateSearch search; @@ -335,12 +337,15 @@ StateExpectString::custom(gchar chr) throw (Error) * String termination handling */ if (Modifiers::at) { - undo.push_var(Modifiers::at); - Modifiers::at = false; - undo.push_var(escape_char); - escape_char = g_ascii_toupper(chr); + if (last) + undo.push_var(Modifiers::at) = false; - return this; + switch (escape_char) { + case '\x1B': + case '{': + undo.push_var(escape_char) = g_ascii_toupper(chr); + return this; + } } if (escape_char == '{') { @@ -362,10 +367,10 @@ StateExpectString::custom(gchar chr) throw (Error) if (!nesting) { State *next; gchar *string = strings[0]; - undo.push_str(strings[0]); - strings[0] = NULL; - undo.push_var(escape_char); - escape_char = '\x1B'; + + undo.push_str(strings[0]) = NULL; + if (last) + undo.push_var(escape_char) = '\x1B'; nesting = 1; if (string_building) { @@ -1109,8 +1114,8 @@ StateCondCommand::custom(gchar chr) throw (Error) break; case 'C': BEGIN_EXEC(&States::start); - /* FIXME */ - result = g_ascii_isalnum((gchar)value); + result = g_ascii_isalnum((gchar)value) || + value == '.' || value == '$' || value == '_'; break; case 'D': BEGIN_EXEC(&States::start); @@ -1239,7 +1244,7 @@ StateECommand::StateECommand() : State() { transitions['\0'] = this; transitions['B'] = &States::editfile; - transitions['S'] = &States::scintilla; + transitions['S'] = &States::scintilla_symbols; transitions['Q'] = &States::eqcommand; transitions['W'] = &States::savefile; } @@ -1293,24 +1298,84 @@ StateECommand::custom(gchar chr) throw (Error) return &States::start; } -State * -StateScintilla::done(const gchar *str) throw (Error) -{ +static struct ScintillaMessage { unsigned int iMessage; uptr_t wParam; sptr_t lParam; +} scintilla_message = {0, 0, 0}; - BEGIN_EXEC(&States::start); +State * +StateScintilla_symbols::done(const gchar *str) throw (Error) +{ + BEGIN_EXEC(&States::scintilla_lparam); + + undo.push_var(scintilla_message); + if (*str) { + gchar **symbols = g_strsplit(str, ",", -1); + gint64 v; + + if (!symbols[0]) + goto cleanup; + if (*symbols[0]) { + v = Symbols::scintilla.lookup(symbols[0], "SCI_"); + if (v < 0) + throw Error("Unknown Scintilla message symbol \"%s\"", + symbols[0]); + scintilla_message.iMessage = v; + } + + if (!symbols[1]) + goto cleanup; + if (*symbols[1]) { + v = Symbols::scilexer.lookup(symbols[1]); + if (v < 0) + throw Error("Unknown Scintilla Lexer symbol \"%s\"", + symbols[1]); + scintilla_message.wParam = v; + } + + if (!symbols[2]) + goto cleanup; + if (*symbols[2]) { + v = Symbols::scilexer.lookup(symbols[2]); + if (v < 0) + throw Error("Unknown Scintilla Lexer symbol \"%s\"", + symbols[2]); + scintilla_message.lParam = v; + } + +cleanup: + g_strfreev(symbols); + } expressions.eval(); - if (!expressions.args()) - throw Error("<ES> command requires at least a message code"); + if (!scintilla_message.iMessage) { + if (!expressions.args()) + throw Error("<ES> command requires at least a message code"); + + scintilla_message.iMessage = expressions.pop_num_calc(1, 0); + } + if (!scintilla_message.wParam) + scintilla_message.wParam = expressions.pop_num_calc(1, 0); + + return &States::scintilla_lparam; +} + +State * +StateScintilla_lParam::done(const gchar *str) throw (Error) +{ + BEGIN_EXEC(&States::start); + + if (!scintilla_message.lParam) + scintilla_message.lParam = *str ? (sptr_t)str + : expressions.pop_num_calc(1, 0); - iMessage = expressions.pop_num_calc(1, 0); - wParam = expressions.pop_num_calc(1, 0); - lParam = *str ? (sptr_t)str : expressions.pop_num_calc(1, 0); + expressions.push(interface.ssm(scintilla_message.iMessage, + scintilla_message.wParam, + scintilla_message.lParam)); - expressions.push(interface.ssm(iMessage, wParam, lParam)); + undo.push_var(scintilla_message); + memset(&scintilla_message, 0, sizeof(scintilla_message)); return &States::start; } |