aboutsummaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
authorRobin Haberkorn <robin.haberkorn@googlemail.com>2012-11-24 17:56:29 +0100
committerRobin Haberkorn <robin.haberkorn@googlemail.com>2012-11-24 17:56:29 +0100
commitfad826dcfe095d57aa5faf6cc8a863069f65b0d6 (patch)
tree729df2493b9a56a023ac04868bb5069451e27f45
parent0e536bd36250419698fe884d01d5997581241d93 (diff)
downloadsciteco-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--Makefile9
-rw-r--r--parser.cpp111
-rw-r--r--parser.h33
-rwxr-xr-xsymbols-extract.tes17
-rw-r--r--symbols.cpp17
-rw-r--r--symbols.h4
-rw-r--r--teco.ini56
7 files changed, 172 insertions, 75 deletions
diff --git a/Makefile b/Makefile
index 361f966..9c7123b 100644
--- a/Makefile
+++ b/Makefile
@@ -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)
diff --git a/parser.cpp b/parser.cpp
index d84f1b6..a94f7dd 100644
--- a/parser.cpp
+++ b/parser.cpp
@@ -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;
}
diff --git a/parser.h b/parser.h
index 79f9219..c21f872 100644
--- a/parser.h
+++ b/parser.h
@@ -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;
diff --git a/symbols.h b/symbols.h
index 735fdda..a603b3b 100644
--- a/symbols.h
+++ b/symbols.h
@@ -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
diff --git a/teco.ini b/teco.ini
index 2925b53..01de669 100644
--- a/teco.ini
+++ b/teco.ini
@@ -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