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 | |
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
-rw-r--r-- | Makefile | 9 | ||||
-rw-r--r-- | parser.cpp | 111 | ||||
-rw-r--r-- | parser.h | 33 | ||||
-rwxr-xr-x | symbols-extract.tes | 17 | ||||
-rw-r--r-- | symbols.cpp | 17 | ||||
-rw-r--r-- | symbols.h | 4 | ||||
-rw-r--r-- | teco.ini | 56 |
7 files changed, 172 insertions, 75 deletions
@@ -59,7 +59,8 @@ MINIMAL_OBJS:=main.o cmdline.o undo.o expressions.o qbuffers.o \ all : sciteco -sciteco : $(MINIMAL_OBJS) symbols-scintilla.o +sciteco : $(MINIMAL_OBJS) \ + symbols-scintilla.o symbols-scilexer.o $(CXX) -o $@ $^ $(LDFLAGS) sciteco-minimal : $(MINIMAL_OBJS) @@ -67,7 +68,11 @@ sciteco-minimal : $(MINIMAL_OBJS) symbols-scintilla.cpp : $(SCI_DIR)/include/Scintilla.h \ sciteco-minimal symbols-extract.tes - ./sciteco-minimal -m symbols-extract.tes $< $@ SCI_ scintilla + ./sciteco-minimal -m symbols-extract.tes $< $@ "SCI_" scintilla + +symbols-scilexer.cpp : $(SCI_DIR)/include/SciLexer.h \ + sciteco-minimal symbols-extract.tes + ./sciteco-minimal -m symbols-extract.tes $< $@ "SCLEX_,SCE_" scilexer ifeq ($(INTERFACE),GTK) @@ -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; } @@ -117,10 +117,12 @@ class StateExpectString : public State { gint nesting; bool string_building; + bool last; public: - StateExpectString(bool _building = true) - : State(), nesting(1), string_building(_building) {} + StateExpectString(bool _building = true, bool _last = true) + : State(), nesting(1), + string_building(_building), last(_last) {} private: gchar *machine_input(gchar key) throw (Error); @@ -202,7 +204,15 @@ private: State *custom(gchar chr) throw (Error); }; -class StateScintilla : public StateExpectString { +class StateScintilla_symbols : public StateExpectString { +public: + StateScintilla_symbols() : StateExpectString(true, false) {} + +private: + State *done(const gchar *str) throw (Error); +}; + +class StateScintilla_lParam : public StateExpectString { private: State *done(const gchar *str) throw (Error); }; @@ -241,14 +251,15 @@ private: }; namespace States { - extern StateStart start; - extern StateControl control; - extern StateFlowCommand flowcommand; - extern StateCondCommand condcommand; - extern StateECommand ecommand; - extern StateScintilla scintilla; - extern StateInsert insert; - extern StateSearch search; + extern StateStart start; + extern StateControl control; + extern StateFlowCommand flowcommand; + extern StateCondCommand condcommand; + extern StateECommand ecommand; + extern StateScintilla_symbols scintilla_symbols; + extern StateScintilla_lParam scintilla_lparam; + extern StateInsert insert; + extern StateSearch search; extern State *current; } diff --git a/symbols-extract.tes b/symbols-extract.tes index 08ab2d7..6497324 100755 --- a/symbols-extract.tes +++ b/symbols-extract.tes @@ -1,10 +1,10 @@ #!./sciteco-minimal -m -! ./symbols-extract.tes <input file> <output file> <prefix> <array name> ! +! ./symbols-extract.tes <input file> <output file> <prefix pattern list> <array name> ! ! <pos1,pos2>Mc - Compare string at pos1 with string at pos2 ! @^Uc{ U.2U.1 -.%.1^[ -.%.2^[ - <Q.1A-(Q.2A)U.c Q.1A"A|Q.2A"A|;'' Q.c"N;' %.1^[%.2> + <Q.1A-(Q.2A)U.c Q.1A"C|Q.2A"C|;'' Q.c"N;' %.1^[%.2> Q.c } @@ -44,7 +44,7 @@ LR 0Xi 2LR 0Xo 2LR 0Xp 2LR 0Xn HK ! copy all defines in input file beginning with prefix ! -EBQi <S#define^SQp; :Xa> EF +EBQi <S#defineS[Qp]; -SS :Xa> EF ! sort all defines ! Ga ZJB 0,.Mq J @@ -61,13 +61,12 @@ I/* static const SymbolList::Entry entries[] = { < - .,W.Xa 0K - I#ifdef QpQa + .,W.Xa 0KK + I#ifdef Qa + {"Qa", ^EQa}, +#endif - ^I{"Qa", V I ^EQp^EQa}, -#endif - L .-Z; -> +.-Z;> I}; /* overwrites weak object in symbols.cpp */ diff --git a/symbols.cpp b/symbols.cpp index c123ebc..8e81354 100644 --- a/symbols.cpp +++ b/symbols.cpp @@ -1,3 +1,5 @@ +#include <string.h> + #include <glib.h> #include "symbols.h" @@ -7,6 +9,7 @@ */ namespace Symbols { SymbolList __attribute__((weak)) scintilla; + SymbolList __attribute__((weak)) scilexer; } /* @@ -14,14 +17,24 @@ namespace Symbols { * binary search. */ gint -SymbolList::lookup(const gchar *name) +SymbolList::lookup(const gchar *name, const gchar *prefix, bool case_sensitive) { + int (*cmp_fnc)(const char *, const char *, size_t); + gint prefix_skip = strlen(prefix); + gint name_len = strlen(name); + gint left = 0; gint right = size - 1; + cmp_fnc = case_sensitive ? strncmp : g_ascii_strncasecmp; + + if (!cmp_fnc(name, prefix, prefix_skip)) + prefix_skip = 0; + while (left <= right) { gint cur = left + (right-left)/2; - gint cmp = g_strcmp0(entries[cur].name, name); + gint cmp = cmp_fnc(entries[cur].name + prefix_skip, + name, name_len + 1); if (!cmp) return entries[cur].value; @@ -18,12 +18,14 @@ public: SymbolList(const Entry *_entries = NULL, gint _size = 0) : entries(_entries), size(_size) {} - gint lookup(const gchar *name); + gint lookup(const gchar *name, const gchar *prefix = "", + bool case_sensitive = false); GList *get_glist(void); }; namespace Symbols { extern SymbolList __attribute__((weak)) scintilla; + extern SymbolList __attribute__((weak)) scilexer; } #endif @@ -13,32 +13,34 @@ ! <bold,bg,fg,style>M.r ! @.r{ U.sU.vU.bU.h - Q.v:M.c,Q.s,2051ES - Q.b:M.c,Q.s,2052ES - Q.h,Q.s,2053ES + Q.v:M.c,Q.sESSTYLESETFORE + Q.b:M.c,Q.sESSTYLESETBACK + Q.h,Q.sESSTYLESETBOLD } ZJ -:S.[cpp,c,h]"S Z-."= EBQ.f - 3,4001ES - 0,4005ESand and_eq asm auto bitand bitor bool break - case catch char class compl const const_cast continue - default delete do double dynamic_cast else enum explicit export extern false float for - friend goto if inline int long mutable namespace new not not_eq - operator or or_eq private protected public - register reinterpret_cast return short signed sizeof static static_cast struct switch - template this throw true try typedef typeid typename union unsigned using - virtual void volatile wchar_t while xor xor_eq - 2,4005ESa addindex addtogroup anchor arg attention - author b brief bug c class code date def defgroup deprecated dontinclude - e em endcode endhtmlonly endif endlatexonly endlink endverbatim enum example exception - f$ f[ f] file fn hideinitializer htmlinclude htmlonly - if image include ingroup internal invariant interface latexonly li line link - mainpage name namespace nosubgrouping note overload - p page par param post pre ref relates remarks return retval - sa section see showinitializer since skip skipline struct subsection - test throw todo typedef union until - var verbatim verbinclude version warning weakgroup $ @ \ & < > # { } + ESSETLEXER,SCLEX_CPP + 0ESSETKEYWORDS + and and_eq asm auto bitand bitor bool break + case catch char class compl const const_cast continue + default delete do double dynamic_cast else enum explicit export extern false float for + friend goto if inline int long mutable namespace new not not_eq + operator or or_eq private protected public + register reinterpret_cast return short signed sizeof static static_cast struct switch + template this throw true try typedef typeid typename union unsigned using + virtual void volatile wchar_t while xor xor_eq + 2ESSETKEYWORDS + a addindex addtogroup anchor arg attention + author b brief bug c class code date def defgroup deprecated dontinclude + e em endcode endhtmlonly endif endlatexonly endlink endverbatim enum example exception + f$ f[ f] file fn hideinitializer htmlinclude htmlonly + if image include ingroup internal invariant interface latexonly li line link + mainpage name namespace nosubgrouping note overload + p page par param post pre ref relates remarks return retval + sa section see showinitializer since skip skipline struct subsection + test throw todo typedef union until + var verbatim verbinclude version warning weakgroup $ @ \ & < > # { } ! Whitespace ! 0,0,2,0:M.r ! Comments ! 0,0,2,1:M.r 0,0,2,2:M.r 1,0,2,3:M.r ! Number ! 0,0,1,4:M.r @@ -52,8 +54,8 @@ ZJ -:Smakefile"S Z-."= EBQ.f - 11,4001ES - 0,4005ESifeq else endif + ESSETLEXER,SCLEX_MAKEFILE + 0ESSETKEYWORDSifeq else endif ! Default ! 0,0,7,0:M.r ! Comments ! 0,0,2,1:M.r ! Preprocessor ! 0,0,4,2:M.r @@ -79,9 +81,9 @@ ED#32ED ! margins ! -5,0,2242ES -0,1,2242ES -1,2,2242ES +5,0ESSETMARGINWIDTHN +0,1ESSETMARGINWIDTHN +1,2ESSETMARGINWIDTHN ! open all files specified on the commandline ! [.f |