1 /* Bluefish HTML Editor 2 * bftextview2_private.h 3 * 4 * Copyright (C) 2012,2013,2014 Olivier Sessink 5 * 6 * This program is free software; you can redistribute it and/or modify 7 * it under the terms of the GNU General Public License as published by 8 * the Free Software Foundation; either version 3 of the License, or 9 * (at your option) any later version. 10 * 11 * This program is distributed in the hope that it will be useful, 12 * but WITHOUT ANY WARRANTY; without even the implied warranty of 13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 * GNU General Public License for more details. 15 * 16 * You should have received a copy of the GNU General Public License 17 * along with this program. If not, see <http://www.gnu.org/licenses/>. 18 */ 19 20 #ifndef _BFTEXTVIEW2_PRIVATE_H_ 21 #define _BFTEXTVIEW2_PRIVATE_H_ 22 23 #define CONDITIONALPATTERN 24 25 #if defined(__GNUC__) || (defined(__SUNPRO_C) && __SUNPRO_C > 0x580) 26 #define DBG_NONE(args...) 27 /**/ 28 #else /* notdef __GNUC__ || __SUNPRO_C */ 29 extern void g_none(char *first, ...); 30 #define DBG_NONE g_none 31 #endif 32 /**/ 33 34 #define BF_OFFSET_UNDEFINED G_MAXINT32 35 #define BF_POSITION_UNDEFINED G_MAXINT32 36 37 /*#define DUMP_CONTEXTS*/ 38 /*#define DUMP_PATTERNS*/ 39 /*#define DUMP_SCANCACHE*/ 40 /*#define DUMP_SCANCACHE_UPDATE_OFFSET*/ 41 /*#define CHECK_CONSISTENCY*/ 42 43 #define DBG_MSG DBG_NONE 44 #define DBG_SCANCACHE DBG_NONE 45 #define DBG_SCANNING DBG_NONE 46 #define DBG_BLOCKMATCH DBG_NONE 47 #define DBG_PATCOMPILE DBG_NONE 48 #define DBG_SIGNALS DBG_NONE 49 #define DBG_AUTOCOMP DBG_NONE 50 #define DBG_DELAYSCANNING DBG_NONE 51 #define DBG_FOLD DBG_NONE 52 #define DBG_MARGIN DBG_NONE 53 #define DBG_PARSING DBG_NONE 54 #define DBG_TOOLTIP DBG_NONE 55 #define DBG_SPELL DBG_NONE 56 #define DBG_IDENTIFIER DBG_NONE 57 #define DBG_MARKREGION DBG_NONE 58 59 #ifdef UPDATE_OFFSET_DELAYED 60 #include "bf_lib.h" 61 typedef struct { 62 BF_ELIST_HEAD; 63 guint32 startpos; 64 gint32 offset; 65 } Toffsetupdate; 66 #define OFFSETUPDATE(var) ((Toffsetupdate *)var) 67 #endif /*UPDATE_OFFSET_DELAYED*/ 68 69 #define NUMSCANCHARS 127 /* 128 is ascii, but the last character is never scanned (DEL) 70 and the Ttablerow has one more 16bit value. By setting this to 127 instead of 128 71 we dont need padding to align the Ttablerow in memory 72 (Ttablerow = (127+1)*16=2048 bits or 256 bytes) */ 73 /*****************************************************************/ 74 /* building the automata and autocompletion cache */ 75 /*****************************************************************/ 76 #define COMMENT_INDEX_INHERIT 255 77 #define COMMENT_INDEX_NONE 254 78 #define SPELLCHECK_INHERIT 255 79 #define SPELLCHECK_ENABLED 1 80 #define SPELLCHECK_DISABLED 0 81 typedef struct { 82 GArray *table; /* a pointer to the DFA table for this context */ 83 GCompletion *ac; /* autocompletion items in this context */ 84 GHashTable *patternhash; /* a hash table where the pattern and its autocompletion strings are the keys, and an integer 85 to the ID of the pattern is the value. Only patterns that have backup cursor, a condition, or 86 a reference set are required in this hash. */ 87 GtkTextTag *contexttag; /* if the context area itself needs some kind of style (to implement a string context for example) */ 88 gchar *contexthighlight; /* the string that has the id for the highlight */ 89 guint8 has_tagclose_from_blockstack; /* this context has xml end patterns that need autoclosing for generix xml tags, based on the tag that is on top of the blockstack */ 90 guint8 comment_block; /* block comment index in array scantable->comments 91 or COMMENT_INDEX_INHERIT (which means inherit) 92 or COMMENT_INDEX_NONE if there is no block comment */ 93 guint8 comment_line; /* index in array scantable->comments for line comments; see comment_block */ 94 guint8 autocomplete_case_insens; 95 guint8 autocomplete_has_conditions; /* 0 means any autocomplete item is valid, 1 means we have to check for runtime conditions */ 96 guint8 default_spellcheck; 97 guint8 dump_dfa_run; 98 } Tcontext; 99 /* 100 32bit size = 5*32 + 7*8 = 208 + 8 padding bits = 28 bytes 101 64bit size = 5*64 + 7*8 = 368 + 8 padding bits = 48 bytes 102 */ 103 104 typedef struct { 105 gchar *refname; /* because we can match the name only after all contexts are loaded, we store it in the structure */ 106 guint16 ref; /* if the reference was a context, the ID of that context, if the reference 107 was a pattern, the ID of that pattern, otherwise 0 */ 108 gint8 parentrelation; /* -1 means any parent, 0 = direct parent, 1= grandparent, etc. */ 109 guint8 relationtype; /* 1 = valid if relation with context matches, 110 2 = invalid if relation with context matches, 111 3 = valid if relation with block matches 112 4 = invalid if relation with block matches 113 */ 114 } Tpattern_condition; 115 116 typedef struct { 117 gchar *autocomplete_string; 118 guint16 condition; /* 0 for most patterns, only blocks that are (in)valid in a certain condition have this set (refers to a Tpattern_condition) */ 119 guint8 autocomplete_backup_cursor; /* number of characters to backup the cursor after autocompletion (max 256) */ 120 guint8 trigger_new_autocomp_popup; /* if a new autocompletion popup should be triggered immediately after the text of 121 this one is inserted. Useful for example to autocomplete the values of an attribute 122 after an attribute has been inserted. */ 123 } Tpattern_autocomplete; 124 /* 125 32bit size = 32 + 16 + 2*8 = 64 + 0 padding bits = 8 bytes 126 64bit size = 64 + 16 + 2*8 = 96 + 32 padding bits = 16 bytes 127 */ 128 129 typedef struct { 130 gchar *name; 131 GtkTextTag *tag; /* if this pattern ends a context or a block, we can highlight 132 the region within the start and end pattern with this tag */ 133 gchar *highlight; /* a string for the highlight corresponding to the blocktag */ 134 gboolean foldable; 135 } Tpattern_block; 136 137 typedef struct { 138 GtkTextTag *selftag; /* the tag used to highlight this pattern */ 139 gchar *reference; /* the reference data, or NULL. may be inserted in hash tables for multiple keys in multiple contexts */ 140 gchar *pattern; /* the pattern itself. stored in the Tpattern so we can re-use it in another context */ 141 GSList *autocomp_items; /* a list of Tpattern_autocomplete - a pattern can autocomplete in multiple ways, for 142 example with and without closing tag, or with and without function arguments. 143 to be able to recompile a pattern in multiple contexts we need this information in Tpattern */ 144 gchar *selfhighlight; /* a string with the highlight for this pattern. used when re-linking highlights and textstyles 145 if the user changed any of these in the preferences */ 146 guint16 condition; /* 0 for most patterns, only blocks that are (in)valid in a certain condition have this set */ 147 guint16 block; /* this is 0 for most blocks, only blocks that need a tag have this set, refers to a a position in an array of Tpattern_block*/ 148 gint16 blockstartpattern; /* the number of the pattern that may start this block, or -1 to end the last started block, also used for stretch block */ 149 gint16 nextcontext; /* 0, or if this pattern starts a new context the number of the context, or -1 or -2 etc. 150 to pop a context of the stack */ 151 guint8 identmode :2; 152 guint8 identaction :2; /* 2 bits, first bit is add to jump hashtable, second bit is autocomplete */ 153 /* we use 1 bit integers here because these values are all booleans */ 154 guint8 starts_block :1; /* wether or not this pattern may start a block */ 155 guint8 ends_block :1; /* wether or not this pattern may end a block */ 156 guint8 tagclose_from_blockstack :1; /* this is a generix xml close tag that needs the blockstack to autoclose */ 157 guint8 stretch_blockstart :1; /* the end of this match is the new end-of-blockstart, used for HTML/XML tags */ 158 guint8 case_insens :1; 159 guint8 is_regex :1; 160 } Tpattern; 161 /* 162 32bit size = 5*32 + 4*16 + 2*2 + 6*1 = 234 + 22 padding bits = 32 bytes 163 64bit size = 5*64 + 4*16 + 2*2 + 6*1 = 394 + 54 padding bits = 56 bytes 164 */ 165 166 typedef struct { 167 guint16 row[NUMSCANCHARS]; /* contains for each character the number of the next state 168 because we use a 16bit unsigned number we can support only 65535 states 169 at maximum!!!!!!! but we use half the size of the scanning table, which 170 hopefully helps to keep the scanning table in the L2 cache of the CPU */ 171 guint16 match; /* 0 == no match, refers to the index number in array 'matches' */ 172 } Ttablerow; /* a row in the DFA, right now exactly 256 bytes */ 173 174 175 /*#define character_is_symbol(st,context,c) (g_array_index((GArray *)g_array_index(st->contexts, Tcontext, context).table, Ttablerow, 1).row[c] != 1)*/ 176 gboolean character_is_symbol(Tscantable *st,guint16 context, gunichar uc); 177 178 #define get_table(scantable, context) ((GArray *)g_array_index(scantable->contexts, Tcontext, context).table) 179 180 #define get_tablerow(scantable, context, curstate) (g_array_index(g_array_index(scantable->contexts, Tcontext, context).table, Ttablerow, curstate)) 181 182 /*****************************************************************/ 183 /* scanning the text and caching the results */ 184 /*****************************************************************/ 185 typedef struct { 186 gpointer parentfblock; 187 guint32 start1_o; 188 guint32 end1_o; 189 guint32 start2_o; 190 guint32 end2_o; 191 gint16 patternum; /* which pattern (number of the array element in scantable->matches) started the block */ 192 guint8 folded; 193 guint8 foldable; /* FALSE on a single line */ 194 } Tfoundblock; /* Once a start-of-block is found start1 and end1 are set 195 and the Tfoundblock is added to the foundcache. 196 The previous foundblock is set as parentfblock 197 so we can later on find what the current blockstack looks like. 198 Once the end-of-block is found, start2 and end2 are set 199 The Tfoundblock is popped as current block, and the parent 200 is active again. This is also put on the foundcache 201 202 on 64bit this type has size 8+4+4+4+4+2+1+1 + 4 padding = 32 bytes 203 on 32bit this type has size 4+4+4+4+4+2+1+1 NO padding = 24 bytes 204 */ 205 206 typedef struct { 207 gpointer parentfcontext; 208 guint32 start_o; 209 guint32 end_o; 210 gint16 context; /* number of the element in scantable->contexts */ 211 } Tfoundcontext; /* Once a start-of-context is found start is set 212 and the Tfoundcontext is added to the current foundcache. 213 The previous fcontext is set in parentfcontext 214 so we can later on find what the current contextstack looks like. 215 once the end-of-context is found, end is set 216 The Tfoundcontext is popped from the current stack and 217 this entry is also added to the foundcache 218 219 on 64bit this type has size 8+4+4+2 + 6 padding = 24 bytes 220 on 32bit this type has size 4+4+4+2 + 2 padding = 16 bytes 221 */ 222 223 typedef struct { 224 Tfoundcontext *fcontext; /* if numcontextchange == 0 this points to the current active context 225 if numcontextchange > 0 this points to the pushed context, which also happens to be the current context 226 if numcontextchange < 0 this points to the top of the stack at this position, to get the current position 227 you'll have to pop N items (where N is -1 * numcontextchange). */ 228 Tfoundblock *fblock; /* if numblockchange == 0 this points to the current active block 229 if numblockchange > 0 this points to the pushed block, which also happens to be the current block 230 if numblockchange < 0 this points to the top of the stack at this position, to get the current position 231 you'll have to pop N items (where N is -1 * numblockchange). */ 232 guint32 charoffset_o; 233 gint16 numblockchange; /* there are files that have > 127 pops in a single position 234 for example html files that don't close paragrahs or tablerows */ 235 gint8 numcontextchange; /* 0 means no change, 1 means 1 push, -2 means 2 popped etc. */ 236 } Tfound; /* 237 on 64bit this type has size 8+8+4+2+1 + 1 padding = 24 bytes 238 on 32bit this type has size 4+4+4+2+1 + 1 padding = 16 bytes 239 */ 240 241 #define IS_FOUNDMODE_CONTEXTPUSH(i) (i->numcontextchange > 0) 242 #define IS_FOUNDMODE_CONTEXTPOP(i) (i->numcontextchange < 0) 243 #define IS_FOUNDMODE_BLOCKPUSH(i) (i->numblockchange ==1) 244 #define IS_FOUNDMODE_BLOCKPOP(i) (i->numblockchange < 0) 245 246 #endif /* _BFTEXTVIEW2_PRIVATE_H_ */ 247