]> git.pld-linux.org Git - packages/vim.git/blame - vim-ispell.patch
- now it works...
[packages/vim.git] / vim-ispell.patch
CommitLineData
41e3656f 1diff -ruN vim62./src/edit.c vim62/src/edit.c
2--- vim62./src/edit.c 2003-05-29 20:35:21.000000000 +0200
3+++ vim62/src/edit.c 2003-06-02 19:57:21.000000000 +0200
4@@ -656,7 +656,11 @@
98f80704 5 if ((c == Ctrl_V || c == Ctrl_Q) && ctrl_x_mode == CTRL_X_CMDLINE)
24ec98f0
JB
6 goto docomplete;
7 #endif
8- if (c == Ctrl_V || c == Ctrl_Q)
9+ if (c == Ctrl_V
10+#ifndef FEAT_SPELL_HL /* WM */
11+ || c == Ctrl_Q
12+#endif
13+ )
14 {
15 ins_ctrl_v();
16 c = Ctrl_V; /* pretend CTRL-V is last typed character */
41e3656f 17@@ -1222,6 +1226,20 @@
24ec98f0
JB
18 continue_status = 0;
19 break;
20 #endif /* FEAT_INS_EXPAND */
21+#ifdef FEAT_SPELL_HL /* WM */
22+ case Ctrl_Q:
23+ if(set_to_private_dict(
24+ ml_get_buf(curbuf, curwin->w_cursor.lnum, FALSE),
25+ curwin->w_cursor.col, FALSE))
26+ vim_beep();
27+ break;
28+ case Ctrl_S:
29+ if(set_to_private_dict(
30+ ml_get_buf(curbuf, curwin->w_cursor.lnum, FALSE),
31+ curwin->w_cursor.col, TRUE))
32+ vim_beep();
33+ break;
34+#endif
35
36 case Ctrl_Y: /* copy from previous line or scroll down */
37 case Ctrl_E: /* copy from next line or scroll up */
41e3656f 38diff -ruN vim62./src/eval.c vim62/src/eval.c
39--- vim62./src/eval.c 2003-05-30 21:11:19.000000000 +0200
40+++ vim62/src/eval.c 2003-06-02 19:57:21.000000000 +0200
41@@ -4864,6 +4864,9 @@
42 #ifdef FEAT_SNIFF
43 "sniff",
44 #endif
45+#ifdef FEAT_SPELL_HL
46+ "spell",
47+#endif
48 #ifdef FEAT_STL_OPT
49 "statusline",
50 #endif
51diff -ruN vim62./src/ex_cmds.h vim62/src/ex_cmds.h
52--- vim62./src/ex_cmds.h 2003-05-23 19:13:14.000000000 +0200
53+++ vim62/src/ex_cmds.h 2003-06-02 19:57:21.000000000 +0200
54@@ -712,6 +712,8 @@
24ec98f0 55 BANG|FILE1|TRLBAR|SBOXOK|CMDWIN),
24ec98f0
JB
56 EX(CMD_split, "split", ex_splitview,
57 BANG|FILE1|RANGE|NOTADR|EDITCMD|ARGOPT|TRLBAR),
27d8a8e1
MM
58+EX(CMD_spell, "spell", ex_spell,
59+ EXTRA|NOTRLCOM|CMDWIN),
24ec98f0 60 EX(CMD_sprevious, "sprevious", ex_previous,
27d8a8e1
MM
61 EXTRA|RANGE|NOTADR|COUNT|BANG|EDITCMD|ARGOPT|TRLBAR),
62 EX(CMD_srewind, "srewind", ex_rewind,
41e3656f 63diff -ruN vim62./src/ex_docmd.c vim62/src/ex_docmd.c
64--- vim62./src/ex_docmd.c 2003-05-24 19:31:40.000000000 +0200
65+++ vim62/src/ex_docmd.c 2003-06-02 19:57:21.000000000 +0200
66@@ -215,6 +215,9 @@
24ec98f0
JB
67 #ifndef FEAT_SYN_HL
68 # define ex_syntax ex_ni
69 #endif
70+#ifndef FEAT_SPELL_HL
71+# define ex_spell ex_ni
72+#endif
73 #ifndef FEAT_PERL
74 # define ex_perl ex_ni
75 # define ex_perldo ex_ni
41e3656f 76@@ -3079,6 +3082,12 @@
24ec98f0
JB
77 set_context_in_syntax_cmd(xp, arg);
78 break;
79 #endif
80+#ifdef FEAT_SPELL_HL
81+ case CMD_spell:
82+ return arg;
83+ break;
84+#endif
85+
86 #ifdef FEAT_EVAL
87 case CMD_let:
88 case CMD_if:
41e3656f 89diff -ruN vim62./src/feature.h vim62/src/feature.h
90--- vim62./src/feature.h 2003-05-25 19:44:49.000000000 +0200
91+++ vim62/src/feature.h 2003-06-02 19:57:21.000000000 +0200
92@@ -314,6 +314,11 @@
93 # define FEAT_RIGHTLEFT
24ec98f0 94 # endif
24ec98f0
JB
95 #endif
96+#ifdef FEAT_BIG
97+#undef FEAT_RIGHTLEFT
98+#undef FEAT_FKMAP
24ec98f0
JB
99+#endif
100+/* # define FEAT_PRINTER */
101
102 /*
41e3656f 103 * +arabic Arabic keymap and shaping support.
104diff -ruN vim62./src/globals.h vim62/src/globals.h
105--- vim62./src/globals.h 2003-05-28 20:24:00.000000000 +0200
106+++ vim62/src/globals.h 2003-06-02 19:57:21.000000000 +0200
107@@ -846,6 +846,9 @@
24ec98f0
JB
108 #ifdef USE_TERM_CONSOLE
109 EXTERN int term_console INIT(= FALSE); /* set to TRUE when console used */
110 #endif
111+#ifdef FEAT_SPELL_HL
112+EXTERN char_u hashname[MAXPATHL]; /* name of the dictionary */
113+#endif
114 EXTERN int termcap_active INIT(= FALSE); /* set by starttermcap() */
115 EXTERN int cur_tmode INIT(= TMODE_COOK); /* input terminal mode */
116 EXTERN int bangredo INIT(= FALSE); /* set to TRUE whith ! command */
41e3656f 117diff -ruN vim62./src/main.c vim62/src/main.c
118--- vim62./src/main.c 2003-05-29 11:20:15.000000000 +0200
119+++ vim62/src/main.c 2003-06-02 19:57:21.000000000 +0200
120@@ -2202,6 +2202,9 @@
24ec98f0
JB
121 }
122 }
123 #endif /* FEAT_VIMINFO */
124+#ifdef FEAT_SPELL_HL
125+ spell_save_private_dict();
126+#endif
127
128 #ifdef FEAT_AUTOCMD
129 apply_autocmds(EVENT_VIMLEAVE, NULL, NULL, FALSE, curbuf);
41e3656f 130diff -ruN vim62./src/Makefile vim62/src/Makefile
131--- vim62./src/Makefile 2003-06-01 15:18:29.000000000 +0200
132+++ vim62/src/Makefile 2003-06-02 20:02:03.000000000 +0200
133@@ -1156,6 +1156,22 @@
134 # Use this for cproto 3 patchlevel 7 or above (use "cproto -V" to check):
135 PROTO_FLAGS = -m -M__ARGS -d -E"$(CPP)" $(NO_ATTR)
136
137+SPELL_SRC = spell.c \
138+ spell/good.c \
139+ spell/lookup.c \
140+ spell/hash.c \
141+ spell/makedent.c \
142+ spell/tree.c \
143+ spell/tgood.c \
144+ spell/util.c
145+SPELL_OBJ = objects/spell.o \
146+ objects/good.o \
147+ objects/lookup.o \
148+ objects/hash.o \
149+ objects/makedent.o \
150+ objects/tree.o \
151+ objects/tgood.o \
152+ objects/util.o
153
154 ################################################
155 ## no changes required below this line ##
156@@ -1166,7 +1182,7 @@
157 .SUFFIXES:
158 .SUFFIXES: .cc .c .o .pro
159
160-PRE_DEFS = -Iproto $(DEFS) $(GUI_DEFS) $(GUI_IPATH) $(CPPFLAGS) $(EXTRA_IPATHS)
161+PRE_DEFS = -Iproto -Ispell $(DEFS) $(GUI_DEFS) $(GUI_IPATH) $(CPPFLAGS) $(EXTRA_IPATHS)
162 POST_DEFS = $(X_CFLAGS) $(PERL_CFLAGS) $(PYTHON_CFLAGS) $(TCL_CFLAGS) $(RUBY_CFLAGS) $(EXTRA_DEFS)
163
164 ALL_CFLAGS = $(PRE_DEFS) $(CFLAGS) $(PROFILE_CFLAGS) $(POST_DEFS)
165@@ -1248,6 +1264,7 @@
166 screen.c \
167 search.c \
168 syntax.c \
169+ $(SPELL_SRC) \
170 tag.c \
171 term.c \
172 ui.c \
173@@ -1314,6 +1331,7 @@
174 objects/screen.o \
175 objects/search.o \
176 objects/syntax.o \
177+ $(SPELL_OBJ) \
178 $(SNIFF_OBJ) \
179 objects/tag.o \
180 objects/term.o \
181@@ -2252,6 +2270,9 @@
182 objects/undo.o: undo.c
183 $(CCC) -o $@ undo.c
184
185+objects/spell.o: spell.c spell/local.h
186+ $(CCC) -o $@ spell.c
187+
188 objects/window.o: window.c
189 $(CCC) -o $@ window.c
190
191@@ -2410,6 +2431,9 @@
192 auto/osdef.h ascii.h keymap.h term.h macros.h structs.h regexp.h \
193 gui.h gui_beval.h proto/gui_beval.pro option.h ex_cmds.h proto.h \
194 globals.h farsi.h arabic.h
195+objects/spell.o: spell.c vim.h spell/config.h feature.h os_unix.h auto/osdef.h \
196+ ascii.h keymap.h term.h macros.h regexp.h structs.h gui.h globals.h farsi.h \
197+ option.h ex_cmds.h proto.h spell/local.h spell/wm.h spell/ispell.h
198 objects/syntax.o: syntax.c vim.h auto/config.h feature.h os_unix.h \
199 auto/osdef.h ascii.h keymap.h term.h macros.h structs.h regexp.h \
200 gui.h gui_beval.h proto/gui_beval.pro option.h ex_cmds.h proto.h \
201@@ -2558,3 +2582,26 @@
202 auto/osdef.h ascii.h keymap.h term.h macros.h structs.h regexp.h \
203 gui.h gui_beval.h proto/gui_beval.pro option.h ex_cmds.h proto.h \
204 globals.h farsi.h arabic.h version.h
205+
206+SPELL_CFLAGS=$(CFLAGS) -pedantic -DUSG=1
207+
208+objects/good.o: spell/good.c spell/config.h spell/ispell.h spell/i_proto.h spell/msgs.h spell/local.h
209+ $(CC) -c $(SPELL_CFLAGS) spell/good.c -o objects/good.o
210+
211+objects/lookup.o: spell/lookup.c spell/config.h spell/ispell.h spell/i_proto.h spell/msgs.h spell/local.h
212+ $(CC) -c $(SPELL_CFLAGS) spell/lookup.c -o objects/lookup.o
213+
214+objects/hash.o: spell/hash.c spell/config.h spell/ispell.h spell/i_proto.h spell/local.h
215+ $(CC) -c $(SPELL_CFLAGS) spell/hash.c -o objects/hash.o
216+
217+objects/makedent.o: spell/makedent.c spell/config.h spell/ispell.h spell/i_proto.h spell/msgs.h spell/local.h
218+ $(CC) -c $(SPELL_CFLAGS) spell/makedent.c -o objects/makedent.o
219+
220+objects/tree.o: spell/tree.c spell/config.h spell/ispell.h spell/i_proto.h spell/msgs.h spell/local.h
221+ $(CC) -c $(SPELL_CFLAGS) spell/tree.c -o objects/tree.o
222+
223+objects/tgood.o: spell/tgood.c spell/config.h spell/ispell.h spell/i_proto.h spell/local.h
224+ $(CC) -c $(SPELL_CFLAGS) spell/tgood.c -o objects/tgood.o
225+
226+objects/util.o: spell/util.c spell/config.h spell/ispell.h spell/i_proto.h spell/local.h
227+ $(CC) -c $(SPELL_CFLAGS) spell/util.c -o objects/util.o
228diff -ruN vim62./src/normal.c vim62/src/normal.c
229--- vim62./src/normal.c 2003-05-21 16:44:35.000000000 +0200
230+++ vim62/src/normal.c 2003-06-02 19:57:21.000000000 +0200
231@@ -84,6 +84,10 @@
24ec98f0
JB
232 #ifdef FEAT_VISUAL
233 static int get_visual_text __ARGS((cmdarg_T *cap, char_u **pp, int *lenp));
234 #endif
235+#ifdef FEAT_SPELL_HL
236+static void nv_settodict_q __ARGS((cmdarg_T *cap));
237+static void nv_settodict_s __ARGS((cmdarg_T *cap));
238+#endif
239 static void nv_tagpop __ARGS((cmdarg_T *cap));
240 static void nv_scroll __ARGS((cmdarg_T *cap));
98f80704 241 static void nv_right __ARGS((cmdarg_T *cap));
41e3656f 242@@ -231,9 +235,17 @@
24ec98f0
JB
243 {Ctrl_N, nv_down, NV_STS, FALSE},
244 {Ctrl_O, nv_ctrlo, 0, 0},
245 {Ctrl_P, nv_up, NV_STS, FALSE},
246+#ifdef FEAT_SPELL_HL
247+ {Ctrl_Q, nv_settodict_q, 0, 0},
248+#else
249 {Ctrl_Q, nv_ignore, 0, 0},
250+#endif
251 {Ctrl_R, nv_redo, 0, 0},
252+#ifdef FEAT_SPELL_HL
253+ {Ctrl_S, nv_settodict_s, 0, 0},
254+#else
255 {Ctrl_S, nv_ignore, 0, 0},
256+#endif
257 {Ctrl_T, nv_tagpop, NV_NCW, 0},
258 {Ctrl_U, nv_halfpage, 0, 0},
259 #ifdef FEAT_VISUAL
41e3656f 260@@ -7574,6 +7586,28 @@
24ec98f0
JB
261 #endif
262 }
263
264+#ifdef FEAT_SPELL_HL
265+static void
266+nv_settodict_q(cap)
267+ cmdarg_T *cap;
268+{
269+ if(set_to_private_dict(
270+ ml_get_buf(curbuf, curwin->w_cursor.lnum, FALSE),
271+ curwin->w_cursor.col, FALSE))
272+ clearopbeep(cap->oap);
273+}
274+
275+static void
276+nv_settodict_s(cap)
277+ cmdarg_T *cap;
278+{
279+ if(set_to_private_dict(
280+ ml_get_buf(curbuf, curwin->w_cursor.lnum, FALSE),
281+ curwin->w_cursor.col, TRUE))
282+ clearopbeep(cap->oap);
283+}
284+#endif
285+
286 #ifdef FEAT_VISUAL
287 /*
288 * In exclusive Visual mode, may include the last character.
41e3656f 289diff -ruN vim62./src/option.c vim62/src/option.c
290--- vim62./src/option.c 2003-05-29 17:13:38.000000000 +0200
291+++ vim62/src/option.c 2003-06-02 19:57:21.000000000 +0200
292@@ -121,6 +121,8 @@
24ec98f0
JB
293 , PV_SW
294 , PV_SWF
295 , PV_SYN
296+ , PV_SPELL_DIR
297+ , PV_SPELL_LANG
298 , PV_TAGS
299 , PV_TS
300 , PV_TSR
41e3656f 301@@ -221,6 +223,10 @@
24ec98f0
JB
302 #ifdef FEAT_SYN_HL
303 static char_u *p_syn;
304 #endif
305+#ifdef FEAT_SPELL_HL
306+static char_u *p_spelldirectory;
307+static char_u *p_language;
308+#endif
309 static long p_ts;
310 static long p_tw;
311 static int p_tx;
41e3656f 312@@ -1052,7 +1058,7 @@
24ec98f0
JB
313 {(char_u *)FALSE, (char_u *)0L}},
314 {"highlight", "hl", P_STRING|P_VI_DEF|P_RCLR|P_COMMA|P_NODUP,
315 (char_u *)&p_hl, PV_NONE,
316- {(char_u *)"8:SpecialKey,@:NonText,d:Directory,e:ErrorMsg,i:IncSearch,l:Search,m:MoreMsg,M:ModeMsg,n:LineNr,r:Question,s:StatusLine,S:StatusLineNC,c:VertSplit,t:Title,v:Visual,V:VisualNOS,w:WarningMsg,W:WildMenu,f:Folded,F:FoldColumn,A:DiffAdd,C:DiffChange,D:DiffDelete,T:DiffText",
317+ {(char_u *)"8:SpecialKey,@:NonText,d:Directory,e:ErrorMsg,i:IncSearch,l:Search,m:MoreMsg,M:ModeMsg,n:LineNr,r:Question,s:StatusLine,S:StatusLineNC,c:VertSplit,t:Title,v:Visual,V:VisualNOS,w:WarningMsg,W:WildMenu,f:Folded,F:FoldColumn,A:DiffAdd,C:DiffChange,D:DiffDelete,T:DiffText,Z:Spell",
318 (char_u *)0L}},
319 {"history", "hi", P_NUM|P_VIM,
320 (char_u *)&p_hi, PV_NONE,
41e3656f 321@@ -1317,6 +1323,13 @@
24ec98f0
JB
322 (char_u *)NULL, PV_NONE,
323 #endif
324 {(char_u *)"", (char_u *)0L}},
325+ {"language", "lang", P_STRING|P_ALLOCED|P_VI_DEF,
326+#ifdef FEAT_SPELL_HL
327+ (char_u *)&p_language, PV_SPELL_LANG,
328+#else
329+ (char_u *)NULL, PV_NONE,
330+#endif
331+ {(char_u *)"", (char_u *)0L}},
332 {"laststatus", "ls", P_NUM|P_VI_DEF|P_RALL,
333 #ifdef FEAT_WINDOWS
334 (char_u *)&p_ls, PV_NONE,
41e3656f 335@@ -1915,6 +1928,14 @@
24ec98f0
JB
336 {"sourceany", NULL, P_BOOL|P_VI_DEF,
337 (char_u *)NULL, PV_NONE,
338 {(char_u *)FALSE, (char_u *)0L}},
339+ {"spelldirectory", "spelldir", P_STRING|P_ALLOCED|P_VI_DEF|P_EXPAND,
340+#ifdef FEAT_SPELL_HL
341+ (char_u *)&p_spelldirectory, PV_SPELL_DIR,
342+ {(char_u *)"/usr/lib/ispell", (char_u *)0L}},
343+#else
344+ (char_u *)NULL, PV_NONE,
345+ {(char_u *)"", (char_u *)0L}},
346+#endif
347 {"splitbelow", "sb", P_BOOL|P_VI_DEF,
348 #ifdef FEAT_WINDOWS
349 (char_u *)&p_sb, PV_NONE,
41e3656f 350@@ -4690,6 +4711,26 @@
24ec98f0
JB
351 errmsg = e_invarg;
352 }
353 #endif
354+#ifdef FEAT_SPELL_HL
355+ else if (varp == &p_spell_dir)
356+ {
357+ STRCPY(hashname, p_spell_dir);
358+ STRCAT(hashname, "/");
359+ STRCAT(hashname, p_spell_lang);
360+ STRCAT(hashname, ".hash");
361+ reload_dict();
362+ redraw_all_later(NOT_VALID);
363+ }
364+ else if (varp == &p_spell_lang)
365+ {
366+ STRCPY(hashname, p_spell_dir);
367+ STRCAT(hashname, "/");
368+ STRCAT(hashname, p_spell_lang);
369+ STRCAT(hashname, ".hash");
370+ reload_dict();
371+ redraw_all_later(NOT_VALID);
372+ }
373+#endif
374
375 #ifdef FEAT_MBYTE
376 /* 'encoding' and 'fileencoding' */
41e3656f 377@@ -7725,6 +7766,10 @@
24ec98f0
JB
378 #ifdef FEAT_SYN_HL
379 case PV_SYN: return (char_u *)&(curbuf->b_p_syn);
98f80704 380 #endif
24ec98f0
JB
381+#ifdef FEAT_SPELL_HL
382+ case PV_SPELL_DIR: return (char_u *)&(p_spell_dir);
383+ case PV_SPELL_LANG: return (char_u *)&(p_spell_lang);
98f80704 384+#endif
24ec98f0
JB
385 case PV_SW: return (char_u *)&(curbuf->b_p_sw);
386 case PV_TS: return (char_u *)&(curbuf->b_p_ts);
98f80704 387 case PV_TW: return (char_u *)&(curbuf->b_p_tw);
41e3656f 388diff -ruN vim62./src/option.h vim62/src/option.h
389--- vim62./src/option.h 2003-05-17 21:02:23.000000000 +0200
390+++ vim62/src/option.h 2003-06-02 19:57:21.000000000 +0200
391@@ -371,6 +371,8 @@
24ec98f0
JB
392 EXTERN char_u *p_dex; /* 'diffexpr' */
393 # endif
394 #endif
395+EXTERN char_u *p_spell_dir; /* directory with spell hash*/
396+EXTERN char_u *p_spell_lang; /* name of language (spell hash file)*/
397 #ifdef FEAT_INS_EXPAND
398 EXTERN char_u *p_dict; /* 'dictionary' */
399 #endif
41e3656f 400diff -ruN vim62./src/proto/spell.pro vim62/src/proto/spell.pro
401--- vim62./src/proto/spell.pro 1970-01-01 01:00:00.000000000 +0100
402+++ vim62/src/proto/spell.pro 2003-06-02 19:57:21.000000000 +0200
24ec98f0
JB
403@@ -0,0 +1,5 @@
404+int reload_dict(void);\r
405+void ex_spell(exarg_T *eap);\r
406+int get_spell_attr(colnr_T spell_col, colnr_T col, char_u *line);\r
407+int set_to_private_dict(char *line, int cursor_col, int convert_to_lower);\r
408+void spell_save_private_dict(void);\r
41e3656f 409diff -ruN vim62./src/proto.h vim62/src/proto.h
410--- vim62./src/proto.h 2003-05-24 17:27:36.000000000 +0200
411+++ vim62/src/proto.h 2003-06-02 19:57:21.000000000 +0200
412@@ -72,6 +72,9 @@
24ec98f0
JB
413 # include "os_qnx.pro"
414 # endif
415
416+#ifdef FEAT_SPELL_HL
417+# include "spell.pro"
418+#endif
419 # include "buffer.pro"
420 # include "charset.pro"
98f80704 421 # ifdef FEAT_CSCOPE
41e3656f 422diff -ruN vim62./src/screen.c vim62/src/screen.c
423--- vim62./src/screen.c 2003-06-02 19:56:54.000000000 +0200
424+++ vim62/src/screen.c 2003-06-02 19:57:21.000000000 +0200
24ec98f0
JB
425@@ -115,6 +115,9 @@
426 static match_T match_hl; /* used for ":match" highlight matching */
427 #endif
428
429+#ifdef FEAT_SPELL_HL
430+extern int spell_flag;
431+#endif
432 #ifdef FEAT_FOLDING
433 static foldinfo_T win_foldinfo; /* info for 'foldcolumn' */
434 #endif
41e3656f 435@@ -2466,6 +2469,9 @@
24ec98f0 436 int has_syntax = FALSE; /* this buffer has syntax highl. */
98f80704 437 int save_did_emsg;
24ec98f0
JB
438 #endif
439+#ifdef FEAT_SPELL_HL
440+ int spell_attr = 0;
441+#endif
442 int extra_check; /* has syntax or linebreak */
443 #ifdef FEAT_MBYTE
444 int multi_attr = 0; /* attributes desired by multibyte */
41e3656f 445@@ -2544,8 +2550,18 @@
24ec98f0
JB
446 #else
447 extra_check = 0;
448 #endif
449+#if defined(FEAT_SYN_HL) || defined(FEAT_SPELL_HL)
450+ if (
451 #ifdef FEAT_SYN_HL
452- if (syntax_present(wp->w_buffer))
453+ syntax_present(wp->w_buffer)
454+#else
455+ 0
456+#endif
457+#ifdef FEAT_SPELL_HL
458+ ||
459+ spell_flag
460+#endif
461+ )
462 {
98f80704 463 /* Prepare for syntax highlighting in this line. When there is an
464 * error, stop syntax highlighting. */
41e3656f 465@@ -3196,6 +3212,10 @@
24ec98f0
JB
466 else if (search_attr == 0 && has_syntax)
467 char_attr = syntax_attr;
468 #endif
469+#ifdef FEAT_SPELL_HL
470+ else if (spell_flag)
471+ char_attr = spell_attr;
472+#endif
473 else
474 char_attr = search_attr;
475
41e3656f 476@@ -3510,6 +3530,17 @@
24ec98f0 477 char_attr = syntax_attr;
27d8a8e1
MM
478 }
479 #endif
24ec98f0 480+#ifdef FEAT_SPELL_HL
27d8a8e1 481+ if (spell_flag)
24ec98f0
JB
482+ {
483+ v = ptr - line;
27d8a8e1
MM
484+ spell_attr = get_spell_attr((colnr_T)v - 1, col,
485+ ml_get_buf(wp->w_buffer,
486+ lnum, FALSE));
487+ if (area_attr == 0 && search_attr == 0 && spell_attr)
488+ char_attr = spell_attr;
489+ }
490+#endif
24ec98f0 491 #ifdef FEAT_LINEBREAK
27d8a8e1
MM
492 /*
493 * Found last space before word: check for line break
41e3656f 494diff -ruN vim62./src/spell/config.h vim62/src/spell/config.h
495--- vim62./src/spell/config.h 1970-01-01 01:00:00.000000000 +0100
496+++ vim62/src/spell/config.h 2003-06-02 19:57:21.000000000 +0200
24ec98f0
JB
497@@ -0,0 +1,846 @@
498+#include "local.h" /* local definitions for options */
499+
500+/*
501+** Major-differences selection. The default system is BSD; for USG
502+** or non-UNIX systems you should add the appropriate #define to local.h.
503+*/
504+#ifndef USG
505+#undef USG /* Define this in local.h for System V machines */
506+#endif /* USG */
507+
508+#ifndef WIN32
509+#include <sys/param.h>
510+#include <sys/types.h>
511+#endif
512+#ifndef USG
513+# ifndef FEAT_SPELL_HL
514+# if HAVE_DIRENT_H
515+# include <dirent.h>
516+# ifndef NAMLEN
517+# define NAMLEN(dirent) strlen((dirent)->d_name)
518+# endif
519+# else
520+# define dirent direct
521+# define NAMLEN(dirent) (dirent)->d_namlen
522+# if HAVE_SYS_NDIR_H
523+# include <sys/ndir.h>
524+# endif
525+# if HAVE_SYS_DIR_H
526+# include <sys/dir.h>
527+# endif
528+# if HAVE_NDIR_H
529+# include <ndir.h>
530+# endif
531+# endif
532+# endif
533+#endif /* USG */
534+
535+/*
536+** Things that normally go in a Makefile. Define these just like you
537+** might in the Makefile, except you should use #define instead of
538+** make's assignment syntax. Everything must be double-quoted, and
539+** (unlike make) you can't use any sort of $-syntax to pick up the
540+** values of other definitions.
541+*/
542+#ifndef CC
543+#define CC "cc"
544+#endif /* CC */
545+#ifndef EMACS
546+#define EMACS "emacs"
547+#endif /* EMACS */
548+#ifndef LINT
549+#define LINT "lint"
550+#endif /* LINT */
551+#ifndef CFLAGS
552+#define CFLAGS "-O"
553+#endif /* CFLAGS */
554+#ifndef LINTFLAGS
555+#define LINTFLAGS ""
556+#endif /* LINTFLAGS */
557+#ifndef YACC
558+#define YACC "yacc"
559+#endif /* YACC */
560+
561+/*
562+** Libraries that may need to be added to the cc line to get ispell to
563+** link. Normally, this should be null.
564+*/
565+#ifndef LIBES
566+#define LIBES ""
567+#endif
568+
569+/*
570+** TERMLIB - where to get the termcap library. Should be -ltermcap or
571+** -lcurses on most systems.
572+*/
573+#ifndef TERMLIB
574+#define TERMLIB "-lncurses"
575+#endif
576+
577+/*
578+** REGLIB - where to get the regular-expression routines, if
579+** REGEX_LOOKUP is defined. Should be -lPW on USG systems, null on
580+** BSD systems.
581+*/
582+#ifndef REGLIB
583+#define REGLIB ""
584+#endif
585+
586+/*
587+** Where to install various components of ispell. BINDIR contains
588+** binaries. LIBDIR contains hash tables and affix files. ELISPDIR
589+** contains emacs lisp files (if any) and TEXINFODIR contains emacs
590+** TeXinfo files. MAN1DIR and MAN4DIR will hold the chapter-1 and
591+** chapter-4 manual pages, respectively.
592+**
593+** If you intend to use multiple dictionary files, I would suggest
594+** LIBDIR be a directory which will contain nothing else, so sensible
595+** names can be constructed for the -d option without conflict.
596+*/
597+#ifndef BINDIR
598+#define BINDIR "/usr/bin"
599+#endif
600+#ifndef LIBDIR
601+#define LIBDIR "/usr/lib/ispell"
602+#endif
603+#ifndef ELISPDIR
604+#define ELISPDIR "/usr/lib/emacs/site-lisp"
605+#endif
606+#ifndef TEXINFODIR
607+#define TEXINFODIR "/usr/share/info"
608+#endif
609+#ifndef MAN1DIR
610+#define MAN1DIR "/usr/share/man/man1"
611+#endif
612+#ifndef MAN4DIR
613+#define MAN4DIR "/usr/share/man/man4"
614+#endif
615+
616+/*
617+** Extensions to put on manual pages. Usually these are ".1" or ".1l".
618+*/
619+#ifndef MAN1EXT
620+#define MAN1EXT ".1"
621+#endif
622+#ifndef MAN4EXT
623+#define MAN4EXT ".4"
624+#endif
625+
626+/*
627+** List of all hash files (languages) which will be supported by ispell.
628+**
629+** This variable has a complex format so that many options can be
630+** specified. The format is as follows:
631+**
632+** <language>[,<make-options>...] [<language> [,<make-options> ...] ...]
633+**
634+** where
635+**
636+** language is the name of a subdirectory of the
637+** "languages" directory
638+** make-options are options that are to be passed to "make" in
639+** the specified directory. The make-options
640+** should not, in general, specify a target, as
641+** this will be provided by the make process.
642+**
643+** For example, if LANGUAGES is:
644+**
645+** "{american,MASTERDICTS=american.med+,HASHFILES=americanmed+.hash,EXTRADICT=/usr/dict/words /usr/dict/web2} {deutsch,DICTALWAYS=deutsch.sml,DICTOPTIONS=}"
646+**
647+** then the American-English and Deutsch (German) languages will be supported,
648+** and the following variable settings will be passed to the two Makefiles:
649+**
650+** American:
651+**
652+** MASTERDICTS='american.med+'
653+** HASHFILES='americanmed+.hash'
654+** EXTRADICT='/usr/dict/words /usr/dict/web2'
655+**
656+** Deutsch:
657+**
658+** DICTALWAYS='deutsch.sml'
659+** DICTOPTIONS=''
660+**
661+** Notes on the syntax: The makefile is not very robust. If you have
662+** make problems, or if make seems to fail in the language-subdirs
663+** dependency, check your syntax. The makefile adds single quotes to
664+** the individual variables in the LANGUAGES specification, so don't
665+** use quotes of any kind.
666+**
667+** In the future, the first language listed in this variable will
668+** become the default, and the DEFHASH, DEFLANG, and DEFPAFF,
669+** variables will all become obsolete. So be sure to put your default
670+** language first, to make later conversion easier!
671+**
672+** Notes on options for the various languages will be found in the
673+** Makefiles for those languages. Some of those languages may require
674+** you to also change various limits limits like MASKBITS or the
675+** length parameters.
676+**
677+** A special note on the English language: because the British and
678+** American dialects use different spelling, you should usually select
679+** one or the other of these. If you select both, the setting of
680+** MASTERHASH will determine which becomes the language linked to
681+** DEFHASH (which will usually be named english.hash).
682+**
683+** On MSDOS systems you must use names which are consistent with the
684+** 8+3 filename restrictions, or you will risk filename collision. See
685+** the file pc/local.djgpp for details.
686+*/
687+#ifndef LANGUAGES
688+#define LANGUAGES "{american,MASTERDICTS=american.med+,HASHFILES=americanmed+.hash,EXTRADICT=/usr/dict/words}"
689+#endif /* LANGUAGES */
690+
691+/*
692+** Master hash file for DEFHASH. This is the name of a hash file
693+** built by a language Makefile. It should be the most-popular hash
694+** file on your system, because it is the one that will be used by
695+** default. It must be listed in LANGUAGES, above.
696+*/
697+#ifndef MASTERHASH
698+#define MASTERHASH "polish+.hash"
699+#endif
700+
701+/*
702+** Default native-language hash file. This is the name given to the
703+** hash table that will be used if no language is specified to
704+** ispell. It is a link to MASTERHASH, above.
705+*/
706+#ifndef DEFHASH
707+#define DEFHASH "polish.hash"
708+#endif
709+
710+/*
711+** Language tables for the default language. This must be the name of
712+** the affix file that was used to generate the MASTERHASH/DEFHASH,
713+** above.
714+*/
715+#ifndef DEFLANG
716+#define DEFLANG "polish.aff"
717+#endif
718+
719+/*
720+** Language to use for error messages. If there are no messages in this
721+** language, English will be used instead.
722+*/
723+#ifndef MSGLANG
724+#define MSGLANG "polish"
725+#endif /* MSGLANG */
726+
727+/*
728+** If your sort command accepts the -T switch to set temp file
729+** locations (try it out; it exists but is undocumented on some
730+** systems), make the following variable the null string. Otherwise
731+** leave it as the sed script.
732+*/
733+#ifndef SORTTMP
734+#define SORTTMP "-e '/!!SORTTMP!!/s/=.*$/=/'"
735+#endif
736+
737+/*
738+** If your sort command accepts the -T switch (see above), make the
739+** following variable refer to a temporary directory with lots of
740+** space. Otherwise make it the null string.
741+*/
742+#ifndef MAKE_SORTTMP
743+#define MAKE_SORTTMP "-T ${TMPDIR-/usr/tmp}"
744+#endif
745+
746+/*
747+** If your shell needs ": Use /bin/sh" at the first line of a shell
748+** script, make the following variable the null string. Otherwise
749+** leave it as this sed script which will put a "#!/bin/sh" there.
750+*/
751+#ifndef MAKE_POUND_BANG
752+#define MAKE_POUND_BANG "-e 1s,^:.*Use.*/bin/sh,#!/bin/sh,"
753+#endif
754+
755+
756+/*
757+** INSTALL program. Could be a copy program like cp or something fancier
758+** like /usr/ucb/install -c
759+*/
760+#ifndef INSTALL
761+#define INSTALL "cp"
762+#endif
763+
764+/*
765+** If your system has the rename(2) system call, define HAS_RENAME and
766+** ispell will use that call to rename backup files. Otherwise, it
767+** will use link/unlink. There is no harm in this except on MS-DOS,
768+** which doesn't support link/unlink.
769+*/
770+#ifndef HAS_RENAME
771+#undef HAS_RENAME
772+#endif /* HAS_RENAME */
773+
774+/* type given to signal() by signal.h */
775+#ifndef SIGNAL_TYPE
776+#define SIGNAL_TYPE void
777+#endif
778+
779+/* environment variable for user's word list */
780+#ifndef PDICTVAR
781+#define PDICTVAR "WORDLIST"
782+#endif
783+
784+/* prefix part of default word list */
785+#ifndef DEFPDICT
786+#define DEFPDICT ".ispell_"
787+#endif
788+
789+/*
790+** suffix part of default word list
791+*/
792+#ifndef DEFPAFF
793+#define DEFPAFF "words"
794+#endif
795+
796+/* old place to look for default word list */
797+#ifndef OLDPDICT
798+#define OLDPDICT ".ispell_"
799+#endif /* OLDPDICT */
800+#ifndef OLDPAFF
801+#define OLDPAFF "words"
802+#endif /* OLDPAFF */
803+
804+/* environment variable for include file string */
805+#ifndef INCSTRVAR
806+#define INCSTRVAR "INCLUDE_STRING"
807+#endif
808+
809+/* default include string */
810+#ifndef DEFINCSTR
811+#define DEFINCSTR "&Include_File&"
812+#endif
813+
814+/* mktemp template for temporary file - MUST contain 6 consecutive X's */
815+#ifndef TEMPNAME
816+#define TEMPNAME "/tmp/ispellXXXXXX"
817+#endif
818+
819+/*
820+** If REGEX_LOOKUP is undefined, the lookup command (L) will use the look(1)
821+** command (if available) or the egrep command. If REGEX_LOOKUP is defined,
822+** the lookup command will use the internal dictionary and the
823+** regular-expression library (which you must supply separately. There is
824+** a public-domain library available; libraries are also distributed with
825+** both BSD and System V.
826+**
827+** The advantage of no REGEX_LOOKUP is that it is often much faster, especially
828+** if the look(1) command is available, that the words found are presented
829+** in alphabetical order, and that the list of words searched is larger.
830+** The advantage of REGEX_LOOKUP is that ispell doesn't need to spawn another
831+** program, and the list of words searched is exactly the list of (root) words
832+** that ispell will accept. (However, note that words formed with affixes will
833+** not be found; this can produce some artifacts. For example, since
834+** "brother" can be formed as "broth+er", a lookup command might fail to
835+** find "brother.")
836+*/
837+#ifndef REGEX_LOOKUP
838+#undef REGEX_LOOKUP
839+#endif /* REGEX_LOOKUP */
840+
841+/*
842+** Choose the proper type of regular-expression routines here. BSD
843+** and public-domain systems have routines called re_comp and re_exec;
844+** System V uses regcmp and regex.
845+**
846+** REGCTYPE is the type of a variable to hold the compiled regexp
847+** REGCMP(re,str) is the function which compiles a regexp in `str' into
848+** a compiled regexp `re' declared as REGCTYPE and
849+** returns `re'.
850+** REGEX(re,str,dummy) is a function which matches `str' against a compiled
851+** regexp in `re' and returns a non-NULL pointer if it
852+** matches, NULL otherwise.
853+** REGFREE(re) is anything that should be done when the compiled
854+** regexp `re' is no longer needed. It can be also used
855+** to allocate any structures required to compile a
856+** regexp, since it is called *before* compiling a new
857+** regexp (that's where we know that the old one will no
858+** longer be used).
859+**
860+** Here is one way of defining these if you have POSIX regexp functions:
861+**
862+** #include <sys/types.h>
863+** #include <regex.h>
864+** #define REGCTYPE regex_t *
865+** #define REGCMP(re,str) (regcomp (re, str, 0), re)
866+** #define REGEX(re, str, dummy) \
867+** (re != 0 && regexec (re, str, 0, 0, 0) == 0 ? (char *)1 : NULL)
868+** #define REGFREE(re) \
869+** do { \
870+** if (re == 0) \
871+** re = (regex_t *)calloc (1, sizeof (regex_t)); \
872+** else \
873+** regfree(re); \
874+** } while (0)
875+**
876+*/
877+#ifdef REGEX_LOOKUP
878+#ifndef REGCMP
879+#ifdef USG
880+#define REGCTYPE char *
881+#define REGCMP(re,str) regcmp (str, (char *) 0)
882+#define REGEX(re, str, dummy) regex (re, str, dummy, dummy, dummy, dummy, \
883+ dummy, dummy, dummy, dummy, dummy, dummy)
884+#define REGFREE(re) do {if (re != NULL) free (re); re = NULL;} \
885+ while (0)
886+#else /* USG */
887+#define REGCTYPE char *
888+#define REGFREE(re) (void)0
889+#define REGCMP(re,str) re_comp (str)
890+#define REGEX(re, str, dummy) re_exec (str)
891+#endif /* USG */
892+#endif /* REGCMP */
893+#endif /* REGEX_LOOKUP */
894+
895+/* look command (if look(1) MAY BE available - ignored if not) */
896+#ifndef REGEX_LOOKUP
897+#ifndef LOOK
898+#define LOOK "look -df"
899+#endif
900+#endif /* REGEX_LOOKUP */
901+
902+/* path to egrep (use speeded up version if available) */
903+#ifndef EGREPCMD
904+#ifdef USG
905+#define EGREPCMD "/bin/egrep"
906+#else
907+#define EGREPCMD "/usr/bin/egrep -i"
908+#endif
909+#endif
910+
911+/* path to wordlist for Lookup command (typically /usr/dict/{words|web2}) */
912+/* note that /usr/dict/web2 is usually a bad idea due to obscure words */
913+#ifndef WORDS
914+#define WORDS "/usr/dict/words"
915+#endif
916+
917+/* buffer size to use for file names if not in sys/param.h */
918+#ifndef MAXPATHLEN
919+#define MAXPATHLEN 240
920+#endif
921+
922+/* max file name length (will truncate to fit BAKEXT) if not in sys/param.h */
923+#ifndef MAXNAMLEN
924+#define MAXNAMLEN 14
925+#endif
926+
927+/* define if you want .bak file names truncated to MAXNAMLEN characters */
928+#ifndef TRUNCATEBAK
929+#undef TRUNCATEBAK
930+#endif /* TRUNCATEBAK */
931+
932+/* largest word accepted from a file by any input routine, plus one */
933+#ifndef INPUTWORDLEN
934+#define INPUTWORDLEN 100
935+#endif
936+
937+/* largest amount that a word might be extended by adding affixes */
938+#ifndef MAXAFFIXLEN
939+#define MAXAFFIXLEN 20
940+#endif
941+
942+/*
943+** Define the following to suppress the 8-bit character feature.
944+** Unfortunately, this doesn't work as well as it might, because ispell
945+** only strips the 8th bit in some places. For example, it calls strcmp()
946+** quite often without first stripping parity. However, I really wonder
947+** about the utility of this option, so I haven't bothered to fix it. If
948+** you think the stripping feature of NO8BIT is useful, you might let me
949+** (Geoff Kuenning) know.
950+**
951+** Nevertheless, NO8BIT is a useful option for other reasons. If NO8BIT
952+** is defined, ispell will probably use 8-bit characters internally;
953+** this improves time efficiency and saves a small amount of space
954+** in the hash file. Thus, I recommend you specify NO8BIT unless you
955+** actually expect to be spelling files which use a 256-character set.
956+*/
957+#ifndef NO8BIT
958+#undef NO8BIT
959+#endif /* NO8BIT */
960+
961+/*
962+** Number of mask bits (affix flags) supported. Must be 32, 64, 128, or
963+** 256. If MASKBITS is 32 or 64, there are really only 26 or 58 flags
964+** available, respectively. If it is 32, the flags are named with the
965+** 26 English uppercase letters; lowercase will be converted to uppercase.
966+** If MASKBITS is 64, the 58 flags are named 'A' through 'z' in ASCII
967+** order, including the 6 special characters from 'Z' to 'a': "[\]^_`".
968+** If MASKBITS is 128 or 256, all the 7-bit or 8-bit characters,
969+** respectively, are theoretically available, though a few (newline, slash,
970+** null byte) are pretty hard to actually use successfully.
971+**
972+** Note that a number of non-English affix files depend on having a
973+** larger value for MASKBITS. See the affix files for more
974+** information.
975+*/
976+#ifndef MASKBITS
977+#define MASKBITS 64
978+#endif
979+
980+/*
981+** C type to use for masks. This should be a type that the processor
982+** accesses efficiently.
983+**
984+** MASKTYPE_WIDTH must correctly reflect the number of bits in a
985+** MASKTYPE. Unfortunately, it is also required to be a constant at
986+** preprocessor time, which means you can't use the sizeof operator to
987+** define it.
988+**
989+** Note that MASKTYPE *must* match MASKTYPE_WIDTH or you may get
990+** division-by-zero errors!
991+*/
992+#ifndef MASKTYPE
993+#define MASKTYPE long
994+#endif
995+#ifndef MASKTYPE_WIDTH
996+#define MASKTYPE_WIDTH 32
997+#endif
998+#if MASKBITS < MASKTYPE_WIDTH
999+#undef MASKBITS
1000+#define MASKBITS MASKTYPE_WIDTH
1001+#endif /* MASKBITS < MASKTYPE_WIDTH */
1002+
1003+
1004+/* maximum number of include files supported by xgets; set to 0 to disable */
1005+#ifndef MAXINCLUDEFILES
1006+#define MAXINCLUDEFILES 5
1007+#endif
1008+
1009+/*
1010+** Maximum hash table fullness percentage. Larger numbers trade space
1011+** for time.
1012+**/
1013+#ifndef MAXPCT
1014+#define MAXPCT 70 /* Expand table when 70% full */
1015+#endif
1016+
1017+/*
1018+** Maximum number of "string" characters that can be defined in a
1019+** language (affix) file. Don't forget that an upper/lower string
1020+** character counts as two!
1021+*/
1022+#ifndef MAXSTRINGCHARS
35c7515f 1023+#define MAXSTRINGCHARS 512
24ec98f0
JB
1024+#endif /* MAXSTRINGCHARS */
1025+
1026+/*
1027+** Maximum length of a "string" character. The default is appropriate for
1028+** nroff-style characters starting with a backslash.
1029+*/
1030+#ifndef MAXSTRINGCHARLEN
1031+#define MAXSTRINGCHARLEN 10
1032+#endif /* MAXSTRINGCHARLEN */
1033+
1034+/*
1035+** the S_NOPARITY mask is applied to user input characters from the terminal
1036+** in order to mask out the parity bit.
1037+*/
1038+#ifdef NO8BIT
1039+#define S_NOPARITY 0x7f
1040+#else
1041+#define S_NOPARITY 0xff
1042+#endif
1043+
1044+
1045+/*
1046+** the terminal mode for ispell, set to CBREAK or RAW
1047+**
1048+*/
1049+#ifndef TERM_MODE
1050+#define TERM_MODE CBREAK
1051+#endif
1052+
1053+/*
1054+** Define this if you want your columns of words to be of equal length.
1055+** This will spread short word lists across the screen instead of down it.
1056+*/
1057+#ifndef EQUAL_COLUMNS
1058+#undef EQUAL_COLUMNS
1059+#endif /* EQUAL_COLUMNS */
1060+
1061+/*
1062+** This is the extension that will be added to backup files
1063+*/
1064+#ifndef BAKEXT
1065+#define BAKEXT ".bak"
1066+#endif
1067+
1068+/*
1069+** Define this if you want to suppress the capitalization-checking
1070+** feature. This will reduce the size of the hashed dictionary on
1071+** most 16-bit and some 32-bit machines. This option is not
1072+** recommended.
1073+*/
1074+#ifndef NO_CAPITALIZATION_SUPPORT
1075+#undef NO_CAPITALIZATION_SUPPORT
1076+#endif /* NO_CAPITALIZATION_SUPPORT */
1077+
1078+/*
1079+** Define this if you want your personal dictionary sorted. This may take
1080+** a long time for very large dictionaries. Dictionaries larger than
1081+** SORTPERSONAL words will not be sorted. Define SORTPERSONAL as zero
1082+** to disable this feature.
1083+*/
1084+#ifndef SORTPERSONAL
1085+#define SORTPERSONAL 1000
1086+#endif
1087+
1088+/*
1089+** Define this if you want to use the shell for interpretation of commands
1090+** issued via the "L" command, "^Z" under System V, and "!". If this is
1091+** not defined then a direct fork()/exec() will be used in place of the
1092+** normal system(). This may speed up these operations greately on some
1093+** systems.
1094+*/
1095+#ifndef USESH
1096+#undef USESH
1097+#endif /* USESH */
1098+
1099+/*
1100+** Maximum language-table search size. Smaller numbers make ispell
1101+** run faster, at the expense of more memory (the lowest reasonable value
1102+** is 2). If a given character appears in a significant position in
1103+** more than MAXSEARCH suffixes, it will be given its own index table.
1104+** If you change this, define INDEXDUMP in lookup.c to be sure your
1105+** index table looks reasonable.
1106+*/
1107+#ifndef MAXSEARCH
1108+#define MAXSEARCH 4
1109+#endif
1110+
1111+/*
1112+** Define this if you want to be able to type any command at a "type space
1113+** to continue" prompt.
1114+*/
1115+#ifndef COMMANDFORSPACE
1116+#undef COMMANDFORSPACE
1117+#endif /* COMMANDFORSPACE */
1118+
1119+/*
1120+** Memory-allocation increment. Buildhash allocates memory in chunks
1121+** of this size, and then subdivides it to get its storage. This saves
1122+** much malloc execution time. A good number for this is the system
1123+** page size less the malloc storage overhead.
1124+**
1125+** Define this to zero to revert to using malloc/realloc. This is normally
1126+** useful only on systems with limited memory.
1127+*/
1128+#ifndef MALLOC_INCREMENT
1129+#define MALLOC_INCREMENT 0
1130+#endif
1131+
1132+/*
1133+** Maximum number of "hits" expected on a word. This is basically the
1134+** number of different ways different affixes can produce the same word.
1135+** For example, with "english.aff", "brothers" can be produced 3 ways:
1136+** "brothers," "brother+s", or "broth+ers". If this is too low, no major
1137+** harm will be done, but ispell may occasionally forget a capitalization.
1138+*/
1139+#ifndef MAX_HITS
1140+#define MAX_HITS 10
1141+#endif
1142+
1143+/*
1144+** Maximum number of capitalization variations expected in any word.
1145+** Besides the obvious all-lower, all-upper, and capitalized versions,
1146+** this includes followcase variants. If this is too low, no real
1147+** harm will be done, but ispell may occasionally fail to suggest a
1148+** correct capitalization.
1149+*/
1150+#ifndef MAX_CAPS
1151+#define MAX_CAPS 10
1152+#endif /* MAX_CAPS */
1153+
1154+/* Define this to ignore spelling check of entire LaTeX bibliography listings */
1155+#ifndef IGNOREBIB
1156+#undef IGNOREBIB
1157+#endif
1158+
1159+/*
1160+** Default nroff and TeX special characters. Normally, you won't want to
1161+** change this; instead you would override it in the language-definition
1162+** file.
1163+*/
1164+#ifndef TEXSPECIAL
1165+#define TEXSPECIAL "{}$*.%#&?,;:!@~-"
1166+#endif
1167+
1168+#ifndef NRSPECIAL
1169+#define NRSPECIAL "().\\*"
1170+#endif
1171+
1172+/*
1173+** Defaults for certain command-line flags.
1174+*/
1175+#ifndef DEFNOBACKUPFLAG
1176+#define DEFNOBACKUPFLAG 0 /* Don't suppress backup file */
1177+#endif
1178+#ifndef DEFTEXFLAG
1179+#define DEFTEXFLAG 0 /* Default to nroff mode */
1180+#endif
1181+
1182+/*
1183+** Define this if you want ispell to place a limitation on the maximum
1184+** size of the screen. On windowed workstations with very large windows,
1185+** the size of the window can be too much of a good thing, forcing the
1186+** user to look back and forth between the bottom and top of the screen.
1187+** If MAX_SCREEN_SIZE is nonzero, screens larger than this will be treated
1188+** as if they have only MAX_SCREEN_SIZE lines. A good value for this
1189+** variable is 24 or 30. Define it as zero to suppress the feature.
1190+*/
1191+#ifndef MAX_SCREEN_SIZE
1192+#define MAX_SCREEN_SIZE 0
1193+#endif
1194+
1195+/*
1196+** The next three variables are used to provide a variable-size context
1197+** display at the bottom of the screen. Normally, the user will see
1198+** a number of lines equal to CONTEXTPCT of his screen, rounded down
1199+** (thus, with CONTEXTPCT == 10, a 24-line screen will produce two lines
1200+** of context). The context will never be greater than MAXCONTEXT or
1201+** less than MINCONTEXT. To disable this feature entirely, set MAXCONTEXT
1202+** and MINCONTEXT to the same value. To round context percentages up,
1203+** define CONTEXTROUNDUP.
1204+**
1205+** Warning: don't set MAXCONTEXT ridiculously large. There is a
1206+** static buffer of size MAXCONTEXT*BUFSIZ; since BUFSIZ is frequently
1207+** 1K or larger, this can create a remarkably large executable.
1208+*/
1209+#ifndef CONTEXTPCT
1210+#define CONTEXTPCT 10 /* Use 10% of the screen for context */
1211+#endif
1212+#ifndef MINCONTEXT
1213+#define MINCONTEXT 2 /* Always show at least 2 lines of context */
1214+#endif
1215+#ifndef MAXCONTEXT
1216+#define MAXCONTEXT 10 /* Never show more than 10 lines of context */
1217+#endif
1218+#ifndef CONTEXTROUNDUP
1219+#undef CONTEXTROUNDUP /* Don't round context up */
1220+#endif
1221+
1222+/*
1223+** Define this if you want the context lines to be displayed at the
1224+** bottom of the screen, the way they used to be, rather than at the top.
1225+*/
1226+#ifndef BOTTOMCONTEXT
1227+#undef BOTTOMCONTEXT
1228+#endif /* BOTTOMCONTEXT */
1229+
1230+/*
1231+** Define this if you want the "mini-menu," which gives the most important
1232+** options at the bottom of the screen, to be the default (in any case, it
1233+** can be controlled with the "-M" switch).
1234+*/
1235+#ifndef MINIMENU
1236+#undef MINIMENU
1237+#endif
1238+
1239+/*
1240+** You might want to change this to zero if your users want to check
1241+** single-letter words against the dictionary. However, you should try
1242+** some sample runs using the -W switch before you try it out; you'd
1243+** be surprised how many single letters appear in documents. If you increase
1244+** MINWORD beyond 1, don't say I didn't warn you that it was a bad idea.
1245+*/
1246+#ifndef MINWORD
1247+#define MINWORD 1 /* Words this short and shorter are always ok */
1248+#endif
1249+
1250+/*
1251+** ANSI C compilers are supposed to provide an include file,
1252+** "stdlib.h", which gives function prototypes for all library
1253+** routines. Define NO_STDLIB_H if you have a compiler that claims to
1254+** be ANSI, but doesn't provide this include file.
1255+*/
1256+#ifndef NO_STDLIB_H
1257+#ifndef __STDC__
1258+#define NO_STDLIB_H
1259+#endif /* __STDC__ */
1260+#endif /* NO_STDLIB_H */
1261+
1262+/*
1263+** The following define is used by the ispell developer to help
1264+** double-check the software. Leave it undefined on other systems
1265+** unless you are especially fond of warning messages, or are pursuing
1266+** an inexplicable bug that might be related to a type mismatch.
1267+*/
1268+#ifndef GENERATE_LIBARARY_PROTOS
1269+#undef GENERATE_LIBARARY_PROTOS
1270+#endif /* GENERATE_LIBARARY_PROTOS */
1271+
1272+/*
1273+** Symbols below this point are generally intended to cater to
1274+** idiosyncracies of specific machines and operating systems.
1275+**
1276+** MS-DOS users should also define HAS_RENAME, above, if appropriate.
1277+**
1278+** Define PIECEMEAL_HASH_WRITES if your system can't handle huge write
1279+** operations. This is known to be a problem on MS-DOS systems when
1280+** a 16-bit compiler is used to compile Ispell.
1281+*/
1282+#ifndef PIECEMEAL_HASH_WRITES
1283+#undef PIECEMEAL_HASH_WRITES
1284+#endif /* PIECEMEAL_HASH_WRITES */
1285+
1286+/*
1287+** Redefine GETKEYSTROKE() to getkey() on some MS-DOS systems where
1288+** getchar() doesn't operate properly in raw mode.
1289+*/
1290+#ifndef GETKEYSTROKE
1291+#define GETKEYSTROKE() getchar ()
1292+#endif /* GETKEYSTROKE */
1293+
1294+/*
1295+** Define MSDOS_BINARY_OPEN to 0x8000 on MS-DOS systems. This can be
1296+** done by adding "#include fcntl.h" to your local.h file.
1297+*/
1298+#ifndef MSDOS_BINARY_OPEN
1299+#ifdef O_BINARY
1300+#define MSDOS_BINARY_OPEN O_BINARY
1301+#else /* O_BINARY */
1302+#define MSDOS_BINARY_OPEN 0
1303+#endif /* O_BINARY */
1304+#endif /* MSDOS_BINARY_OPEN */
1305+
1306+/*
1307+** Environment variable to use to locate the home directory. On DOS
1308+** systems you might want to set this to ISPELL_HOME to avoid
1309+** conflicts with other programs that look for a HOME environment
1310+** variable; on all other systems it should be just HOME.
1311+*/
1312+#ifndef HOME
1313+#define HOME "HOME"
1314+#endif /* HOME */
1315+
1316+/*
1317+** On MS-DOS systems, define PDICTHOME to be the name of a directory
1318+** to be used to contain the personal dictionary (.ispell_english,
1319+** etc.). On other systems, you can leave it undefined.
1320+*/
1321+#ifndef PDICTHOME
1322+#undef PDICTHOME
1323+#endif /* PDICTHOME */
1324+
1325+/*
1326+** On MS-DOS systems, you can rename the following variables so that
1327+** ispell's files have 3-character suffixes. Note that, if you do
1328+** this, you will have to redefine any variable above that incorporates
1329+** one of the suffixes. (Most MS-DOS environments will silently truncate
1330+** excess characters beyond the 8+3 limit, so you usually don't need to
1331+** change the suffixes just because they are longer than 3 characters.)
1332+*/
1333+#ifndef HASHSUFFIX
1334+#define HASHSUFFIX ".hash"
1335+#endif /* HASHSUFFIX */
1336+#ifndef STATSUFFIX
1337+#define STATSUFFIX ".sta"
1338+#endif /* STATSUFFIX */
1339+#ifndef COUNTSUFFIX
1340+#define COUNTSUFFIX ".cnt"
1341+#endif /* COUNTSUFFIX */
1342+#define SIGNAL_TYPE_STRING "void"
1343+#define MASKTYPE_STRING "long"
41e3656f 1344diff -ruN vim62./src/spell/good.c vim62/src/spell/good.c
1345--- vim62./src/spell/good.c 1970-01-01 01:00:00.000000000 +0100
1346+++ vim62/src/spell/good.c 2003-06-02 19:57:21.000000000 +0200
24ec98f0
JB
1347@@ -0,0 +1,400 @@
1348+#ifndef lint
1349+static char Rcs_Id[] =
1350+ "$Id$";
1351+#endif
1352+
1353+/*
1354+ * good.c - see if a word or its root word
1355+ * is in the dictionary.
1356+ *
1357+ * Pace Willisson, 1983
1358+ *
1359+ * Copyright 1992, 1993, Geoff Kuenning, Granada Hills, CA
1360+ * All rights reserved.
1361+ *
1362+ * Redistribution and use in source and binary forms, with or without
1363+ * modification, are permitted provided that the following conditions
1364+ * are met:
1365+ *
1366+ * 1. Redistributions of source code must retain the above copyright
1367+ * notice, this list of conditions and the following disclaimer.
1368+ * 2. Redistributions in binary form must reproduce the above copyright
1369+ * notice, this list of conditions and the following disclaimer in the
1370+ * documentation and/or other materials provided with the distribution.
1371+ * 3. All modifications to the source code must be clearly marked as
1372+ * such. Binary redistributions based on modified source code
1373+ * must be clearly marked as modified versions in the documentation
1374+ * and/or other materials provided with the distribution.
1375+ * 4. All advertising materials mentioning features or use of this software
1376+ * must display the following acknowledgment:
1377+ * This product includes software developed by Geoff Kuenning and
1378+ * other unpaid contributors.
1379+ * 5. The name of Geoff Kuenning may not be used to endorse or promote
1380+ * products derived from this software without specific prior
1381+ * written permission.
1382+ *
1383+ * THIS SOFTWARE IS PROVIDED BY GEOFF KUENNING AND CONTRIBUTORS ``AS IS'' AND
1384+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
1385+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
1386+ * ARE DISCLAIMED. IN NO EVENT SHALL GEOFF KUENNING OR CONTRIBUTORS BE LIABLE
1387+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
1388+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
1389+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
1390+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
1391+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
1392+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
1393+ * SUCH DAMAGE.
1394+ */
1395+
1396+/*
1397+ * $Log$
1398+ * Revision 1.43 1994/11/02 06:56:05 geoff
1399+ * Remove the anyword feature, which I've decided is a bad idea.
1400+ *
1401+ * Revision 1.42 1994/10/25 05:45:59 geoff
1402+ * Add support for an affix that will work with any word, even if there's
1403+ * no explicit flag.
1404+ *
1405+ * Revision 1.41 1994/05/24 06:23:06 geoff
1406+ * Let tgood decide capitalization questions, rather than doing it ourselves.
1407+ *
1408+ * Revision 1.40 1994/05/17 06:44:10 geoff
1409+ * Add support for controlled compound formation and the COMPOUNDONLY
1410+ * option to affix flags.
1411+ *
1412+ * Revision 1.39 1994/01/25 07:11:31 geoff
1413+ * Get rid of all old RCS log lines in preparation for the 3.1 release.
1414+ *
1415+ */
1416+
1417+#include <ctype.h>
1418+#include "ispell.h"
1419+
1420+#ifndef NO_CAPITALIZATION_SUPPORT
1421+Public Logical cap_ok (ichar_t * word, struct success * hit, int len);
1422+Local Logical entryhasaffixes (struct dent * dent, struct success * hit);
1423+#endif /* NO_CAPITALIZATION_SUPPORT */
1424+Public void flagpr (ichar_t * word, int preflag, int prestrip,
1425+ int preadd, int sufflag, int sufadd);
1426+Local ichar_t * orig_word;
1427+
1428+Public int
1429+#ifndef NO_CAPITALIZATION_SUPPORT
1430+good (ichar_t *w, int ignoreflagbits, int allhits, int pfxopts, int sfxopts)
1431+#else
1432+/* ARGSUSED */
1433+good (ichar_t *w, int ignoreflagbits, int dummy, int pfxopts, int sfxopts)
1434+#define allhits 0 /* Never actually need more than one hit */
1435+#endif
1436+
1437+{
1438+ ichar_t nword[INPUTWORDLEN + MAXAFFIXLEN];
1439+ register ichar_t *p;
1440+ register ichar_t *q;
1441+ register n;
1442+ register struct dent *dp;
1443+
1444+ /*
1445+ ** Make an uppercase copy of the word we are checking.
1446+ */
1447+ for (p = w, q = nword; *p; )
1448+ *q++ = mytoupper (*p++);
1449+ *q = 0;
1450+ n = q - nword;
1451+
1452+ numhits = 0;
1453+
1454+ if (cflag)
1455+ {
1456+ (void) printf ("%s", ichartosstr (w, 0));
1457+ orig_word = w;
1458+ }
1459+ else if ((dp = lookup (nword, 1)) != NULL)
1460+ {
1461+ hits[0].dictent = dp;
1462+ hits[0].prefix = NULL;
1463+ hits[0].suffix = NULL;
1464+#ifndef NO_CAPITALIZATION_SUPPORT
1465+ if (allhits || cap_ok (w, &hits[0], n))
1466+ numhits = 1;
1467+#else
1468+ numhits = 1;
1469+#endif
1470+ /*
1471+ * If we're looking for compounds, and this root doesn't
1472+ * participate in compound formation, undo the hit.
1473+ */
1474+ if (compoundflag == COMPOUND_CONTROLLED
1475+ && ((pfxopts | sfxopts) & FF_COMPOUNDONLY) != 0
1476+ && hashheader.compoundbit >= 0
1477+ && TSTMASKBIT (dp->mask, hashheader.compoundbit) == 0)
1478+ numhits = 0;
1479+ }
1480+ if (numhits && !allhits)
1481+ return 1;
1482+
1483+ /* try stripping off affixes */
1484+
1485+#if 0
1486+ numchars = icharlen (nword);
1487+ if (numchars < 4)
1488+ {
1489+ if (cflag)
1490+ (void) putchar ('\n');
1491+ return numhits || (numchars == 1);
1492+ }
1493+#endif
1494+
1495+ chk_aff (w, nword, n, ignoreflagbits, allhits, pfxopts, sfxopts);
1496+
1497+ if (cflag)
1498+ (void) putchar ('\n');
1499+
1500+ return numhits;
1501+}
1502+
1503+#ifndef NO_CAPITALIZATION_SUPPORT
1504+Public Logical
1505+cap_ok (register ichar_t *word, register struct success *hit, int len)
1506+{
1507+ register ichar_t * dword;
1508+ register ichar_t * w;
1509+ register struct dent * dent;
1510+ ichar_t dentword[INPUTWORDLEN + MAXAFFIXLEN];
1511+ int preadd;
1512+ int prestrip;
1513+ int sufadd;
1514+ ichar_t * limit;
1515+ long thiscap;
1516+ long dentcap;
1517+
1518+ thiscap = whatcap (word);
1519+ /*
1520+ ** All caps is always legal, regardless of affixes.
1521+ */
1522+ preadd = prestrip = sufadd = 0;
1523+ if (thiscap == ALLCAPS)
1524+ return 1;
1525+ else if (thiscap == FOLLOWCASE)
1526+ {
1527+ /* Set up some constants for the while(1) loop below */
1528+ if (hit->prefix)
1529+ {
1530+ preadd = hit->prefix->affl;
1531+ prestrip = hit->prefix->stripl;
1532+ }
1533+ else
1534+ preadd = prestrip = 0;
1535+ sufadd = hit->suffix ? hit->suffix->affl : 0;
1536+ }
1537+ /*
1538+ ** Search the variants for one that matches what we have. Note
1539+ ** that thiscap can't be ALLCAPS, since we already returned
1540+ ** for that case.
1541+ */
1542+ dent = hit->dictent;
1543+ while(True)
1544+ {
1545+ dentcap = captype (dent->flagfield);
1546+ if (dentcap != thiscap)
1547+ {
1548+ if (dentcap == ANYCASE && thiscap == CAPITALIZED
1549+ && entryhasaffixes (dent, hit))
1550+ return True;
1551+ }
1552+ else /* captypes match */
1553+ {
1554+ if (thiscap != FOLLOWCASE)
1555+ {
1556+ if (entryhasaffixes (dent, hit))
1557+ return True;
1558+ }
1559+ else
1560+ {
1561+ /*
1562+ ** Make sure followcase matches exactly.
1563+ ** Life is made more difficult by the
1564+ ** possibility of affixes. Start with
1565+ ** the prefix.
1566+ */
1567+ (void) strtoichar (dentword, dent->word, INPUTWORDLEN, 1);
1568+ dword = dentword;
1569+ limit = word + preadd;
1570+ if (myupper (dword[prestrip]))
1571+ {
1572+ for (w = word; w < limit; w++)
1573+ {
1574+ if (mylower (*w))
1575+ goto doublecontinue;
1576+ }
1577+ }
1578+ else
1579+ {
1580+ for (w = word; w < limit; w++)
1581+ {
1582+ if (myupper (*w))
1583+ goto doublecontinue;
1584+ }
1585+ }
1586+ dword += prestrip;
1587+ /* Do root part of word */
1588+ limit = dword + len - preadd - sufadd;
1589+ while (dword < limit)
1590+ {
1591+ if (*dword++ != *w++)
1592+ goto doublecontinue;
1593+ }
1594+ /* Do suffix */
1595+ dword = limit - 1;
1596+ if (myupper (*dword))
1597+ {
1598+ for ( ; *w; w++)
1599+ {
1600+ if (mylower (*w))
1601+ goto doublecontinue;
1602+ }
1603+ }
1604+ else
1605+ {
1606+ for ( ; *w; w++)
1607+ {
1608+ if (myupper (*w))
1609+ goto doublecontinue;
1610+ }
1611+ }
1612+ /*
1613+ ** All failure paths go to "doublecontinue,"
1614+ ** so if we get here it must match.
1615+ */
1616+ if (entryhasaffixes (dent, hit))
1617+ return True;
1618+doublecontinue: ;
1619+ }
1620+ }
1621+ if ((dent->flagfield & MOREVARIANTS) == 0)
1622+ break;
1623+ dent = dent->next;
1624+ }
1625+
1626+ /* No matches found */
1627+ return False;
1628+}
1629+
1630+/*
1631+** See if this particular capitalization (dent) is legal with these
1632+** particular affixes.
1633+*/
1634+Local Logical
1635+entryhasaffixes (register struct dent *dent, register struct success *hit)
1636+{
1637+
1638+ if (hit->prefix && !TSTMASKBIT (dent->mask, hit->prefix->flagbit))
1639+ return False;
1640+ if (hit->suffix && !TSTMASKBIT (dent->mask, hit->suffix->flagbit))
1641+ return False;
1642+ return True; /* Yes, these affixes are legal */
1643+}
1644+#endif
1645+
1646+/*
1647+ * Print a word and its flag, making sure the case of the output matches
1648+ * the case of the original found in "orig_word".
1649+ */
1650+Public void
1651+flagpr (register ichar_t *word, /* (Modified) word to print */
1652+ int preflag, /* Prefix flag (if any) */
1653+ int prestrip, /* Lth of pfx stripped off orig_word */
1654+ int preadd, /* Length of prefix added to w */
1655+ int sufflag, /* Suffix flag (if any) */
1656+ int sufadd) /* Length of suffix added to w */
1657+{
1658+ register ichar_t * origp; /* Pointer into orig_word */
1659+ int orig_len; /* Length of orig_word */
1660+
1661+ orig_len = icharlen (orig_word);
1662+ /*
1663+ * We refuse to print if the cases outside the modification
1664+ * points don't match those just inside. This prevents things
1665+ * like "OEM's" from being turned into "OEM/S" which expands
1666+ * only to "OEM'S".
1667+ */
1668+ if (preflag > 0)
1669+ {
1670+ origp = orig_word + preadd;
1671+ if (myupper (*origp))
1672+ {
1673+ for (origp = orig_word; origp < orig_word + preadd; origp++)
1674+ {
1675+ if (mylower (*origp))
1676+ return;
1677+ }
1678+ }
1679+ else
1680+ {
1681+ for (origp = orig_word; origp < orig_word + preadd; origp++)
1682+ {
1683+ if (myupper (*origp))
1684+ return;
1685+ }
1686+ }
1687+ }
1688+ if (sufflag > 0)
1689+ {
1690+ origp = orig_word + orig_len - sufadd;
1691+ if (myupper (origp[-1]))
1692+ {
1693+ for ( ; *origp != 0; origp++)
1694+ {
1695+ if (mylower (*origp))
1696+ return;
1697+ }
1698+ }
1699+ else
1700+ {
1701+ origp = orig_word + orig_len - sufadd;
1702+ for ( ; *origp != 0; origp++)
1703+ {
1704+ if (myupper (*origp))
1705+ return;
1706+ }
1707+ }
1708+ }
1709+ /*
1710+ * The cases are ok. Put out the word, being careful that the
1711+ * prefix/suffix cases match those in the original, and that the
1712+ * unchanged characters from the original actually match it.
1713+ */
1714+ (void) putchar (' ');
1715+ origp = orig_word + preadd;
1716+ if (myupper (*origp))
1717+ {
1718+ while (--prestrip >= 0)
1719+ (void) fputs (printichar ((int) *word++), stdout);
1720+ }
1721+ else
1722+ {
1723+ while (--prestrip >= 0)
1724+ (void) fputs (printichar ((int) mytolower (*word++)), stdout);
1725+ }
1726+ for (prestrip = orig_len - preadd - sufadd; --prestrip >= 0; word++)
1727+ (void) fputs (printichar ((int) *origp++), stdout);
1728+ if (origp > orig_word)
1729+ origp--;
1730+ if (myupper (*origp))
1731+ (void) fputs (ichartosstr (word, 0), stdout);
1732+ else
1733+ {
1734+ while (*word)
1735+ {
1736+ (void) fputs (printichar ((int) mytolower (*word++)), stdout);
1737+ }
1738+ }
1739+ /*
1740+ * Now put out the flags
1741+ */
1742+ (void) putchar (hashheader.flagmarker);
1743+ if (preflag > 0)
1744+ (void) putchar (preflag);
1745+ if (sufflag > 0)
1746+ (void) putchar (sufflag);
1747+}
41e3656f 1748diff -ruN vim62./src/spell/hash.c vim62/src/spell/hash.c
1749--- vim62./src/spell/hash.c 1970-01-01 01:00:00.000000000 +0100
1750+++ vim62/src/spell/hash.c 2003-06-02 19:57:21.000000000 +0200
24ec98f0
JB
1751@@ -0,0 +1,91 @@
1752+/*
1753+ * hash.c - a simple hash function for ispell
1754+ *
1755+ * Pace Willisson, 1983
1756+ *
1757+ * Copyright 1992, 1993, Geoff Kuenning, Granada Hills, CA
1758+ * All rights reserved.
1759+ *
1760+ * Redistribution and use in source and binary forms, with or without
1761+ * modification, are permitted provided that the following conditions
1762+ * are met:
1763+ *
1764+ * 1. Redistributions of source code must retain the above copyright
1765+ * notice, this list of conditions and the following disclaimer.
1766+ * 2. Redistributions in binary form must reproduce the above copyright
1767+ * notice, this list of conditions and the following disclaimer in the
1768+ * documentation and/or other materials provided with the distribution.
1769+ * 3. All modifications to the source code must be clearly marked as
1770+ * such. Binary redistributions based on modified source code
1771+ * must be clearly marked as modified versions in the documentation
1772+ * and/or other materials provided with the distribution.
1773+ * 4. All advertising materials mentioning features or use of this software
1774+ * must display the following acknowledgment:
1775+ * This product includes software developed by Geoff Kuenning and
1776+ * other unpaid contributors.
1777+ * 5. The name of Geoff Kuenning may not be used to endorse or promote
1778+ * products derived from this software without specific prior
1779+ * written permission.
1780+ *
1781+ * THIS SOFTWARE IS PROVIDED BY GEOFF KUENNING AND CONTRIBUTORS ``AS IS'' AND
1782+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
1783+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
1784+ * ARE DISCLAIMED. IN NO EVENT SHALL GEOFF KUENNING OR CONTRIBUTORS BE LIABLE
1785+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
1786+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
1787+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
1788+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
1789+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
1790+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
1791+ * SUCH DAMAGE.
1792+ */
1793+
1794+/*
1795+ * $Log$
1796+ * Revision 1.20 1994/01/25 07:11:34 geoff
1797+ * Get rid of all old RCS log lines in preparation for the 3.1 release.
1798+ *
1799+ */
1800+
1801+#include "ispell.h"
1802+
1803+/*
1804+ * The following hash algorithm is due to Ian Dall, with slight modifications
1805+ * by Geoff Kuenning to reflect the results of testing with the English
1806+ * dictionaries actually distributed with ispell.
1807+ */
1808+#define HASHSHIFT 5
1809+
1810+#ifdef NO_CAPITALIZATION_SUPPORT
1811+#define HASHUPPER(c) c
1812+#else /* NO_CAPITALIZATION_SUPPORT */
1813+#define HASHUPPER(c) mytoupper(c)
1814+#endif /* NO_CAPITALIZATION_SUPPORT */
1815+
1816+Public int
1817+hash (
1818+ register ichar_t * s,
1819+ register int hashtblsize)
1820+{
1821+ register long h = 0;
1822+ register int i;
1823+
1824+#ifdef ICHAR_IS_CHAR
1825+ for (i = 4; i-- && *s != 0; )
1826+ h = (h << 8) | HASHUPPER (*s++);
1827+#else /* ICHAR_IS_CHAR */
1828+ for (i = 2; i-- && *s != 0; )
1829+ h = (h << 16) | HASHUPPER (*s++);
1830+#endif /* ICHAR_IS_CHAR */
1831+ while (*s != 0)
1832+ {
1833+ /*
1834+ * We have to do circular shifts the hard way, since C doesn't
1835+ * have them even though the hardware probably does. Oh, well.
1836+ */
1837+ h = (h << HASHSHIFT) |
1838+ ((h >> (32 - HASHSHIFT)) & ((1 << HASHSHIFT) - 1));
1839+ h ^= HASHUPPER (*s++);
1840+ }
1841+ return (unsigned long) h % hashtblsize;
1842+}
41e3656f 1843diff -ruN vim62./src/spell/i_proto.h vim62/src/spell/i_proto.h
1844--- vim62./src/spell/i_proto.h 1970-01-01 01:00:00.000000000 +0100
1845+++ vim62/src/spell/i_proto.h 2003-06-02 19:57:21.000000000 +0200
24ec98f0
JB
1846@@ -0,0 +1,112 @@
1847+Global int addvheader (struct dent * ent);
1848+Global void askmode (void);
1849+Global void backup (void);
1850+#ifndef NO_CAPITALIZATION_SUPPORT
1851+Global Logical cap_ok (ichar_t * word, struct success * hit, int len);
1852+#endif /* NO_CAPITALIZATION_SUPPORT */
1853+Global void chupcase (char * s);
1854+Global void checkfile (void);
1855+Global void checkline (FILE * ofile);
1856+Global void chk_aff (ichar_t * word, ichar_t * ucword, int len,
1857+ int ignoreflagbits, int allhits, int pfxopts, int sfxopts);
1858+Global int combinecaps (struct dent * hdr, struct dent * newent);
1859+Global int compoundgood (ichar_t * word, int pfxopts);
1860+Global void copyout (char ** cc, int cnt);
1861+Global void correct (char * ctok, int ctokl, ichar_t * itok, int itokl,
1862+ char ** curchar);
1863+Global char * do_regex_lookup (char * expr, int whence);
1864+Global SIGNAL_TYPE done (int);
1865+Global void dumpmode (void);
1866+Global void erase (void);
1867+Global int expand_pre (char * croot, ichar_t * rootword,
1868+ MASKTYPE mask[], int option, char *extra);
1869+Global int expand_suf (char * croot, ichar_t * rootword,
1870+ MASKTYPE mask[], int crossonly, int option, char * extra);
1871+Global int findfiletype (char * name, int searchnames,
1872+ int * deformatter);
1873+Global void flagpr (ichar_t * word, int preflag, int prestrip,
1874+ int preadd, int sufflag, int sufadd);
1875+Global void givehelp (int interactive);
1876+Global int good (ichar_t * word, int ignoreflagbits, int allhits,
1877+ int pfxopts, int sfxopts);
1878+Global int hash (ichar_t * word, int hashtablesize);
1879+#ifndef ICHAR_IS_CHAR
1880+Global int icharcmp (ichar_t * s1, ichar_t * s2);
1881+Global ichar_t * icharcpy (ichar_t * out, ichar_t * in);
1882+Global int icharlen (ichar_t * str);
1883+Global int icharncmp (ichar_t * s1, ichar_t * s2, int n);
1884+#endif /* ICHAR_IS_CHAR */
1885+Global int ichartostr (char * out, ichar_t * in, int outlen,
1886+ int canonical);
1887+Global char * ichartosstr (ichar_t * in, int canonical);
1888+Global void inverse (void);
1889+Global struct dent * lookup (ichar_t * word, int dotree);
1890+Global void lowcase (ichar_t * string);
1891+Global int makedent (char * lbuf, int lbuflen, struct dent * d);
1892+Global void makepossibilities (ichar_t * word);
1893+Global void move (int row, int col);
1894+Global void normal (void);
1895+Global char * printichar (int in);
1896+#ifdef USESH
1897+Global int shellescape (char * buf);
1898+Global void shescape (char * buf);
1899+#else /* USESH */
1900+#ifndef REGEX_LOOKUP
1901+Global int shellescape (char * buf);
1902+#endif /* REGEX_LOOKUP */
1903+#endif /* USESH */
1904+Global char * skipoverword (char * bufp);
1905+Global void stop (void);
1906+Global int stringcharlen (char * bufp, int canonical);
1907+Global int strtoichar (ichar_t * out, char * in, int outlen,
1908+ int canonical);
1909+Global ichar_t * strtosichar (char * in, int canonical);
1910+Global void terminit (void);
1911+Global void toutent (FILE * outfile, struct dent * hent, int onlykeep);
1912+Global void treeinit (char * persdict, char * LibDict);
1913+Global void treeinsert (char * word, int wordlen, int keep);
1914+Global struct dent * treelookup (ichar_t * word);
1915+Global void treeoutput (void);
1916+Global void upcase (ichar_t * string);
1917+#ifndef NO_CAPITALIZATION_SUPPORT
1918+Global long whatcap (ichar_t * word);
1919+#endif
1920+Global char * xgets (char * string, int size, FILE * stream);
1921+Global void yyinit (void);
1922+Global Logical yyopen (char * file);
1923+Global int yyparse (void);
1924+
1925+#include <string.h>
1926+
1927+#ifdef REGEX_LOOKUP
1928+# ifdef USG
1929+Global char * regcmp (const char * expr, const char * terminator, ...);
1930+Global char * regex (const char * pat, const char * subject, ...);
1931+# else
1932+Global char * re_comp (const char * expr);
1933+Global int * re_exec (const char * pat);
1934+# endif
1935+#endif
1936+/* WM
1937+Global int tgetent (char * buf, const char * termname);
1938+Global int tgetnum (const char * id);
1939+Global char * tgetstr (const char * id, char ** area);
1940+Global char * tgoto (const char * cm, int col, int row);
1941+Global char * tputs (const char * str, int pad, int (*func) (int ch);
1942+*/
1943+
1944+Global char * mypath_rindex(char const *str, char c);
1945+Global void save_root_cap (ichar_t * word, ichar_t * pattern,
1946+ int prestrip, int preadd, int sufstrip, int sufadd,
1947+ struct dent * firstdent, struct flagent * pfxent,
1948+ struct flagent * sufent,
1949+ ichar_t savearea[MAX_CAPS][INPUTWORDLEN + MAXAFFIXLEN],
1950+ int * nsaved);
1951+Global int casecmp (char * a, char * b, int canonical);
1952+Global int ins_root_cap (ichar_t * word, ichar_t * pattern,
1953+ int prestrip, int preadd, int sufstrip, int sufadd,
1954+ struct dent * firstdent, struct flagent * pfxent,
1955+ struct flagent * sufent);
1956+Global int insert(register ichar_t * word);
1957+Global char * linit (char *);
1958+Global char * last_slash (char *file);
41e3656f 1959diff -ruN vim62./src/spell/ispell.h vim62/src/spell/ispell.h
1960--- vim62./src/spell/ispell.h 1970-01-01 01:00:00.000000000 +0100
1961+++ vim62/src/spell/ispell.h 2003-06-02 19:57:21.000000000 +0200
35c7515f 1962@@ -0,0 +1,611 @@
24ec98f0
JB
1963+/*
1964+ * $Id$
1965+ */
1966+
1967+/*
1968+ * Copyright 1992, 1993, Geoff Kuenning, Granada Hills, CA
1969+ * All rights reserved.
1970+ *
1971+ * Redistribution and use in source and binary forms, with or without
1972+ * modification, are permitted provided that the following conditions
1973+ * are met:
1974+ *
1975+ * 1. Redistributions of source code must retain the above copyright
1976+ * notice, this list of conditions and the following disclaimer.
1977+ * 2. Redistributions in binary form must reproduce the above copyright
1978+ * notice, this list of conditions and the following disclaimer in the
1979+ * documentation and/or other materials provided with the distribution.
1980+ * 3. All modifications to the source code must be clearly marked as
1981+ * such. Binary redistributions based on modified source code
1982+ * must be clearly marked as modified versions in the documentation
1983+ * and/or other materials provided with the distribution.
1984+ * 4. All advertising materials mentioning features or use of this software
1985+ * must display the following acknowledgment:
1986+ * This product includes software developed by Geoff Kuenning and
1987+ * other unpaid contributors.
1988+ * 5. The name of Geoff Kuenning may not be used to endorse or promote
1989+ * products derived from this software without specific prior
1990+ * written permission.
1991+ *
1992+ * THIS SOFTWARE IS PROVIDED BY GEOFF KUENNING AND CONTRIBUTORS ``AS IS'' AND
1993+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
1994+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
1995+ * ARE DISCLAIMED. IN NO EVENT SHALL GEOFF KUENNING OR CONTRIBUTORS BE LIABLE
1996+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
1997+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
1998+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
1999+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
2000+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
2001+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
2002+ * SUCH DAMAGE.
2003+ */
2004+
2005+/*
2006+ * $Log$
2007+ * Revision 1.68 1995/03/06 02:42:41 geoff
2008+ * Be vastly more paranoid about parenthesizing macro arguments. This
2009+ * fixes a bug in defmt.c where a complex argument was passed to
2010+ * isstringch.
2011+ *
2012+ * Revision 1.67 1995/01/03 19:24:12 geoff
2013+ * Get rid of a non-global declaration.
2014+ *
2015+ * Revision 1.66 1994/12/27 23:08:49 geoff
2016+ * Fix a lot of subtly bad assumptions about the widths of ints and longs
2017+ * which only show up on 64-bit machines like the Cray and the DEC Alpha.
2018+ *
2019+ * Revision 1.65 1994/11/02 06:56:10 geoff
2020+ * Remove the anyword feature, which I've decided is a bad idea.
2021+ *
2022+ * Revision 1.64 1994/10/25 05:46:18 geoff
2023+ * Add the FF_ANYWORD flag for defining an affix that will apply to any
2024+ * word, even if not explicitly specified. (Good for French.)
2025+ *
2026+ * Revision 1.63 1994/09/16 04:48:28 geoff
2027+ * Make stringdups and laststringch unsigned ints, and dupnos a plain
2028+ * int, so that we can handle more than 128 stringchars and stringchar
2029+ * types.
2030+ *
2031+ * Revision 1.62 1994/09/01 06:06:39 geoff
2032+ * Change erasechar/killchar to uerasechar/ukillchar to avoid
2033+ * shared-library problems on HP systems.
2034+ *
2035+ * Revision 1.61 1994/08/31 05:58:35 geoff
2036+ * Add contextoffset, used in -a mode to handle extremely long lines.
2037+ *
2038+ * Revision 1.60 1994/05/17 06:44:15 geoff
2039+ * Add support for controlled compound formation and the COMPOUNDONLY
2040+ * option to affix flags.
2041+ *
2042+ * Revision 1.59 1994/03/15 06:25:16 geoff
2043+ * Change deftflag's initialization so we can tell if -t/-n appeared.
2044+ *
2045+ * Revision 1.58 1994/02/07 05:53:28 geoff
2046+ * Add typecasts to the the 7-bit versions of ichar* routines
2047+ *
2048+ * Revision 1.57 1994/01/25 07:11:48 geoff
2049+ * Get rid of all old RCS log lines in preparation for the 3.1 release.
2050+ *
2051+ */
2052+
2053+#include <stdio.h>
2054+#include "config.h"
2055+
2056+#ifdef NO8BIT
2057+#define SET_SIZE 128
2058+#else
2059+#define SET_SIZE 256
2060+#endif
2061+
2062+#define MASKSIZE (MASKBITS / MASKTYPE_WIDTH)
2063+
2064+/* The following is really testing for MASKSIZE <= 1, but cpp can't do that */
2065+#if MASKBITS <= MASKTYPE_WIDTH
2066+#define SETMASKBIT(mask, bit) ((mask)[0] |= (MASKTYPE) 1 << (bit))
2067+#define CLRMASKBIT(mask, bit) ((mask)[0] &= (MASKTYPE) ~(1 << (bit)))
2068+#define TSTMASKBIT(mask, bit) ((mask)[0] & ((MASKTYPE) 1 << (bit)))
2069+#else
2070+#define SETMASKBIT(mask, bit) \
2071+ ((mask)[(bit) / MASKTYPE_WIDTH] |= \
2072+ (MASKTYPE) 1 << ((bit) & (MASKTYPE_WIDTH - 1)))
2073+#define CLRMASKBIT(mask, bit) \
2074+ ((mask)[(bit) / MASKTYPE_WIDTH] &= \
2075+ ~((MASKTYPE) 1 << ((bit) & (MASKTYPE_WIDTH - 1))))
2076+#define TSTMASKBIT(mask, bit) \
2077+ ((mask)[(bit) / MASKTYPE_WIDTH] & \
2078+ ((MASKTYPE) 1 << ((bit) & (MASKTYPE_WIDTH - 1))))
2079+#endif
2080+
2081+#if MASKBITS > 64
2082+#define FULLMASKSET
2083+#endif
2084+
2085+#if MASKBITS <= 32
2086+# ifndef lint
2087+#define BITTOCHAR(bit) ((bit) + 'A')
2088+#define CHARTOBIT(ch) ((ch) - 'A')
2089+# endif /* lint */
2090+#define LARGESTFLAG 26 /* 5 are needed for flagfield below */
2091+#define FLAGBASE ((MASKTYPE_WIDTH) - 6)
2092+#else
2093+# if MASKBITS <= 64
2094+# ifndef lint
2095+#define BITTOCHAR(bit) ((bit) + 'A')
2096+#define CHARTOBIT(ch) ((ch) - 'A')
2097+# endif /* lint */
2098+#define LARGESTFLAG (64 - 6) /* 5 are needed for flagfield below */
2099+#define FLAGBASE ((MASKTYPE_WIDTH) - 6)
2100+# else
2101+# ifndef lint
2102+#define BITTOCHAR(bit) (bit)
2103+#define CHARTOBIT(ch) (ch)
2104+# endif /* lint */
2105+#define LARGESTFLAG MASKBITS /* flagfield is a separate field */
2106+#define FLAGBASE 0
2107+# endif
2108+#endif
2109+
2110+/*
2111+** Data type for internal word storage. If necessary, we use shorts rather
2112+** than chars so that string characters can be encoded as a single unit.
2113+*/
2114+#if (SET_SIZE + MAXSTRINGCHARS) <= 256
2115+#ifndef lint
2116+#define ICHAR_IS_CHAR
2117+#endif /* lint */
2118+#endif
2119+
2120+#ifdef ICHAR_IS_CHAR
2121+typedef unsigned char ichar_t; /* Internal character */
2122+#define icharlen(s) strlen ((char *) (s))
2123+#define icharcpy(a, b) strcpy ((char *) (a), (char *) (b))
2124+#define icharcmp(a, b) strcmp ((char *) (a), (char *) (b))
2125+#define icharncmp(a, b, n) strncmp ((char *) (a), (char *) (b), (n))
2126+#define chartoichar(x) ((ichar_t) (x))
2127+#else
2128+typedef unsigned short ichar_t; /* Internal character */
2129+#define chartoichar(x) ((ichar_t) (unsigned char) (x))
2130+#endif
2131+
2132+struct dent
2133+ {
2134+ struct dent * next;
2135+ char * word;
2136+ MASKTYPE mask[MASKSIZE];
2137+#ifdef FULLMASKSET
2138+ char flags;
2139+#endif
2140+ };
2141+
2142+/*
2143+** Flags in the directory entry. If FULLMASKSET is undefined, these are
2144+** stored in the highest bits of the last longword of the mask field. If
2145+** FULLMASKSET is defined, they are stored in the extra "flags" field.
2146+#ifndef NO_CAPITALIZATION_SUPPORT
2147+**
2148+** If a word has only one capitalization form, and that form is not
2149+** FOLLOWCASE, it will have exactly one entry in the dictionary. The
2150+** legal capitalizations will be indicated by the 2-bit capitalization
2151+** field, as follows:
2152+**
2153+** ALLCAPS The word must appear in all capitals.
2154+** CAPITALIZED The word must be capitalized (e.g., London).
2155+** It will also be accepted in all capitals.
2156+** ANYCASE The word may appear in lowercase, capitalized,
2157+** or all-capitals.
2158+**
2159+** Regardless of the capitalization flags, the "word" field of the entry
2160+** will point to an all-uppercase copy of the word. This is to simplify
2161+** the large portion of the code that doesn't care about capitalization.
2162+** Ispell will generate the correct version when needed.
2163+**
2164+** If a word has more than one capitalization, there will be multiple
2165+** entries for it, linked together by the "next" field. The initial
2166+** entry for such words will be a dummy entry, primarily for use by code
2167+** that ignores capitalization. The "word" field of this entry will
2168+** again point to an all-uppercase copy of the word. The "mask" field
2169+** will contain the logical OR of the mask fields of all variants.
2170+** A header entry is indicated by a capitalization type of ALLCAPS,
2171+** with the MOREVARIANTS bit set.
2172+**
2173+** The following entries will define the individual variants. Each
2174+** entry except the last has the MOREVARIANTS flag set, and each
2175+** contains one of the following capitalization options:
2176+**
2177+** ALLCAPS The word must appear in all capitals.
2178+** CAPITALIZED The word must be capitalized (e.g., London).
2179+** It will also be accepted in all capitals.
2180+** FOLLOWCASE The word must be capitalized exactly like the
2181+** sample in the entry. Prefix (suffix) characters
2182+** must be rendered in the case of the first (last)
2183+** "alphabetic" character. It will also be accepted
2184+** in all capitals. ("Alphabetic" means "mentioned
2185+** in a 'casechars' statement".)
2186+** ANYCASE The word may appear in lowercase, capitalized,
2187+** or all-capitals.
2188+**
2189+** The "mask" field for the entry contains only the affix flag bits that
2190+** are legal for that capitalization. The "word" field will be null
2191+** except for FOLLOWCASE entries, where it will point to the
2192+** correctly-capitalized spelling of the root word.
2193+**
2194+** It is worth discussing why the ALLCAPS option is used in
2195+** the header entry. The header entry accepts an all-capitals
2196+** version of the root plus every affix (this is always legal, since
2197+** words get capitalized in headers and so forth). Further, all of
2198+** the following variant entries will reject any all-capitals form
2199+** that is illegal due to an affix.
2200+**
2201+** Finally, note that variations in the KEEP flag can cause a multiple-variant
2202+** entry as well. For example, if the personal dictionary contains "ALPHA",
2203+** (KEEP flag set) and the user adds "alpha" with the KEEP flag clear, a
2204+** multiple-variant entry will be created so that "alpha" will be accepted
2205+** but only "ALPHA" will actually be kept.
2206+#endif
2207+*/
2208+#ifdef FULLMASKSET
2209+#define flagfield flags
2210+#else
2211+#define flagfield mask[MASKSIZE - 1]
2212+#endif
2213+#define USED ((MASKTYPE) 1 << (FLAGBASE + 0))
2214+#define KEEP ((MASKTYPE) 1 << (FLAGBASE + 1))
2215+#ifdef NO_CAPITALIZATION_SUPPORT
2216+#define ALLFLAGS (USED | KEEP)
2217+#else /* NO_CAPITALIZATION_SUPPORT */
2218+#define ANYCASE ((MASKTYPE) 0 << (FLAGBASE + 2))
2219+#define ALLCAPS ((MASKTYPE) 1 << (FLAGBASE + 2))
2220+#define CAPITALIZED ((MASKTYPE) 2 << (FLAGBASE + 2))
2221+#define FOLLOWCASE ((MASKTYPE) 3 << (FLAGBASE + 2))
2222+#define CAPTYPEMASK ((MASKTYPE) 3 << (FLAGBASE + 2))
2223+#define MOREVARIANTS ((MASKTYPE) 1 << (FLAGBASE + 4))
2224+#define ALLFLAGS (USED | KEEP | CAPTYPEMASK | MOREVARIANTS)
2225+#define captype(x) ((x) & CAPTYPEMASK)
2226+#endif /* NO_CAPITALIZATION_SUPPORT */
2227+
2228+/*
2229+ * Language tables used to encode prefix and suffix information.
2230+ */
2231+struct flagent
2232+ {
2233+ ichar_t * strip; /* String to strip off */
2234+ ichar_t * affix; /* Affix to append */
2235+ short flagbit; /* Flag bit this ent matches */
2236+ short stripl; /* Length of strip */
2237+ short affl; /* Length of affix */
2238+ short numconds; /* Number of char conditions */
2239+ short flagflags; /* Modifiers on this flag */
2240+ char conds[SET_SIZE + MAXSTRINGCHARS]; /* Adj. char conds */
2241+ };
2242+
2243+/*
2244+ * Bits in flagflags
2245+ */
2246+#define FF_CROSSPRODUCT (1 << 0) /* Affix does cross-products */
2247+#define FF_COMPOUNDONLY (1 << 1) /* Afx works in compounds */
2248+
2249+union ptr_union /* Aid for building flg ptrs */
2250+ {
2251+ struct flagptr * fp; /* Pointer to more indexing */
2252+ struct flagent * ent; /* First of a list of ents */
2253+ };
2254+
2255+struct flagptr
2256+ {
2257+ union ptr_union pu; /* Ent list or more indexes */
2258+ int numents; /* If zero, pu.fp is valid */
2259+ };
2260+
2261+/*
2262+ * Description of a single string character type.
2263+ */
2264+struct strchartype
2265+ {
2266+ char * name; /* Name of the type */
2267+ char * deformatter; /* Deformatter to use */
2268+ char * suffixes; /* File suffixes, null seps */
2269+ };
2270+
2271+/*
2272+ * Header placed at the beginning of the hash file.
2273+ */
2274+struct hashheader
2275+ {
2276+ unsigned short magic; /* Magic number for ID */
2277+ unsigned short compileoptions; /* How we were compiled */
2278+ short maxstringchars; /* Max # strchrs we support */
2279+ short maxstringcharlen; /* Max strchr len supported */
2280+ short compoundmin; /* Min lth of compound parts */
2281+ short compoundbit; /* Flag 4 compounding roots */
2282+ unsigned int stringsize; /* Size of string table */
2283+ int lstringsize; /* Size of lang. str tbl */
2284+ unsigned int tblsize; /* No. entries in hash tbl */
2285+ int stblsize; /* No. entries in sfx tbl */
2286+ int ptblsize; /* No. entries in pfx tbl */
2287+ int sortval; /* Largest sort ID assigned */
2288+ int nstrchars; /* No. strchars defined */
2289+ int nstrchartype; /* No. strchar types */
2290+ int strtypestart; /* Start of strtype table */
2291+ char nrchars[5]; /* Nroff special characters */
2292+ char texchars[13]; /* TeX special characters */
2293+#define TeXleftparen texchars[0]
2294+#define TeXrightparen texchars[1]
2295+#define TeXleftsquare texchars[2]
2296+#define TeXrightsquare texchars[3]
2297+#define TeXleftcurly texchars[4]
2298+#define TeXrightcurly texchars[5]
2299+#define TeXlefttangle texchars[6]
2300+#define TeXrighttangle texchars[7]
2301+#define TeXbackslash texchars[8]
2302+#define TeXdollar texchars[9]
2303+#define TeXstar texchars[10]
2304+#define TeXdot texchars[11]
2305+#define TeXpercent texchars[12]
2306+ char compoundflag; /* Compund-word handling */
2307+ char defhardflag; /* Default tryveryhard flag */
2308+ char flagmarker; /* "Start-of-flags" char */
2309+ unsigned short sortorder[SET_SIZE + MAXSTRINGCHARS]; /* Sort ordering */
2310+ ichar_t lowerconv[SET_SIZE + MAXSTRINGCHARS]; /* Lower-conversion table */
2311+ ichar_t upperconv[SET_SIZE + MAXSTRINGCHARS]; /* Upper-conversion table */
2312+ char wordchars[SET_SIZE + MAXSTRINGCHARS]; /* NZ for chars found in wrds */
2313+ char upperchars[SET_SIZE + MAXSTRINGCHARS]; /* NZ for uppercase chars */
2314+ char lowerchars[SET_SIZE + MAXSTRINGCHARS]; /* NZ for lowercase chars */
2315+ char boundarychars[SET_SIZE + MAXSTRINGCHARS]; /* NZ for boundary chars */
2316+ char stringstarts[SET_SIZE]; /* NZ if char can start str */
2317+ char stringchars[MAXSTRINGCHARS][MAXSTRINGCHARLEN + 1]; /* String chars */
2318+ unsigned int stringdups[MAXSTRINGCHARS]; /* No. of "base" char */
2319+ int dupnos[MAXSTRINGCHARS]; /* Dup char ID # */
2320+ unsigned short magic2; /* Second magic for dbl chk */
2321+ };
2322+
2323+/* hash table magic number */
2324+#define SPELL_MAGIC 0x9602
2325+
2326+/* compile options, put in the hash header for consistency checking */
35c7515f
JB
2327+# define MAGICNOTUSED1 0x01
2328+# define MAGICNOTUSED2 0x02
24ec98f0
JB
2329+#if MASKBITS <= 32
2330+# define MAGICMASKSET 0x00
2331+#else
2332+# if MASKBITS <= 64
2333+# define MAGICMASKSET 0x04
2334+# else
2335+# if MASKBITS <= 128
2336+# define MAGICMASKSET 0x08
2337+# else
2338+# define MAGICMASKSET 0x0C
2339+# endif
2340+# endif
2341+#endif
2342+
35c7515f 2343+#define COMPILEOPTIONS (MAGICNOTUSED1 | MAGICNOTUSED2 | MAGICMASKSET)
24ec98f0
JB
2344+
2345+/*
2346+ * Structure used to record data about successful lookups; these values
2347+ * are used in the ins_root_cap routine to produce correct capitalizations.
2348+ */
2349+struct success
2350+ {
2351+ struct dent * dictent; /* Header of dict entry chain for wd */
2352+ struct flagent * prefix; /* Prefix flag used, or NULL */
2353+ struct flagent * suffix; /* Suffix flag used, or NULL */
2354+ };
2355+
2356+/*
2357+** Offsets into the nroff special-character array
2358+*/
2359+#define NRLEFTPAREN hashheader.nrchars[0]
2360+#define NRRIGHTPAREN hashheader.nrchars[1]
2361+#define NRDOT hashheader.nrchars[2]
2362+#define NRBACKSLASH hashheader.nrchars[3]
2363+#define NRSTAR hashheader.nrchars[4]
2364+
2365+/*
2366+** Values for compoundflag
2367+*/
2368+#define COMPOUND_NEVER 0 /* Compound words are never good */
2369+#define COMPOUND_ANYTIME 1 /* Accept run-together words */
2370+#define COMPOUND_CONTROLLED 2 /* Compounds controlled by afx flags */
2371+
2372+/*
2373+** The isXXXX macros normally only check ASCII range, and don't support
2374+** the character sets of other languages. These private versions handle
2375+** whatever character sets have been defined in the affix files.
2376+*/
2377+#define myupper(X) (hashheader.upperchars[(X)])
2378+#define mylower(X) (hashheader.lowerchars[(X)])
2379+#define myspace(X) (((X) > 0) && ((X) < 0x80) \
2380+ && isspace((unsigned char) (X)))
2381+#define iswordch(X) (hashheader.wordchars[(X)])
2382+#define isboundarych(X) (hashheader.boundarychars[(X)])
2383+#define isstringstart(X) (hashheader.stringstarts[(unsigned char) (X)])
2384+#define mytolower(X) (hashheader.lowerconv[(X)])
2385+#define mytoupper(X) (hashheader.upperconv[(X)])
2386+
2387+/*
2388+** These macros are similar to the ones above, but they take into account
2389+** the possibility of string characters. Note well that they take a POINTER,
2390+** not a character.
2391+**
2392+** The "l_" versions set "len" to the length of the string character as a
2393+** handy side effect. (Note that the global "laststringch" is also set,
2394+** and sometimes used, by these macros.)
2395+**
2396+** The "l1_" versions go one step further and guarantee that the "len"
2397+** field is valid for *all* characters, being set to 1 even if the macro
2398+** returns false. This macro is a great example of how NOT to write
2399+** readable C.
2400+*/
2401+#define isstringch(ptr, canon) (isstringstart (*(ptr)) \
2402+ && stringcharlen ((ptr), (canon)) > 0)
2403+#define l_isstringch(ptr, len, canon) \
2404+ (isstringstart (*(ptr)) \
2405+ && (len = stringcharlen ((ptr), (canon))) \
2406+ > 0)
2407+#define l1_isstringch(ptr, len, canon) \
2408+ (len = 1, \
2409+ isstringstart (*(ptr)) \
2410+ && ((len = \
2411+ stringcharlen ((ptr), (canon))) \
2412+ > 0 \
2413+ ? 1 : (len = 1, 0)))
2414+
2415+/*
2416+ * Sizes of buffers returned by ichartosstr/strtosichar.
2417+ */
2418+#define ICHARTOSSTR_SIZE (INPUTWORDLEN + 4 * MAXAFFIXLEN + 4)
2419+#define STRTOSICHAR_SIZE ((INPUTWORDLEN + 4 * MAXAFFIXLEN + 4) \
2420+ * sizeof (ichar_t))
2421+
2422+/*
2423+ * termcap variables
2424+ */
2425+#ifdef MAIN
2426+# define S_EXTERN /* nothing */
2427+#define Global
2428+#else
2429+#define Global extern
2430+# define S_EXTERN extern
2431+#endif
2432+
2433+#include "wm.h"
2434+
2435+
2436+S_EXTERN char * BC; /* backspace if not ^H */
2437+S_EXTERN char * cd; /* clear to end of display */
2438+S_EXTERN char * cl; /* clear display */
2439+S_EXTERN char * cm; /* cursor movement */
2440+S_EXTERN char * ho; /* home */
2441+S_EXTERN char * nd; /* non-destructive space */
2442+S_EXTERN char * so; /* standout */
2443+S_EXTERN char * se; /* standout end */
2444+S_EXTERN int sg; /* space taken by so/se */
2445+S_EXTERN char * ti; /* terminal initialization sequence */
2446+S_EXTERN char * te; /* terminal termination sequence */
2447+S_EXTERN int li; /* lines */
2448+S_EXTERN int co; /* columns */
2449+
2450+S_EXTERN int contextsize; /* number of lines of context to show */
2451+S_EXTERN char contextbufs[MAXCONTEXT][BUFSIZ]; /* Context of current line */
2452+S_EXTERN int contextoffset; /* Offset of line start in contextbufs[0] */
2453+S_EXTERN char * currentchar; /* Location in contextbufs */
2454+S_EXTERN char ctoken[INPUTWORDLEN + MAXAFFIXLEN]; /* Current token as char */
2455+S_EXTERN ichar_t itoken[INPUTWORDLEN + MAXAFFIXLEN]; /* Ctoken as ichar_t str */
2456+
2457+S_EXTERN char termcap[2048]; /* termcap entry */
2458+S_EXTERN char termstr[2048]; /* for string values */
2459+S_EXTERN char * termptr; /* pointer into termcap, used by tgetstr */
2460+
2461+S_EXTERN int numhits; /* number of hits in dictionary lookups */
2462+S_EXTERN struct success
2463+ hits[MAX_HITS]; /* table of hits gotten in lookup */
2464+
2465+S_EXTERN char * hashstrings; /* Strings in hash table */
2466+S_EXTERN struct hashheader
2467+ hashheader; /* Header of hash table */
2468+S_EXTERN struct dent *
2469+ hashtbl; /* Main hash table, for dictionary */
2470+S_EXTERN int hashsize; /* Size of main hash table */
2471+
2472+
2473+S_EXTERN int aflag; /* NZ if -a or -A option specified */
2474+S_EXTERN int cflag; /* NZ if -c (crunch) option */
2475+S_EXTERN int lflag; /* NZ if -l (list) option */
2476+S_EXTERN int incfileflag; /* whether xgets() acts exactly like gets() */
2477+Global Logical nodictflag; /* NZ if dictionary not needed */
2478+
2479+S_EXTERN int uerasechar; /* User's erase character, from stty */
2480+S_EXTERN int ukillchar; /* User's kill character */
2481+
2482+S_EXTERN unsigned int laststringch; /* Number of last string character */
2483+S_EXTERN int defdupchar; /* Default duplicate string type */
2484+
2485+S_EXTERN unsigned int numpflags; /* Number of prefix flags in table */
2486+S_EXTERN unsigned int numsflags; /* Number of suffix flags in table */
2487+S_EXTERN struct flagptr *pflagindex;
2488+ /* Fast index to pflaglist */
2489+S_EXTERN struct flagent *pflaglist; /* Prefix flag control list */
2490+S_EXTERN struct flagptr *sflagindex;
2491+ /* Fast index to sflaglist */
2492+S_EXTERN struct flagent *sflaglist; /* Suffix flag control list */
2493+
2494+S_EXTERN struct strchartype * /* String character type collection */
2495+ chartypes;
2496+
2497+S_EXTERN FILE * infile; /* File being corrected */
2498+S_EXTERN FILE * outfile; /* Corrected copy of infile */
2499+
2500+S_EXTERN char * askfilename; /* File specified in -f option */
2501+
2502+S_EXTERN int changes; /* NZ if changes made to cur. file */
2503+S_EXTERN int readonly; /* NZ if current file is readonly */
2504+S_EXTERN int quit; /* NZ if we're done with this file */
2505+
2506+#define MAXPOSSIBLE 100 /* Max no. of possibilities to generate */
2507+
2508+S_EXTERN char possibilities[MAXPOSSIBLE][INPUTWORDLEN + MAXAFFIXLEN];
2509+ /* Table of possible corrections */
2510+S_EXTERN int pcount; /* Count of possibilities generated */
2511+S_EXTERN int maxposslen; /* Length of longest possibility */
2512+S_EXTERN int easypossibilities; /* Number of "easy" corrections found */
2513+ /* ..(defined as those using legal affixes) */
2514+
2515+Global Logical inited;
2516+/*
2517+ * The following array contains a list of characters that should be tried
2518+ * in "missingletter." Note that lowercase characters are omitted.
2519+ */
2520+S_EXTERN int Trynum; /* Size of "Try" array */
2521+S_EXTERN ichar_t Try[SET_SIZE + MAXSTRINGCHARS];
2522+
2523+/*
2524+ * Initialized variables. These are generated using macros so that they
2525+ * may be consistently declared in all programs. Numerous examples of
2526+ * usage are given below.
2527+ */
2528+#ifdef MAIN
2529+#define S_INIT(decl, init) decl = init
2530+#else
2531+#define S_INIT(decl, init) extern decl
2532+#endif
2533+
2534+#ifdef MINIMENU
2535+S_INIT (int minimenusize, 2); /* MUST be either 2 or zero */
2536+#else /* MINIMENU */
2537+S_INIT (int minimenusize, 0); /* MUST be either 2 or zero */
2538+#endif /* MINIMENU */
2539+
2540+S_INIT (int eflag, 0); /* NZ for expand mode */
2541+S_INIT (int dumpflag, 0); /* NZ to do dump mode */
2542+S_INIT (int fflag, 0); /* NZ if -f specified */
2543+#ifndef USG
2544+S_INIT (int sflag, 0); /* NZ to stop self after EOF */
2545+#endif
2546+S_INIT (int vflag, 0); /* NZ to display characters as M-xxx */
2547+S_INIT (int xflag, DEFNOBACKUPFLAG); /* NZ to suppress backups */
2548+S_INIT (int deftflag, -1); /* NZ for TeX mode by default */
2549+S_INIT (int tflag, DEFTEXFLAG); /* NZ for TeX mode in current file */
2550+S_INIT (int prefstringchar, -1); /* Preferred string character type */
2551+
2552+S_INIT (int terse, 0); /* NZ for "terse" mode */
2553+
2554+S_INIT (char tempfile[MAXPATHLEN], ""); /* Name of file we're spelling into */
2555+
2556+S_INIT (int minword, MINWORD); /* Longest always-legal word */
2557+S_INIT (int sortit, 1); /* Sort suggestions alphabetically */
2558+S_INIT (int compoundflag, -1); /* How to treat compounds: see above */
2559+S_INIT (int tryhardflag, -1); /* Always call tryveryhard */
2560+
2561+S_INIT (char * currentfile, NULL); /* Name of current input file */
2562+
2563+/* Odd numbers for math mode in LaTeX; even for LR or paragraph mode */
2564+S_INIT (int math_mode, 0);
2565+/* P -- paragraph or LR mode
2566+ * b -- parsing a \begin statement
2567+ * e -- parsing an \end statement
2568+ * r -- parsing a \ref type of argument.
2569+ * m -- looking for a \begin{minipage} argument.
2570+ */
2571+S_INIT (char LaTeX_Mode, 'P');
2572+
2573+#include "i_proto.h"
41e3656f 2574diff -ruN vim62./src/spell/local.h vim62/src/spell/local.h
2575--- vim62./src/spell/local.h 1970-01-01 01:00:00.000000000 +0100
2576+++ vim62/src/spell/local.h 2003-06-02 19:57:21.000000000 +0200
24ec98f0
JB
2577@@ -0,0 +1,338 @@
2578+/*
2579+ * Written by Eli Zaretskii <eliz@is.elta.co.il>
2580+ *
2581+ * This is local.h file suitable for compiling Ispell on MS-DOS systems
2582+ * with version 2.x of DJGPP port of GNU C/C++ compiler.
2583+ *
2584+ * $Id$
2585+ *
2586+ * $Log$
2587+ */
2588+
2589+/*
2590+ * WARNING WARNING WARNING
2591+ *
2592+ * This file is *NOT* a normal C header file! Although it uses C
2593+ * syntax and is included in C programs, it is also processed by shell
2594+ * scripts that are very stupid about format.
2595+ *
2596+ * Do not try to use #if constructs to configure this file for more
2597+ * than one configuration. Do not place whitespace after the "#" in
2598+ * "#define". Do not attempt to disable lines by commenting them out.
2599+ * Do not use backslashes to reduce the length of long lines.
2600+ * None of these things will work the way you expect them to.
2601+ *
2602+ * WARNING WARNING WARNING
2603+ */
2604+
2605+/*
2606+** Things that normally go in a Makefile. Define these just like you
2607+** might in the Makefile, except you should use #define instead of
2608+** make's assignment syntax. Everything must be double-quoted, and
2609+** (unlike make) you can't use any sort of $-syntax to pick up the
2610+** values of other definitions.
2611+*/
2612+
2613+#define CC "gcc"
2614+#define CFLAGS "-O2 -g"
2615+#define YACC "bison -y"
2616+
2617+/*
2618+** TERMLIB - DJGPP doesn't have one, it uses direct screen writes.
2619+*/
2620+#define TERMLIB ""
2621+
2622+/*
2623+** Where to install various components of ispell. BINDIR contains
2624+** binaries. LIBDIR contains hash tables and affix files. ELISPDIR
2625+** contains emacs lisp files (if any) and TEXINFODIR contains emacs
2626+** TeXinfo files. MAN1DIR and MAN1EXT will hold the chapter-1 and
2627+** chapter-4 manual pages, respectively.
2628+**
2629+** If you intend to use multiple dictionary files, I would suggest
2630+** LIBDIR be a directory which will contain nothing else, so sensible
2631+** names can be constructed for the -d option without conflict.
2632+*/
2633+#define BINDIR "/usr/bin"
2634+#define LIBDIR "/usr/lib/ispell"
2635+#define ELISPDIR "/usr/lib/emacs/site-lisp"
2636+#define TEXINFODIR "/usr/share/info"
2637+#define MAN1DIR "/usr/share/man/man1"
2638+#define MAN4DIR "/usr/share/man/man4"
2639+
2640+/*
2641+** List of all hash files (languages) which will be supported by ispell.
2642+**
2643+** This variable has a complex format so that many options can be
2644+** specified. The format is as follows:
2645+**
2646+** <language>[,<make-options>...] [<language> [,<make-options> ...] ...]
2647+**
2648+** where
2649+**
2650+** language is the name of a subdirectory of the
2651+** "languages" directory
2652+** make-options are options that are to be passed to "make" in
2653+** the specified directory. The make-options
2654+** should not, in general, specify a target, as
2655+** this will be provided by the make process.
2656+**
2657+** For example, if LANGUAGES is:
2658+**
2659+** "{american,EXTRADICT=/usr/dict/words /usr/dict/web2} {deutsch}",
2660+**
2661+** then the American-English and Deutsch (German) languages will be supported,
2662+** and when the English dictionary is built, the variable
2663+** 'EXTRADICT=/usr/dict/words /usr/dict/web2' will be passed to the makefile.
2664+**
2665+** Notes on the syntax: The makefile is not very robust. If you have
2666+** make problems, or if make seems to in the language-subdirs
2667+** dependency, check your syntax. The makefile adds single quotes to
2668+** the individual variables in the LANGUAGES specification, so don't
2669+** use quotes of any kind.
2670+**
2671+** In the future, the first language listed in this variable will
2672+** become the default, and the DEFHASH, DEFLANG, and DEFPAFF,
2673+** variables will all become obsolete. So be sure to put your default
2674+** language first, to make later conversion easier!
2675+**
2676+** Notes on options for the various languages will be found in the
2677+** Makefiles for those languages. Some of those languages may require
2678+** you to also change various limits limits like MASKBITS or the
2679+** length parameters.
2680+**
2681+** A special note on the English language: because the British and
2682+** American dialects use different spelling, you should usually select
2683+** one or the other of these. If you select both, the setting of
2684+** MASTERHASH will determine which becomes the language linked to
2685+** DEFHASH (which will usually be named english.hash).
2686+**
2687+** !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
2688+** !!! Note the pathname for the `words' file: it might be different !!!
2689+** !!! If you don't have this file, make EXTRADICT empty !!!
2690+** !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
2691+*/
2692+#define LANGUAGES "{american,MASTERDICTS=americax.med,HASHFILES=amermedx.hash,EXTRADICT=/usr/lib/ispell/words}"
2693+
2694+/*
2695+** Master hash file for DEFHASH. This is the name of a hash file
2696+** built by a language Makefile. It should be the most-popular hash
2697+** file on your system, because it is the one that will be used by
2698+** default. It must be listed in LANGUAGES, above.
2699+*/
2700+#define MASTERHASH "polish.hash"
2701+
2702+/*
2703+** Default native-language hash file. This is the name given to the
2704+** hash table that will be used if no language is specified to
2705+** ispell. It is a link to MASTERHASH, above.
2706+*/
2707+#define DEFHASH "polish.hash"
2708+
2709+/*
2710+** If your sort command accepts the -T switch to set temp file
2711+** locations (try it out; on some systems it exists but is
2712+** undocumented), make the following variable the null string.
2713+** Otherwise leave it as the sed script.
2714+**
2715+** With DJGPP, you will probably use GNU Sort which accepts -T, so:
2716+*/
2717+#define SORTTMP ""
2718+
2719+/*
2720+** If your system has the rename(2) system call, define HAS_RENAME and
2721+** ispell will use that call to rename backup files. Otherwise, it
2722+** will use link/unlink. There is no harm in this except on MS-DOS,
2723+** which might not support link/unlink (DJGPP does, but also has rename).
2724+*/
2725+#define HAS_RENAME 1
2726+
2727+/* environment variable for user's word list */
2728+#ifndef PDICTVAR
2729+#define PDICTVAR "WORDLIST"
2730+#endif
2731+
2732+/*
2733+** Prefix part of default private dictionary. Under MS-DOS 8.3
2734+** filename limitation, we are in trouble...
2735+*/
310b65f3 2736+#define DEFPDICT ".ispell_"
24ec98f0
JB
2737+
2738+/* old place to look for default word list */
2739+#define OLDPDICT ".isp."
2740+
2741+/*
2742+** mktemp template for temporary file - MUST contain 6 consecutive X's.
2743+** On MSDOS the directory part of TEMPNAME is only used if neither $TMP
2744+** nor $TEMP nor $TMPDIR (in that order) are defined. If any of these
2745+** variables is defined, the filename part of TEMPNAME is appended to
2746+** their value.
2747+*/
2748+#define TEMPNAME "/tmp/isXXXXXX"
2749+
2750+/*
2751+** If REGEX_LOOKUP is NOT defined, the lookup command (L) will use the look(1)
2752+** command (if available) or the egrep command. If REGEX_LOOKUP is defined,
2753+** the lookup command will use the internal dictionary and the
2754+** regular-expression library (which you must supply separately.
2755+** DJGPP v2 has POSIX regexp functions.
2756+*/
2757+#ifndef FEAT_SPELL_HL
2758+#define REGEX_LOOKUP 1
2759+#endif
2760+
2761+/*
2762+** Choose the proper type of regular-expression routines here. BSD
2763+** and public-domain systems have routines called re_comp and re_exec;
2764+** System V uses regcmp and regex.
2765+*/
2766+#include <sys/types.h>
2767+#include <regex.h>
2768+#define REGCTYPE regex_t *
2769+#define REGCMP(re,str) (regcomp (re, str, 0), re)
2770+#define REGEX(re, str, dummy) \
2771+ (re != 0 && regexec (re, str, 0, 0, 0) == 0 ? (char *)1 : NULL)
2772+#define REGFREE(re) \
2773+ do { \
2774+ if (re == 0) \
2775+ re = (regex_t *)calloc (1, sizeof (regex_t)); \
2776+ else \
2777+ regfree(re); \
2778+ } while (0)
2779+
2780+/*
2781+**
2782+** The 2 following definitions are only meaningfull if you don't use
2783+** any regex library.
2784+*/
2785+/* path to egrep (use speeded up version if available);
2786+ defined without explicit path, since there are no
2787+ standard places for programs on MS-DOS. */
2788+#define EGREPCMD "egrep -i"
2789+
2790+/* path to wordlist for Lookup command (typically /usr/dict/{words|web2}) */
2791+/* note that /usr/dict/web2 is usually a bad idea due to obscure words */
2792+#undef WORDS
2793+
2794+/*
2795+** FIXME: The filename truncation below is not flexible enough for DJGPP
2796+** which can support long filenames on some platforms, since we
2797+** will only know if the support is available at runtime.
2798+*/
2799+
2800+/* max file name length (will truncate to fit BAKEXT) if not in sys/param.h */
2801+#ifdef NAME_MAX
2802+#define MAXNAMLEN NAME_MAX
2803+#else
2804+#define MAXNAMLEN 12
2805+#endif
2806+
2807+#define MAXEXTLEN 4 /* max. extension length including '.' */
2808+#define MAXBASENAMELEN 8 /* max. base filename length without ext */
2809+
2810+/* define if you want .bak file names truncated to MAXNAMLEN characters */
2811+/* On MS-DOS, we really have no choice... */
2812+#define TRUNCATEBAK 1
2813+
2814+/*
2815+** This is the extension that will be added to backup files.
2816+** On MS-DOS, it makes sense to use the shortest possible extension.
2817+*/
2818+#define BAKEXT "~"
2819+
2820+/*
2821+** Define the following to suppress the 8-bit character feature.
2822+** FIXME: does this defeat support of foreign languages?
2823+*/
2824+/*#define NO8BIT 1 */
2825+#ifdef NO8BIT
2826+#undef NO8BIT
2827+#endif
2828+
2829+/*
2830+** Define this if you want to use the shell for interpretation of commands
2831+** issued via the "L" command, "^Z" under System V, and "!". If this is
2832+** not defined then a direct spawnvp() will be used in place of the
2833+** normal system(). This may speed up these operations if the SHELL
2834+** environment variable points to a Unix-like shell (such as `sh' or `bash').
2835+**
2836+** However, if you undefine USESH, commands which use pipes, redirection
2837+** and shell wildcards won't work, and you will need support for the SIGTSTP
2838+** signal, for the above commands to work at all.
2839+*/
2840+
2841+#define USESH 1
2842+
2843+/*
2844+** Define this if you want to be able to type any command at a "type space
2845+** to continue" prompt.
2846+*/
2847+#define COMMANDFORSPACE 1
2848+
2849+/*
2850+** The next three variables are used to provide a variable-size context
2851+** display at the bottom of the screen. Normally, the user will see
2852+** a number of lines equal to CONTEXTPCT of his screen, rounded down
2853+** (thus, with CONTEXTPCT == 10, a 24-line screen will produce two lines
2854+** of context). The context will never be greater than MAXCONTEXT or
2855+** less than MINCONTEXT. To disable this feature entirely, set MAXCONTEXT
2856+** and MINCONTEXT to the same value. To round context percentages up,
2857+** define CONTEXTROUNDUP.
2858+**
2859+** Warning: don't set MAXCONTEXT ridiculously large. There is a
2860+** static buffer of size MAXCONTEXT*BUFSIZ; since BUFSIZ is frequently
2861+** 1K or larger, this can create a remarkably large executable.
2862+*/
2863+#define CONTEXTPCT 20 /* Use 20% of the screen for context */
2864+#define MINCONTEXT 2 /* Always show at least 2 lines of context */
2865+#define MAXCONTEXT 10 /* Never show more than 10 lines of context */
2866+#define CONTEXTROUNDUP 1 /* Round context up */
2867+
2868+/*
2869+** Define this if you want the "mini-menu," which gives the most important
2870+** options at the bottom of the screen, to be the default (in any case, it
2871+** can be controlled with the "-M" switch).
2872+*/
2873+#define MINIMENU
2874+
2875+/*
2876+** Redefine GETKEYSTROKE() to whatever appropriate on some MS-DOS systems
2877+** where getchar() doesn't operate properly in raw mode.
2878+*/
2879+#ifdef __DJGPP__
2880+#include <pc.h>
2881+#include <keys.h>
2882+#define GETKEYSTROKE() getxkey()
2883+#else
2884+#define GETKEYSTROKE() getchar()
2885+#endif
2886+
2887+/*
2888+** We include <fcntl.h> to have the definition of O_BINARY. The
2889+** configuration script will notice this and define MSDOS_BINARY_OPEN.
2890+*/
2891+#include <fcntl.h>
2892+
2893+/*
2894+** Environment variable to use to locate the home directory. On DOS
2895+** systems we set this to ISPELL_HOME to avoid conflicts with
8f3725c8 2896+** other programs that look for a HOME environment variable. We're not on DOS.
24ec98f0 2897+*/
8f3725c8 2898+#define HOME "HOME"
24ec98f0
JB
2899+#define PDICTHOME "."
2900+#define OPTIONVAR "ISPELL_OPTIONS"
2901+#define LIBRARYVAR "ISPELL_DICTDIR"
2902+
2903+/*
2904+** On MS-DOS systems, we define the following variables so that
2905+** ispell's files have legal suffixes. Note that these suffixes
2906+** must agree with the way you've defined dictionary files which
2907+** incorporate these suffixes.
2908+**
2909+** Actually, it is not recommended at all to change the suffixes,
2910+** since they are hardwired in the Makefile's under languages/
2911+** subdirectory, and MS-DOS will silently truncate excess letters anyway.
2912+*/
2913+#define HASHSUFFIX ".hash"
2914+#define STATSUFFIX ".sta"
2915+#define COUNTSUFFIX ".cnt"
41e3656f 2916diff -ruN vim62./src/spell/lookup.c vim62/src/spell/lookup.c
2917--- vim62./src/spell/lookup.c 1970-01-01 01:00:00.000000000 +0100
2918+++ vim62/src/spell/lookup.c 2003-06-02 19:57:21.000000000 +0200
24ec98f0
JB
2919@@ -0,0 +1,534 @@
2920+#ifndef lint
2921+static char Rcs_Id[] =
2922+ "$Id$";
2923+#endif
2924+
2925+/*
2926+ * lookup.c - see if a word appears in the dictionary
2927+ *
2928+ * Pace Willisson, 1983
2929+ *
2930+ * Copyright 1987, 1988, 1989, 1992, 1993, Geoff Kuenning, Granada Hills, CA
2931+ * All rights reserved.
2932+ *
2933+ * Redistribution and use in source and binary forms, with or without
2934+ * modification, are permitted provided that the following conditions
2935+ * are met:
2936+ *
2937+ * 1. Redistributions of source code must retain the above copyright
2938+ * notice, this list of conditions and the following disclaimer.
2939+ * 2. Redistributions in binary form must reproduce the above copyright
2940+ * notice, this list of conditions and the following disclaimer in the
2941+ * documentation and/or other materials provided with the distribution.
2942+ * 3. All modifications to the source code must be clearly marked as
2943+ * such. Binary redistributions based on modified source code
2944+ * must be clearly marked as modified versions in the documentation
2945+ * and/or other materials provided with the distribution.
2946+ * 4. All advertising materials mentioning features or use of this software
2947+ * must display the following acknowledgment:
2948+ * This product includes software developed by Geoff Kuenning and
2949+ * other unpaid contributors.
2950+ * 5. The name of Geoff Kuenning may not be used to endorse or promote
2951+ * products derived from this software without specific prior
2952+ * written permission.
2953+ *
2954+ * THIS SOFTWARE IS PROVIDED BY GEOFF KUENNING AND CONTRIBUTORS ``AS IS'' AND
2955+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
2956+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
2957+ * ARE DISCLAIMED. IN NO EVENT SHALL GEOFF KUENNING OR CONTRIBUTORS BE LIABLE
2958+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
2959+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
2960+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
2961+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
2962+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
2963+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
2964+ * SUCH DAMAGE.
2965+ */
2966+
2967+/*
2968+ * $Log$
2969+ * Revision 1.42 1995/01/08 23:23:42 geoff
2970+ * Support MSDOS_BINARY_OPEN when opening the hash file to read it in.
2971+ *
2972+ * Revision 1.41 1994/01/25 07:11:51 geoff
2973+ * Get rid of all old RCS log lines in preparation for the 3.1 release.
2974+ *
2975+ */
2976+
2977+#include "ispell.h"
2978+#include "msgs.h"
2979+#include <stdlib.h>
2980+#include <fcntl.h>
2981+#ifdef WIN32
2982+#include <io.h>
2983+#endif
2984+
2985+#ifdef INDEXDUMP
2986+Local void dumpindex (struct flagptr * indexp, int depth);
2987+#endif /* INDEXDUMP */
2988+
2989+Public Logical inited = False;
2990+
2991+char err_buf[256];
2992+
2993+Public char *
2994+linit (char * hashname)
2995+{
2996+ int hashfd;
2997+ register int i;
2998+ register struct dent * dp;
2999+ struct flagent * entry;
3000+ struct flagptr * ind;
3001+ int nextchar;
3002+ int viazero;
3003+ register ichar_t * cp;
3004+
3005+ if (inited)
3006+ return(NULL);
3007+
3008+ if(hashtbl != NULL)
3009+ free(hashtbl);
3010+ numpflags = 0;
3011+ numsflags = 0;
3012+ if(pflagindex != NULL)
3013+ free(pflagindex);
3014+ pflagindex = NULL;
3015+ if(sflagindex != NULL)
3016+ free(sflagindex);
3017+ sflagindex = NULL;
3018+ if((pflagindex = (struct flagptr *)calloc(SET_SIZE + MAXSTRINGCHARS,
3019+ sizeof(struct flagptr))) == NULL)
3020+ {
3021+ (void) sprintf(err_buf, LOOKUP_C_NO_HASH_SPACE);
3022+ return(err_buf);
3023+ }
3024+ if((sflagindex = (struct flagptr *)calloc(SET_SIZE + MAXSTRINGCHARS,
3025+ sizeof(struct flagptr))) == NULL)
3026+ {
3027+ (void) sprintf(err_buf, LOOKUP_C_NO_HASH_SPACE);
3028+ return(err_buf);
3029+ }
3030+ hashtbl = NULL;
3031+ if ((hashfd = open (hashname, 0 | MSDOS_BINARY_OPEN)) < 0)
3032+ {
3033+ (void) sprintf(err_buf, CANT_OPEN, hashname);
3034+ return(err_buf);
3035+ }
3036+
3037+ hashsize = read (hashfd, (char *) &hashheader, sizeof hashheader);
3038+ if (hashsize < sizeof hashheader)
3039+ {
3040+ if (hashsize < 0)
3041+ (void) sprintf(err_buf, LOOKUP_C_CANT_READ, hashname);
3042+ else if (hashsize == 0)
3043+ (void) sprintf(err_buf, LOOKUP_C_NULL_HASH, hashname);
3044+ else
3045+ (void) sprintf(err_buf, LOOKUP_C_SHORT_HASH (hashname, hashsize,
3046+ (int) sizeof hashheader));
3047+ (void) close (hashfd);
3048+ return(err_buf);
3049+ }
3050+ else if (hashheader.magic != SPELL_MAGIC)
3051+ {
3052+ (void) sprintf(err_buf,
3053+ LOOKUP_C_BAD_MAGIC (hashname, (unsigned int) SPELL_MAGIC,
3054+ (unsigned int) hashheader.magic));
3055+ (void) close (hashfd);
3056+ return(err_buf);
3057+ }
3058+ else if (hashheader.magic2 != SPELL_MAGIC)
3059+ {
3060+ (void) sprintf(err_buf,
3061+ LOOKUP_C_BAD_MAGIC2 (hashname, (unsigned int) SPELL_MAGIC,
3062+ (unsigned int) hashheader.magic2));
3063+ (void) close (hashfd);
3064+ return(err_buf);
3065+ }
3066+ else if (hashheader.compileoptions != COMPILEOPTIONS
3067+ || hashheader.maxstringchars != MAXSTRINGCHARS
3068+ || hashheader.maxstringcharlen != MAXSTRINGCHARLEN)
3069+ {
3070+ (void) sprintf(err_buf,
3071+ LOOKUP_C_BAD_OPTIONS ((unsigned int) hashheader.compileoptions,
3072+ hashheader.maxstringchars, hashheader.maxstringcharlen,
3073+ (unsigned int) COMPILEOPTIONS, MAXSTRINGCHARS, MAXSTRINGCHARLEN));
3074+ (void) close (hashfd);
3075+ return(err_buf);
3076+ }
3077+ if (nodictflag)
3078+ {
3079+ /*
3080+ * Dictionary is not needed - create an empty dummy table. We
3081+ * actually have to have one entry since the hash
3082+ * algorithm involves a divide by the table size
3083+ * (actually modulo, but zero is still unacceptable).
3084+ * So we create an empty entry.
3085+ */
3086+ hashsize = 1; /* This prevents divides by zero */
3087+ hashtbl = (struct dent *) calloc (1, sizeof (struct dent));
3088+ if (hashtbl == NULL)
3089+ {
3090+ (void) sprintf(err_buf, LOOKUP_C_NO_HASH_SPACE);
3091+ (void) close (hashfd);
3092+ return(err_buf);
3093+ }
3094+ hashtbl[0].word = NULL;
3095+ hashtbl[0].next = NULL;
3096+ hashtbl[0].flagfield &= ~(USED | KEEP);
3097+ /* The flag bits don't matter, but calloc cleared them. */
3098+ if(hashstrings != NULL)
3099+ free(hashstrings);
3100+ if((hashstrings = (char *) calloc (1, (unsigned) hashheader.lstringsize))
3101+ == NULL)
3102+ {
3103+ (void) sprintf(err_buf, LOOKUP_C_NO_HASH_SPACE);
3104+ (void) close (hashfd);
3105+ return(err_buf);
3106+ }
3107+ }
3108+ else
3109+ {
3110+ if(hashtbl != NULL)
3111+ free(hashtbl);
3112+ if((hashtbl = (struct dent *)
3113+ malloc ((unsigned) hashheader.tblsize * sizeof (struct dent))) == NULL)
3114+ {
3115+ (void) sprintf(err_buf, LOOKUP_C_NO_HASH_SPACE);
3116+ (void) close (hashfd);
3117+ return(err_buf);
3118+ }
3119+ hashsize = hashheader.tblsize;
3120+ if(hashstrings != NULL)
3121+ free(hashstrings);
3122+ if((hashstrings = (char *) malloc ((unsigned) hashheader.stringsize)) == NULL)
3123+ {
3124+ (void) sprintf(err_buf, LOOKUP_C_NO_HASH_SPACE);
3125+ (void) close (hashfd);
3126+ return(err_buf);
3127+ }
3128+ }
3129+ numsflags = hashheader.stblsize;
3130+ numpflags = hashheader.ptblsize;
3131+ if(sflaglist != NULL)
3132+ free(sflaglist);
3133+ if((sflaglist = (struct flagent *)
3134+ malloc ((numsflags + numpflags) * sizeof (struct flagent))) == NULL)
3135+ {
3136+ (void) sprintf(err_buf, LOOKUP_C_NO_HASH_SPACE);
3137+ (void) close (hashfd);
3138+ return(err_buf);
3139+ }
3140+ pflaglist = sflaglist + numsflags;
3141+
3142+ if (nodictflag)
3143+ {
3144+ /*
3145+ * Read just the strings for the language table, and
3146+ * skip over the rest of the strings and all of the
3147+ * hash table.
3148+ */
3149+ if (read (hashfd, hashstrings, (unsigned) hashheader.lstringsize)
3150+ != hashheader.lstringsize)
3151+ {
3152+ (void) sprintf(err_buf, LOOKUP_C_BAD_FORMAT);
3153+ (void) close (hashfd);
3154+ return(err_buf);
3155+ }
3156+ (void) lseek (hashfd,
3157+ (long) hashheader.stringsize - (long) hashheader.lstringsize
3158+ + (long) hashheader.tblsize * (long) sizeof (struct dent), 1);
3159+ }
3160+ else
3161+ {
3162+ if ((unsigned int)read (hashfd, hashstrings,
3163+ (unsigned int) hashheader.stringsize) != hashheader.stringsize
3164+ || (unsigned int)read (hashfd, (char *) hashtbl, (unsigned)
3165+ hashheader.tblsize * sizeof (struct dent))
3166+ != (unsigned int) hashheader.tblsize * sizeof (struct dent))
3167+ {
3168+ (void) sprintf(err_buf, LOOKUP_C_BAD_FORMAT);
3169+ (void) close (hashfd);
3170+ return(err_buf);
3171+ }
3172+ }
3173+ if ((unsigned int)read (hashfd, (char *) sflaglist,
3174+ (unsigned int) (numsflags + numpflags) * sizeof (struct flagent))
3175+ != (unsigned int)(numsflags + numpflags) * sizeof (struct flagent))
3176+ {
3177+ (void) sprintf(err_buf, LOOKUP_C_BAD_FORMAT);
3178+ (void) close (hashfd);
3179+ return(err_buf);
3180+ }
3181+ (void) close (hashfd);
3182+
3183+ if (!nodictflag)
3184+ {
3185+ for (i = hashsize, dp = hashtbl; --i >= 0; dp++)
3186+ {
3187+ if (dp->word == (char *) -1)
3188+ dp->word = NULL;
3189+ else
3190+ dp->word = &hashstrings [ (int)(dp->word) ];
3191+ if (dp->next == (struct dent *) -1)
3192+ dp->next = NULL;
3193+ else
3194+ dp->next = &hashtbl [ (int)(dp->next) ];
3195+ }
3196+ }
3197+
3198+ for (i = numsflags + numpflags, entry = sflaglist; --i >= 0; entry++)
3199+ {
3200+ if (entry->stripl)
3201+ entry->strip = (ichar_t *) &hashstrings[(int) entry->strip];
3202+ else
3203+ entry->strip = NULL;
3204+ if (entry->affl)
3205+ entry->affix = (ichar_t *) &hashstrings[(int) entry->affix];
3206+ else
3207+ entry->affix = NULL;
3208+ }
3209+ /*
3210+ ** Warning - 'entry' and 'i' are reset in the body of the loop
3211+ ** below. Don't try to optimize it by (e.g.) moving the decrement
3212+ ** of i into the loop condition.
3213+ */
3214+ for (i = numsflags, entry = sflaglist; i > 0; i--, entry++)
3215+ {
3216+ if (entry->affl == 0)
3217+ {
3218+ cp = NULL;
3219+ ind = &sflagindex[0];
3220+ viazero = 1;
3221+ }
3222+ else
3223+ {
3224+ cp = entry->affix + entry->affl - 1;
3225+ ind = &sflagindex[*cp];
3226+ viazero = 0;
3227+ while (ind->numents == 0 && ind->pu.fp != NULL)
3228+ {
3229+ if (cp == entry->affix)
3230+ {
3231+ ind = &ind->pu.fp[0];
3232+ viazero = 1;
3233+ }
3234+ else
3235+ {
3236+ ind = &ind->pu.fp[*--cp];
3237+ viazero = 0;
3238+ }
3239+ }
3240+ }
3241+ if (ind->numents == 0)
3242+ ind->pu.ent = entry;
3243+ ind->numents++;
3244+ /*
3245+ ** If this index entry has more than MAXSEARCH flags in
3246+ ** it, we will split it into subentries to reduce the
3247+ ** searching. However, the split doesn't make sense in
3248+ ** two cases: (a) if we are already at the end of the
3249+ ** current affix, or (b) if all the entries in the list
3250+ ** have identical affixes. Since the list is sorted, (b)
3251+ ** is true if the first and last affixes in the list
3252+ ** are identical.
3253+ */
3254+ if (!viazero && ind->numents >= MAXSEARCH &&
3255+ icharcmp (entry->affix, ind->pu.ent->affix) != 0)
3256+ {
3257+ /* Sneaky trick: back up and reprocess */
3258+ entry = ind->pu.ent - 1; /* -1 is for entry++ in loop */
3259+ i = numsflags - (entry - sflaglist);
3260+ if((ind->pu.fp = (struct flagptr *)
3261+ calloc ((unsigned) (SET_SIZE + hashheader.nstrchars),
3262+ sizeof (struct flagptr))) == NULL)
3263+ {
3264+ (void) sprintf(err_buf, LOOKUP_C_NO_LANG_SPACE);
3265+ return(err_buf);
3266+ }
3267+ ind->numents = 0;
3268+ }
3269+ }
3270+ /*
3271+ ** Warning - 'entry' and 'i' are reset in the body of the loop
3272+ ** below. Don't try to optimize it by (e.g.) moving the decrement
3273+ ** of i into the loop condition.
3274+ */
3275+ for (i = numpflags, entry = pflaglist; i > 0; i--, entry++)
3276+ {
3277+ if (entry->affl == 0)
3278+ {
3279+ cp = NULL;
3280+ ind = &pflagindex[0];
3281+ viazero = 1;
3282+ }
3283+ else
3284+ {
3285+ cp = entry->affix;
3286+ ind = &pflagindex[*cp++];
3287+ viazero = 0;
3288+ while (ind->numents == 0 && ind->pu.fp != NULL)
3289+ {
3290+ if (*cp == 0)
3291+ {
3292+ ind = &ind->pu.fp[0];
3293+ viazero = 1;
3294+ }
3295+ else
3296+ {
3297+ ind = &ind->pu.fp[*cp++];
3298+ viazero = 0;
3299+ }
3300+ }
3301+ }
3302+ if (ind->numents == 0)
3303+ ind->pu.ent = entry;
3304+ ind->numents++;
3305+ /*
3306+ ** If this index entry has more than MAXSEARCH flags in
3307+ ** it, we will split it into subentries to reduce the
3308+ ** searching. However, the split doesn't make sense in
3309+ ** two cases: (a) if we are already at the end of the
3310+ ** current affix, or (b) if all the entries in the list
3311+ ** have identical affixes. Since the list is sorted, (b)
3312+ ** is true if the first and last affixes in the list
3313+ ** are identical.
3314+ */
3315+ if (!viazero && ind->numents >= MAXSEARCH
3316+ && icharcmp (entry->affix, ind->pu.ent->affix) != 0)
3317+ {
3318+ /* Sneaky trick: back up and reprocess */
3319+ entry = ind->pu.ent - 1; /* -1 is for entry++ in loop */
3320+ i = numpflags - (entry - pflaglist);
3321+ ind->pu.fp =
3322+ (struct flagptr *) calloc (SET_SIZE + hashheader.nstrchars,
3323+ sizeof (struct flagptr));
3324+ if (ind->pu.fp == NULL)
3325+ {
3326+ (void) sprintf(err_buf, LOOKUP_C_NO_LANG_SPACE);
3327+ return(err_buf);
3328+ }
3329+ ind->numents = 0;
3330+ }
3331+ }
3332+#ifdef INDEXDUMP
3333+ (void) sprintf(err_buf, "Prefix index table:");
3334+ dumpindex (pflagindex, 0);
3335+ (void) sprintf(err_buf, "Suffix index table:");
3336+ dumpindex (sflagindex, 0);
3337+#endif
3338+ if (hashheader.nstrchartype == 0)
3339+ chartypes = NULL;
3340+ else
3341+ {
3342+ chartypes = (struct strchartype *)
3343+ calloc (1, hashheader.nstrchartype * sizeof (struct strchartype));
3344+ if (chartypes == NULL)
3345+ {
3346+ (void) sprintf(err_buf, LOOKUP_C_NO_LANG_SPACE);
3347+ return(err_buf);
3348+ }
3349+ for (i = 0, nextchar = hashheader.strtypestart;
3350+ i < hashheader.nstrchartype; i++)
3351+ {
3352+ chartypes[i].name = &hashstrings[nextchar];
3353+ nextchar += strlen (chartypes[i].name) + 1;
3354+ chartypes[i].deformatter = &hashstrings[nextchar];
3355+ nextchar += strlen (chartypes[i].deformatter) + 1;
3356+ chartypes[i].suffixes = &hashstrings[nextchar];
3357+ while (hashstrings[nextchar] != '\0')
3358+ nextchar += strlen (&hashstrings[nextchar]) + 1;
3359+ nextchar++;
3360+ }
3361+ }
3362+ inited = True;
3363+ return (NULL);
3364+}
3365+
3366+#ifdef INDEXDUMP
3367+Local void
3368+dumpindex (
3369+ register struct flagptr * indexp,
3370+ register int depth)
3371+{
3372+ register int i;
3373+ int j;
3374+ int k;
3375+ char stripbuf[INPUTWORDLEN + 4 * MAXAFFIXLEN + 4];
3376+
3377+ for (i = 0; i < SET_SIZE + hashheader.nstrchars; i++, indexp++)
3378+ {
3379+ if (indexp->numents == 0 && indexp->pu.fp != NULL)
3380+ {
3381+ for (j = depth; --j >= 0; )
3382+ (void) putc (' ', stderr);
3383+ if (i >= ' ' && i <= '~')
3384+ (void) putc (i, stderr);
3385+ else
3386+ (void) fprintf (stderr, "0x%x", i);
3387+ (void) putc ('\n', stderr);
3388+ dumpindex (indexp->pu.fp, depth + 1);
3389+ }
3390+ else if (indexp->numents)
3391+ {
3392+ for (j = depth; --j >= 0; )
3393+ (void) putc (' ', stderr);
3394+ if (i >= ' ' && i <= '~')
3395+ (void) putc (i, stderr);
3396+ else
3397+ (void) fprintf (stderr, "0x%x", i);
3398+ (void) fprintf (stderr, " -> %d entries\n", indexp->numents);
3399+ for (k = 0; k < indexp->numents; k++)
3400+ {
3401+ for (j = depth; --j >= 0; )
3402+ (void) putc (' ', stderr);
3403+ if (indexp->pu.ent[k].stripl)
3404+ {
3405+ (void) ichartostr (stripbuf, indexp->pu.ent[k].strip,
3406+ sizeof stripbuf, 1);
3407+ (void) fprintf (stderr, " entry %d (-%s,%s)\n",
3408+ &indexp->pu.ent[k] - sflaglist,
3409+ stripbuf,
3410+ indexp->pu.ent[k].affl
3411+ ? ichartosstr (indexp->pu.ent[k].affix, 1) : "-");
3412+ }
3413+ else
3414+ (void) fprintf (stderr, " entry %d (%s)\n",
3415+ &indexp->pu.ent[k] - sflaglist,
3416+ ichartosstr (indexp->pu.ent[k].affix, 1));
3417+ }
3418+ }
3419+ }
3420+}
3421+#endif
3422+
3423+/* n is length of s */
3424+Public struct dent *
3425+lookup (register ichar_t *s, int dotree)
3426+
3427+{
3428+ register struct dent * dp;
3429+ register char * s1;
3430+ char schar[INPUTWORDLEN + MAXAFFIXLEN];
3431+
3432+ dp = &hashtbl[hash (s, hashsize)];
3433+ if (ichartostr (schar, s, sizeof schar, 1))
3434+ (void) fprintf (stderr, WORD_TOO_LONG (schar));
3435+ for ( ; dp != NULL; dp = dp->next)
3436+ {
3437+ /* quick strcmp, but only for equality */
3438+ s1 = dp->word;
3439+ if (s1 && s1[0] == schar[0] && strcmp (s1 + 1, schar + 1) == 0)
3440+ return dp;
3441+#ifndef NO_CAPITALIZATION_SUPPORT
3442+ while (dp->flagfield & MOREVARIANTS) /* Skip variations */
3443+ dp = dp->next;
3444+#endif
3445+ }
3446+ if (dotree)
3447+ {
3448+ dp = treelookup (s);
3449+ return dp;
3450+ }
3451+ else
3452+ return NULL;
3453+}
41e3656f 3454diff -ruN vim62./src/spell/makedent.c vim62/src/spell/makedent.c
3455--- vim62./src/spell/makedent.c 1970-01-01 01:00:00.000000000 +0100
3456+++ vim62/src/spell/makedent.c 2003-06-02 19:57:21.000000000 +0200
24ec98f0
JB
3457@@ -0,0 +1,1107 @@
3458+/*
3459+ * Copyright 1988, 1989, 1992, 1993, Geoff Kuenning, Granada Hills, CA
3460+ * All rights reserved.
3461+ *
3462+ * Redistribution and use in source and binary forms, with or without
3463+ * modification, are permitted provided that the following conditions
3464+ * are met:
3465+ *
3466+ * 1. Redistributions of source code must retain the above copyright
3467+ * notice, this list of conditions and the following disclaimer.
3468+ * 2. Redistributions in binary form must reproduce the above copyright
3469+ * notice, this list of conditions and the following disclaimer in the
3470+ * documentation and/or other materials provided with the distribution.
3471+ * 3. All modifications to the source code must be clearly marked as
3472+ * such. Binary redistributions based on modified source code
3473+ * must be clearly marked as modified versions in the documentation
3474+ * and/or other materials provided with the distribution.
3475+ * 4. All advertising materials mentioning features or use of this software
3476+ * must display the following acknowledgment:
3477+ * This product includes software developed by Geoff Kuenning and
3478+ * other unpaid contributors.
3479+ * 5. The name of Geoff Kuenning may not be used to endorse or promote
3480+ * products derived from this software without specific prior
3481+ * written permission.
3482+ *
3483+ * THIS SOFTWARE IS PROVIDED BY GEOFF KUENNING AND CONTRIBUTORS ``AS IS'' AND
3484+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
3485+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
3486+ * ARE DISCLAIMED. IN NO EVENT SHALL GEOFF KUENNING OR CONTRIBUTORS BE LIABLE
3487+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
3488+ * DAMAGES(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
3489+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
3490+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
3491+ * LIABILITY, OR TORT(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
3492+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
3493+ * SUCH DAMAGE.
3494+ */
3495+
3496+/*
3497+ * $Log$
3498+ * Revision 1.45 1994/12/27 23:08:52 geoff
3499+ * Add code to makedent to reject words that contain non-word characters.
3500+ * This helps protect people who use ISO 8-bit characters when ispell
3501+ * isn't configured for that option.
3502+ *
3503+ * Revision 1.44 1994/10/25 05:46:20 geoff
3504+ * Fix some incorrect declarations in the lint versions of some routines.
3505+ *
3506+ * Revision 1.43 1994/09/16 03:32:34 geoff
3507+ * Issue an error message for bad affix flags
3508+ *
3509+ * Revision 1.42 1994/02/07 04:23:43 geoff
3510+ * Correctly identify the deformatter when changing file types
3511+ *
3512+ * Revision 1.41 1994/01/25 07:11:55 geoff
3513+ * Get rid of all old RCS log lines in preparation for the 3.1 release.
3514+ *
3515+ */
3516+
3517+#include "ispell.h"
3518+#include <stdlib.h>
3519+#include "msgs.h"
3520+
3521+Global int makedent(char * lbuf, int lbuflen, struct dent * ent);
3522+#ifndef NO_CAPITALIZATION_SUPPORT
3523+Global long whatcap(ichar_t * word);
3524+#endif
3525+Global int addvheader(struct dent * ent);
3526+Global int combinecaps(struct dent * hdr, struct dent * newent);
3527+#ifndef NO_CAPITALIZATION_SUPPORT
3528+Local void forcevheader(struct dent * hdrp, struct dent * oldp,
3529+ struct dent * newp);
3530+#endif /* NO_CAPITALIZATION_SUPPORT */
3531+Local int combine_two_entries(struct dent * hdrp,
3532+ struct dent * oldp, struct dent * newp);
3533+Local int acoversb(struct dent * enta, struct dent * entb);
3534+Global void upcase(ichar_t * string);
3535+Global void lowcase(ichar_t * string);
3536+Global void chupcase(char * s);
3537+Local int issubset(struct dent * ent1, struct dent * ent2);
3538+Local void combineaffixes(struct dent * ent1, struct dent * ent2);
3539+Global void toutent(FILE * outfile, struct dent * hent, int onlykeep);
3540+Local void toutword(FILE * outfile, char * word, struct dent * cent);
3541+Local void flagout(FILE * outfile, int flag);
3542+Global int stringcharlen(char * bufp, int canonical);
3543+Global int strtoichar(ichar_t * out, char * in, int outlen,
3544+ int canonical);
3545+Global int ichartostr(char * out, ichar_t * in, int outlen,
3546+ int canonical);
3547+Global ichar_t * strtosichar(char * in, int canonical);
3548+Global char * ichartosstr(ichar_t * in, int canonical);
3549+Global char * printichar(int in);
3550+#ifndef ICHAR_IS_CHAR
3551+Global ichar_t * icharcpy(ichar_t * out, ichar_t * in);
3552+Global int icharlen(ichar_t * str);
3553+Global int icharcmp(ichar_t * s1, ichar_t * s2);
3554+Global int icharncmp(ichar_t * s1, ichar_t * s2, int n);
3555+#endif /* ICHAR_IS_CHAR */
3556+Global int findfiletype(char * name, int searchnames,
3557+ int * deformatter);
3558+
3559+Local Logical has_marker;
3560+
3561+/*
3562+ * Fill in a directory entry, including setting the capitalization flags, and
3563+ * allocate and initialize memory for the d->word field. Returns -1
3564+ * if there was trouble. The input word must be in canonical form.
3565+ */
3566+
3567+Public int
3568+makedent(
3569+ char * lbuf,
3570+ int lbuflen,
3571+ struct dent * d)
3572+{
3573+ ichar_t ibuf[INPUTWORDLEN + MAXAFFIXLEN];
3574+ ichar_t * ip;
3575+ char * p;
3576+ int bit;
3577+ int len;
3578+
3579+ /* Strip off any trailing newline */
3580+ len = strlen(lbuf) - 1;
3581+ if(lbuf[len] == '\n')
3582+ lbuf[len] = '\0';
3583+
3584+ d->next = NULL;
3585+ /* WARNING: flagfield might be the same as mask! See ispell.h. */
3586+ d->flagfield = 0;
3587+ (void) bzero ((char *) d->mask, sizeof (d->mask));
3588+ d->flagfield |= USED;
3589+ d->flagfield &= ~KEEP;
3590+
3591+ p = index(lbuf, hashheader.flagmarker);
3592+ if(p != NULL)
3593+ *p = 0;
3594+
3595+ /*
3596+ ** Convert the word to an ichar_t and back; this makes sure that
3597+ ** it is in canonical form and thus that the length is correct.
3598+ */
3599+ if(strtoichar(ibuf, lbuf, INPUTWORDLEN * sizeof (ichar_t), 1)
3600+ || ichartostr(lbuf, ibuf, lbuflen, 1))
3601+ {
3602+ (void) fprintf(stderr, WORD_TOO_LONG (lbuf));
3603+ return(-1);
3604+ }
3605+ /*
3606+ ** Make sure the word is well-formed(contains only legal characters).
3607+ */
3608+ for(ip = ibuf; *ip != 0; ip++)
3609+ {
3610+ if(!iswordch(*ip))
3611+ {
3612+ /* Boundary characters are legal as long as they're not at edges */
3613+ if(!isboundarych(*ip) || ip == ibuf || ip[1] == 0)
3614+ {
3615+ (void) fprintf(stderr, MAKEDENT_C_BAD_WORD_CHAR, lbuf);
3616+ return -1;
3617+ }
3618+ }
3619+ }
3620+ len = strlen(lbuf);
3621+#ifndef NO_CAPITALIZATION_SUPPORT
3622+ /*
3623+ ** Figure out the capitalization rules from the capitalization of
3624+ ** the sample entry.
3625+ */
3626+ d->flagfield |= whatcap(ibuf);
3627+#endif
3628+
3629+ if(len > INPUTWORDLEN - 1)
3630+ {
3631+ (void) fprintf(stderr, WORD_TOO_LONG (lbuf));
3632+ return(-1);
3633+ }
3634+
3635+ d->word = malloc((unsigned) len + 1);
3636+ if(d->word == NULL)
3637+ {
3638+ (void) fprintf(stderr, MAKEDENT_C_NO_WORD_SPACE, lbuf);
3639+ return -1;
3640+ }
3641+
3642+ (void) strcpy (d->word, lbuf);
3643+#ifdef NO_CAPITALIZATION_SUPPORT
3644+ chupcase(d->word);
3645+#else /* NO_CAPITALIZATION_SUPPORT */
3646+ if(captype(d->flagfield) != FOLLOWCASE)
3647+ chupcase(d->word);
3648+#endif /* NO_CAPITALIZATION_SUPPORT */
3649+ if(p == NULL)
3650+ return(0);
3651+
3652+ p++;
3653+ while(*p != '\0' && *p != '\n')
3654+ {
3655+ bit = CHARTOBIT((unsigned char) *p);
3656+ if(bit >= 0 && bit <= LARGESTFLAG)
3657+ SETMASKBIT(d->mask, bit);
3658+ else
3659+ (void) fprintf (stderr, BAD_FLAG, (unsigned char) *p);
3660+ p++;
3661+ if(*p == hashheader.flagmarker)
3662+ p++; /* Handle old-format dictionaries too */
3663+ }
3664+ return(0);
3665+}
3666+
3667+#ifndef NO_CAPITALIZATION_SUPPORT
3668+/*
3669+** Classify the capitalization of a sample entry. Returns one of the
3670+** four capitalization codes ANYCASE, ALLCAPS, CAPITALIZED, or FOLLOWCASE.
3671+*/
3672+
3673+Public long
3674+whatcap(register ichar_t * word)
3675+{
3676+ register ichar_t * p;
3677+
3678+ for(p = word; *p; p++)
3679+ {
3680+ if(mylower(*p))
3681+ break;
3682+ }
3683+ if(*p == '\0')
3684+ return ALLCAPS;
3685+ else
3686+ {
3687+ for(; *p; p++)
3688+ if(myupper(*p))
3689+ break;
3690+ if(*p == '\0')
3691+ {
3692+ /*
3693+ ** No uppercase letters follow the lowercase ones.
3694+ ** If there is more than one uppercase letter, it's
3695+ ** "followcase". If only the first one is capitalized,
3696+ ** it's "capitalize". If there are no capitals
3697+ ** at all, it's ANYCASE.
3698+ */
3699+ if(myupper(word[0]))
3700+ {
3701+ for(p = word + 1; *p != '\0'; p++)
3702+ if(myupper(*p))
3703+ return FOLLOWCASE;
3704+ return CAPITALIZED;
3705+ }
3706+ else
3707+ return ANYCASE;
3708+ }
3709+ else
3710+ return FOLLOWCASE; /* .../lower/upper */
3711+ }
3712+}
3713+
3714+/*
3715+** Add a variant-capitalization header to a word. This routine may be
3716+** called even for a followcase word that doesn't yet have a header.
3717+**
3718+** Returns 0 if all was ok, -1 if allocation error.
3719+*/
3720+Public int
3721+addvheader(register struct dent *dp) /* Entry to update */
3722+{
3723+ register struct dent * tdent; /* Copy of entry */
3724+
3725+ /*
3726+ ** Add a second entry with the correct capitalization, and then make
3727+ ** dp into a special dummy entry.
3728+ */
3729+ tdent = (struct dent *) malloc (sizeof (struct dent));
3730+ if(tdent == NULL)
3731+ {
3732+ (void) fprintf(stderr, MAKEDENT_C_NO_WORD_SPACE, dp->word);
3733+ return -1;
3734+ }
3735+ *tdent = *dp;
3736+ if(captype(tdent->flagfield) != FOLLOWCASE)
3737+ tdent->word = NULL;
3738+ else
3739+ {
3740+ /* Followcase words need a copy of the capitalization */
3741+ tdent->word = malloc((unsigned int) strlen (tdent->word) + 1);
3742+ if(tdent->word == NULL)
3743+ {
3744+ (void) fprintf (stderr, MAKEDENT_C_NO_WORD_SPACE, dp->word);
3745+ free((char *) tdent);
3746+ return -1;
3747+ }
3748+ (void) strcpy(tdent->word, dp->word);
3749+ }
3750+ chupcase(dp->word);
3751+ dp->next = tdent;
3752+ dp->flagfield &= ~CAPTYPEMASK;
3753+ dp->flagfield |= (ALLCAPS | MOREVARIANTS);
3754+ return 0;
3755+}
3756+#endif /* NO_CAPITALIZATION_SUPPORT */
3757+
3758+/*
3759+** Combine and resolve the entries describing two capitalizations of the same
3760+** word. This may require allocating yet more entries.
3761+**
3762+** Hdrp is a pointer into a hash table. If the word covered by hdrp has
3763+** variations, hdrp must point to the header. Newp is a pointer to temporary
3764+** storage, and space is malloc'ed if newp is to be kept. The newp->word
3765+** field must have been allocated with mymalloc, so that this routine may free
3766+** the space if it keeps newp but not the word.
3767+**
3768+** Return value: 0 if the word was added, 1 if the word was combined
3769+** with an existing entry, and -1 if trouble occurred(e.g., malloc).
3770+** If 1 is returned, newp->word may have been be freed using myfree.
3771+**
3772+** Life is made much more difficult by the KEEP flag's possibilities. We
3773+** must ensure that a !KEEP word doesn't find its way into the personal
3774+** dictionary as a result of this routine's actions. However, a !KEEP
3775+** word that has affixes must have come from the main dictionary, so it
3776+** is acceptable to combine entries in that case(got that?).
3777+**
3778+** The net result of all this is a set of rules that is a bloody pain
3779+** to figure out. Basically, we want to choose one of the following actions:
3780+**
3781+** (1) Add newp's affixes and KEEP flag to oldp, and discard newp.
3782+** (2) Add oldp's affixes and KEEP flag to newp, replace oldp with
3783+** newp, and discard newp.
3784+#ifndef NO_CAPITALIZATION_SUPPORT
3785+** (3) Insert newp as a new entry in the variants list. If there is
3786+** currently no variant header, this requires adding one. Adding a
3787+** header splits into two sub-cases:
3788+**
3789+** (3a) If oldp is ALLCAPS and the KEEP flags match, just turn it
3790+** into the header.
3791+** (3b) Otherwise, add a new entry to serve as the header.
3792+** To ease list linking, this is done by copying oldp into
3793+** the new entry, and then performing(3a).
3794+**
3795+** After newp has been added as a variant, its affixes and KEEP
3796+** flag are OR-ed into the variant header.
3797+#endif
3798+**
3799+** So how to choose which? The default is always case(3), which adds newp
3800+** as a new entry in the variants list. Cases(1) and (2) are symmetrical
3801+** except for which entry is discarded. We can use case(1) or (2) whenever
3802+** one entry "covers" the other. "Covering" is defined as follows:
3803+**
3804+** (4) For entries with matching capitalization types, A covers B
3805+** if:
3806+**
3807+** (4a) B's affix flags are a subset of A's, or the KEEP flags
3808+** match, and
3809+** (4b) either the KEEP flags match, or A's KEEP flag is set.
3810+** (Since A has more suffixes, combining B with it won't
3811+** cause any extra suffixes to be added to the dictionary.)
3812+** (4c) If the words are FOLLOWCASE, the capitalizations match
3813+** exactly.
3814+**
3815+#ifndef NO_CAPITALIZATION_SUPPORT
3816+** (5) For entries with mismatched capitalization types, A covers B
3817+** if(4a) and(4b) are true, and:
3818+**
3819+** (5a) B is ALLCAPS, or
3820+** (5b) A is ANYCASE, and B is CAPITALIZED.
3821+#endif
3822+**
3823+** For any "hdrp" without variants, oldp is the same as hdrp. Otherwise,
3824+** the above tests are applied using each variant in turn for oldp.
3825+*/
3826+Public int
3827+combinecaps(
3828+ struct dent * hdrp, /* Header of entry currently in dictionary */
3829+ register struct dent * newp) /* Entry to add */
3830+{
3831+ register struct dent *
3832+ oldp; /* Current "oldp" entry */
3833+#ifndef NO_CAPITALIZATION_SUPPORT
3834+ register struct dent *
3835+ tdent; /* Entry we'll add to the dictionary */
3836+#endif /* NO_CAPITALIZATION_SUPPORT */
3837+ register int retval = 0; /* Return value from combine_two_entries */
3838+
3839+ /*
3840+ ** First, see if we can combine the two entries(cases 1 and 2). If
3841+ ** combine_two_entries does so, it will return 1. If it has trouble,
3842+ ** it will return zero.
3843+ */
3844+ oldp = hdrp;
3845+#ifdef NO_CAPITALIZATION_SUPPORT
3846+ retval = combine_two_entries(hdrp, oldp, newp);
3847+#else /* NO_CAPITALIZATION_SUPPORT */
3848+ if((oldp->flagfield &(CAPTYPEMASK | MOREVARIANTS))
3849+ == (ALLCAPS | MOREVARIANTS))
3850+ {
3851+ while(oldp->flagfield & MOREVARIANTS)
3852+ {
3853+ oldp = oldp->next;
3854+ retval = combine_two_entries(hdrp, oldp, newp);
3855+ if(retval != 0) /* Did we combine them? */
3856+ break;
3857+ }
3858+ }
3859+ else
3860+ retval = combine_two_entries(hdrp, oldp, newp);
3861+ if(retval == 0)
3862+ {
3863+ /*
3864+ ** Couldn't combine the two entries. Add a new variant. For
3865+ ** ease, we'll stick it right behind the header, rather than
3866+ ** at the end of the list.
3867+ */
3868+ forcevheader(hdrp, oldp, newp);
3869+ tdent = (struct dent *) malloc (sizeof (struct dent));
3870+ if(tdent == NULL)
3871+ {
3872+ (void) fprintf (stderr, MAKEDENT_C_NO_WORD_SPACE, newp->word);
3873+ return -1;
3874+ }
3875+ *tdent = *newp;
3876+ tdent->next = hdrp->next;
3877+ hdrp->next = tdent;
3878+ tdent->flagfield |= (hdrp->flagfield & MOREVARIANTS);
3879+ hdrp->flagfield |= MOREVARIANTS;
3880+ combineaffixes(hdrp, newp);
3881+ hdrp->flagfield |= (newp->flagfield & KEEP);
3882+ if(captype(newp->flagfield) == FOLLOWCASE)
3883+ tdent->word = newp->word;
3884+ else
3885+ {
3886+ tdent->word = NULL;
3887+ free(newp->word); /* newp->word isn't needed */
3888+ }
3889+ }
3890+#endif /* NO_CAPITALIZATION_SUPPORT */
3891+ return retval;
3892+}
3893+
3894+#ifndef NO_CAPITALIZATION_SUPPORT
3895+/*
3896+** The following routine implements steps 3a and 3b in the commentary
3897+** for "combinecaps".
3898+*/
3899+Local void
3900+forcevheader(
3901+ register struct dent * hdrp,
3902+ struct dent * oldp,
3903+ struct dent * newp)
3904+{
3905+
3906+ if((hdrp->flagfield &(CAPTYPEMASK | MOREVARIANTS)) == ALLCAPS
3907+ && ((oldp->flagfield ^ newp->flagfield) & KEEP) == 0)
3908+ return; /* Caller will set MOREVARIANTS */
3909+ else if((hdrp->flagfield &(CAPTYPEMASK | MOREVARIANTS))
3910+ != (ALLCAPS | MOREVARIANTS))
3911+ (void) addvheader(hdrp);
3912+}
3913+#endif /* NO_CAPITALIZATION_SUPPORT */
3914+
3915+/*
3916+** This routine implements steps 4 and 5 of the commentary for "combinecaps".
3917+**
3918+** Returns 1 if newp can be discarded, 0 if nothing done.
3919+*/
3920+Local int
3921+combine_two_entries(
3922+ struct dent *hdrp, /*(Possible) header of variant chain */
3923+ register struct dent *oldp, /* Pre-existing dictionary entry */
3924+ register struct dent *newp) /* Entry to possibly combine */
3925+{
3926+
3927+ if(acoversb(oldp, newp))
3928+ {
3929+ /* newp is superfluous. Drop it, preserving affixes and keep flag */
3930+ combineaffixes(oldp, newp);
3931+ oldp->flagfield |= (newp->flagfield & KEEP);
3932+ hdrp->flagfield |= (newp->flagfield & KEEP);
3933+ free(newp->word);
3934+ return 1;
3935+ }
3936+ else if(acoversb(newp, oldp))
3937+ {
3938+ /*
3939+ ** oldp is superfluous. Replace it with newp, preserving affixes and
3940+ ** the keep flag.
3941+ */
3942+ combineaffixes(newp, oldp);
3943+#ifdef NO_CAPITALIZATION_SUPPORT
3944+ newp->flagfield |= (oldp->flagfield & KEEP);
3945+#else /* NO_CAPITALIZATION_SUPPORT */
3946+ newp->flagfield |= (oldp->flagfield & (KEEP | MOREVARIANTS));
3947+#endif /* NO_CAPITALIZATION_SUPPORT */
3948+ hdrp->flagfield |= (newp->flagfield & KEEP);
3949+ newp->next = oldp->next;
3950+ /*
3951+ ** We really want to free oldp->word, but that might be part of
3952+ ** "hashstrings". So we'll futz around to arrange things so we can
3953+ ** free newp->word instead. This depends very much on the fact
3954+ ** that both words are the same length.
3955+ */
3956+ if(oldp->word != NULL)
3957+ (void) strcpy (oldp->word, newp->word);
3958+ free(newp->word); /* No longer needed */
3959+ newp->word = oldp->word;
3960+ *oldp = *newp;
3961+#ifndef NO_CAPITALIZATION_SUPPORT
3962+ /* We may need to add a header if newp is followcase */
3963+ if(captype(newp->flagfield) == FOLLOWCASE
3964+ && (hdrp->flagfield & (CAPTYPEMASK | MOREVARIANTS))
3965+ != (ALLCAPS | MOREVARIANTS))
3966+ (void) addvheader (hdrp);
3967+#endif /* NO_CAPITALIZATION_SUPPORT */
3968+ return 1;
3969+ }
3970+ else
3971+ return 0;
3972+}
3973+
3974+/*
3975+** Determine if enta covers entb, according to the rules in steps 4 and 5
3976+** of the commentary for "combinecaps".
3977+*/
3978+Local int
3979+acoversb(
3980+ register struct dent * enta, /* "A" in the rules */
3981+ register struct dent * entb) /* "B" in the rules */
3982+{
3983+ int subset; /* NZ if entb is a subset of enta */
3984+
3985+ if((subset = issubset(entb, enta)) != 0)
3986+ {
3987+ /* entb is a subset of enta; thus enta might cover entb */
3988+ if(((enta->flagfield ^ entb->flagfield) & KEEP) != 0
3989+ && (enta->flagfield & KEEP) == 0) /* Inverse of condition (4b) */
3990+ return 0;
3991+ }
3992+ else
3993+ {
3994+ /* not a subset; KEEP flags must match exactly(both (4a) and (4b)) */
3995+ if(((enta->flagfield ^ entb->flagfield) & KEEP) != 0)
3996+ return 0;
3997+ }
3998+
3999+ /* Rules(4a) and (4b) are satisfied; check for capitalization match */
4000+#ifdef NO_CAPITALIZATION_SUPPORT
4001+#ifdef lint
4002+ return subset; /* Just so it gets used */
4003+#else /* lint */
4004+ return 1; /* All words match */
4005+#endif /* lint */
4006+#else /* NO_CAPITALIZATION_SUPPORT */
4007+ if(((enta->flagfield ^ entb->flagfield) & CAPTYPEMASK) == 0)
4008+ {
4009+ if(captype(enta->flagfield) != FOLLOWCASE /* Condition (4c) */
4010+ || strcmp(enta->word, entb->word) == 0)
4011+ return 1; /* Perfect match */
4012+ else
4013+ return 0;
4014+ }
4015+ else if(subset == 0) /* No flag subset, refuse */
4016+ return 0; /* ..near matches */
4017+ else if(captype(entb->flagfield) == ALLCAPS)
4018+ return 1;
4019+ else if(captype(enta->flagfield) == ANYCASE
4020+ && captype(entb->flagfield) == CAPITALIZED)
4021+ return 1;
4022+ else
4023+ return 0;
4024+#endif /* NO_CAPITALIZATION_SUPPORT */
4025+}
4026+
4027+Public void
4028+upcase(register ichar_t * s)
4029+{
4030+
4031+ while(*s)
4032+ {
4033+ *s = mytoupper(*s);
4034+ s++;
4035+ }
4036+}
4037+
4038+Public void
4039+lowcase(register ichar_t * s)
4040+{
4041+
4042+ while(*s)
4043+ {
4044+ *s = mytolower(*s);
4045+ s++;
4046+ }
4047+}
4048+
4049+/*
4050+ * Upcase variant that works on normal strings. Note that it is a lot
4051+ * slower than the normal upcase. The input must be in canonical form.
4052+ */
4053+Public void
4054+chupcase(char * s)
4055+{
4056+ ichar_t * is;
4057+
4058+ is = strtosichar(s, 1);
4059+ upcase(is);
4060+ (void) ichartostr (s, is, strlen (s) + 1, 1);
4061+}
4062+
4063+/*
4064+** See if one affix field is a subset of another. Returns NZ if ent1
4065+** is a subset of ent2. The KEEP flag is not taken into consideration.
4066+*/
4067+Local int
4068+issubset(
4069+ register struct dent * ent1,
4070+ register struct dent * ent2)
4071+{
4072+/* The following is really testing for MASKSIZE > 1, but cpp can't do that */
4073+#if MASKBITS > 32
4074+ register int flagword;
4075+
4076+#ifdef FULLMASKSET
4077+#define MASKMAX MASKSIZE
4078+#else
4079+#define MASKMAX MASKSIZE - 1
4080+#endif /* FULLMASKSET */
4081+ for(flagword = MASKMAX; --flagword >= 0; )
4082+ {
4083+ if((ent1->mask[flagword] & ent2->mask[flagword])
4084+ != ent1->mask[flagword])
4085+ return 0;
4086+ }
4087+#endif /* MASKBITS > 32 */
4088+#ifdef FULLMASKSET
4089+ return((ent1->mask[MASKSIZE - 1] & ent2->mask[MASKSIZE - 1])
4090+ == ent1->mask[MASKSIZE - 1]);
4091+#else
4092+ if(((ent1->mask[MASKSIZE - 1] & ent2->mask[MASKSIZE - 1])
4093+ ^ ent1->mask[MASKSIZE - 1]) & ~ALLFLAGS)
4094+ return 0;
4095+ else
4096+ return 1;
4097+#endif /* FULLMASKSET */
4098+}
4099+
4100+/*
4101+** Add ent2's affix flags to ent1.
4102+*/
4103+Local void
4104+combineaffixes(
4105+ register struct dent * ent1,
4106+ register struct dent * ent2)
4107+{
4108+/* The following is really testing for MASKSIZE > 1, but cpp can't do that */
4109+#if MASKBITS > 32
4110+ register int flagword;
4111+
4112+ if(ent1 == ent2)
4113+ return;
4114+ /* MASKMAX is defined in issubset, just above */
4115+ for(flagword = MASKMAX; --flagword >= 0; )
4116+ ent1->mask[flagword] |= ent2->mask[flagword];
4117+#endif /* MASKBITS > 32 */
4118+#ifndef FULLMASKSET
4119+ ent1->mask[MASKSIZE - 1] |= ent2->mask[MASKSIZE - 1] & ~ALLFLAGS;
4120+#endif
4121+}
4122+
4123+/*
4124+** Write out a dictionary entry, including capitalization variants.
4125+** If onlykeep is true, only those variants with KEEP set will be
4126+** written.
4127+*/
4128+Public void
4129+toutent(
4130+ register FILE * toutfile,
4131+ struct dent * hent,
4132+ register int onlykeep)
4133+{
4134+#ifdef NO_CAPITALIZATION_SUPPORT
4135+ if(!onlykeep || (hent->flagfield & KEEP))
4136+ toutword(toutfile, hent->word, hent);
4137+#else
4138+ register struct dent * cent;
4139+ ichar_t wbuf[INPUTWORDLEN + MAXAFFIXLEN];
4140+
4141+ cent = hent;
4142+ if(strtoichar(wbuf, cent->word, INPUTWORDLEN, 1))
4143+ (void) fprintf(stderr, WORD_TOO_LONG (cent->word));
4144+ for( ; ; )
4145+ {
4146+ if(!onlykeep || (cent->flagfield & KEEP))
4147+ {
4148+ switch(captype (cent->flagfield))
4149+ {
4150+ case ANYCASE:
4151+ lowcase(wbuf);
4152+ toutword(toutfile, ichartosstr (wbuf, 1), cent);
4153+ break;
4154+ case ALLCAPS:
4155+ if((cent->flagfield & MOREVARIANTS) == 0 || cent != hent)
4156+ {
4157+ upcase(wbuf);
4158+ toutword(toutfile, ichartosstr (wbuf, 1), cent);
4159+ }
4160+ break;
4161+ case CAPITALIZED:
4162+ lowcase(wbuf);
4163+ wbuf[0] = mytoupper(wbuf[0]);
4164+ toutword(toutfile, ichartosstr (wbuf, 1), cent);
4165+ break;
4166+ case FOLLOWCASE:
4167+ toutword(toutfile, cent->word, cent);
4168+ break;
4169+ }
4170+ }
4171+ if(cent->flagfield & MOREVARIANTS)
4172+ cent = cent->next;
4173+ else
4174+ break;
4175+ }
4176+#endif
4177+}
4178+
4179+Local void
4180+toutword(
4181+ register FILE * toutfile,
4182+ char * word,
4183+ register struct dent * cent)
4184+{
4185+ register int bit;
4186+
4187+ has_marker = False;
4188+ (void) fprintf (toutfile, "%s", word);
4189+ for(bit = 0; bit < LARGESTFLAG; bit++)
4190+ {
4191+ if(TSTMASKBIT(cent->mask, bit))
4192+ flagout(toutfile, BITTOCHAR (bit));
4193+ }
4194+ (void) fprintf (toutfile, "\n");
4195+}
4196+
4197+Local void
4198+flagout(
4199+ register FILE * toutfile,
4200+ int flag)
4201+{
4202+ if(!has_marker)
4203+ (void) putc(hashheader.flagmarker, toutfile);
4204+ has_marker = True;
4205+ (void) putc (flag, toutfile);
4206+}
4207+
4208+/*
4209+ * If the string under the given pointer begins with a string character,
4210+ * return the length of that "character". If not, return 0.
4211+ * May be called any time, but it's best if "isstrstart" is first
4212+ * used to filter out unnecessary calls.
4213+ *
4214+ * As a side effect, "laststringch" is set to the number of the string
4215+ * found, or to -1 if none was found. This can be useful for such things
4216+ * as case conversion.
4217+ */
4218+Public int
4219+stringcharlen(
4220+ char * bufp,
4221+ int canonical) /* NZ if input is in canonical form */
4222+{
4223+#ifdef SLOWMULTIPLY
4224+ static char * sp[MAXSTRINGCHARS];
4225+ static int m_inited = 0;
4226+#endif /* SLOWMULTIPLY */
4227+ register char * bufcur;
4228+ register char * stringcur;
4229+ register int stringno;
4230+ register int lowstringno;
4231+ register int highstringno;
4232+ int dupwanted;
4233+
4234+#ifdef SLOWMULTIPLY
4235+ if(!m_inited)
4236+ {
4237+ m_inited = 1;
4238+ for(stringno = 0; stringno < MAXSTRINGCHARS; stringno++)
4239+ sp[stringno] = &hashheader.stringchars[stringno][0];
4240+ }
4241+#endif /* SLOWMULTIPLY */
4242+ lowstringno = 0;
4243+ highstringno = hashheader.nstrchars - 1;
4244+ dupwanted = canonical ? 0 : defdupchar;
4245+ while(lowstringno <= highstringno)
4246+ {
4247+ stringno = (lowstringno + highstringno) >> 1;
4248+#ifdef SLOWMULTIPLY
4249+ stringcur = sp[stringno];
4250+#else /* SLOWMULTIPLY */
4251+ stringcur = &hashheader.stringchars[stringno][0];
4252+#endif /* SLOWMULTIPLY */
4253+ bufcur = bufp;
4254+ while(*stringcur)
4255+ {
4256+#ifdef NO8BIT
4257+ if(((*bufcur++ ^ *stringcur) & 0x7F) != 0)
4258+#else /* NO8BIT */
4259+ if(*bufcur++ != *stringcur)
4260+#endif /* NO8BIT */
4261+ break;
4262+ /*
4263+ ** We can't use autoincrement above because of the
4264+ ** test below.
4265+ */
4266+ stringcur++;
4267+ }
4268+ if(*stringcur == '\0')
4269+ {
4270+ if(hashheader.dupnos[stringno] == dupwanted)
4271+ {
4272+ /* We have a match */
4273+ laststringch = hashheader.stringdups[stringno];
4274+#ifdef SLOWMULTIPLY
4275+ return stringcur - sp[stringno];
4276+#else /* SLOWMULTIPLY */
4277+ return stringcur - &hashheader.stringchars[stringno][0];
4278+#endif /* SLOWMULTIPLY */
4279+ }
4280+ else
4281+ --stringcur;
4282+ }
4283+ /* No match - choose which side to search on */
4284+#ifdef NO8BIT
4285+ if((*--bufcur & 0x7F) <(*stringcur & 0x7F))
4286+ highstringno = stringno - 1;
4287+ else if((*bufcur & 0x7F) >(*stringcur & 0x7F))
4288+ lowstringno = stringno + 1;
4289+#else /* NO8BIT */
4290+ if(*--bufcur < *stringcur)
4291+ highstringno = stringno - 1;
4292+ else if(*bufcur > *stringcur)
4293+ lowstringno = stringno + 1;
4294+#endif /* NO8BIT */
4295+ else if(dupwanted < hashheader.dupnos[stringno])
4296+ highstringno = stringno - 1;
4297+ else
4298+ lowstringno = stringno + 1;
4299+ }
4300+ laststringch = -1;
4301+ return 0; /* Not a string character */
4302+}
4303+
4304+/*
4305+ * Convert an external string to an ichar_t string. If necessary, the parity
4306+ * bit is stripped off as part of the process.
4307+ *
4308+ * Returns NZ if the output string overflowed.
4309+ */
4310+Public int
4311+strtoichar(
4312+ register ichar_t * out, /* Where to put result */
4313+ register char * in, /* String to convert */
4314+ int outlen, /* Size of output buffer, *BYTES* */
4315+ int canonical) /* NZ if input is in canonical form */
4316+{
4317+ register int len; /* Length of next character */
4318+
4319+ outlen /= sizeof(ichar_t); /* Convert to an ichar_t count */
4320+ for( ; --outlen > 0 && *in != '\0'; in += len)
4321+ {
4322+ if(l1_isstringch(in, len, canonical))
4323+ *out++ = SET_SIZE + laststringch;
4324+ else
4325+ *out++ = *in & S_NOPARITY;
4326+ }
4327+ *out = 0;
4328+ return outlen <= 0;
4329+}
4330+
4331+/*
4332+ * Convert an ichar_t string to an external string.
4333+ *
4334+ * WARNING: the resulting string may wind up being longer than the
4335+ * original. In fact, even the sequence strtoichar->ichartostr may
4336+ * produce a result longer than the original, because the output form
4337+ * may use a different string type set than the original input form.
4338+ *
4339+ * Returns NZ if the output string overflowed.
4340+ */
4341+Public int
4342+ichartostr(
4343+ register char * out, /* Where to put result */
4344+ register ichar_t * in, /* String to convert */
4345+ int outlen, /* Size of output buffer, bytes */
4346+ int canonical) /* NZ for canonical form */
4347+{
4348+ register unsigned int ch; /* Next character to store */
4349+ register unsigned int i; /* Index into duplicates list */
4350+ register char * scharp; /* Pointer into a string char */
4351+
4352+ while(--outlen > 0 && (ch = *in++) != 0)
4353+ {
4354+ if(ch < SET_SIZE)
4355+ *out++ = (char) ch;
4356+ else
4357+ {
4358+ ch -= SET_SIZE;
4359+ if(!canonical)
4360+ {
4361+ for(i = hashheader.nstrchars; --i >= 0; )
4362+ {
4363+ if(hashheader.dupnos[i] == defdupchar
4364+ && hashheader.stringdups[i] == ch)
4365+ {
4366+ ch = i;
4367+ break;
4368+ }
4369+ }
4370+ }
4371+ scharp = hashheader.stringchars[(unsigned) ch];
4372+ while((*out++ = *scharp++) != '\0')
4373+ ;
4374+ out--;
4375+ }
4376+ }
4377+ *out = '\0';
4378+ return outlen <= 0;
4379+}
4380+
4381+/*
4382+ * Convert a string to an ichar_t, storing the result in a static area.
4383+ */
4384+Public ichar_t *
4385+strtosichar(
4386+ char * in, /* String to convert */
4387+ int canonical) /* NZ if input is in canonical form */
4388+{
4389+ static ichar_t out[STRTOSICHAR_SIZE / sizeof(ichar_t)];
4390+
4391+ if(strtoichar(out, in, sizeof out, canonical))
4392+ (void) fprintf(stderr, WORD_TOO_LONG (in));
4393+ return out;
4394+}
4395+
4396+/*
4397+ * Convert an ichar_t to a string, storing the result in a static area.
4398+ */
4399+Public char *
4400+ichartosstr(
4401+ ichar_t * in, /* Internal string to convert */
4402+ int canonical) /* NZ for canonical conversion */
4403+{
4404+ static char out[ICHARTOSSTR_SIZE];
4405+
4406+ if(ichartostr(out, in, sizeof out, canonical))
4407+ (void) fprintf(stderr, WORD_TOO_LONG (out));
4408+ return out;
4409+}
4410+
4411+/*
4412+ * Convert a single ichar to a printable string, storing the result in
4413+ * a static area.
4414+ */
4415+Public char *
4416+printichar(int in)
4417+{
4418+ static char out[MAXSTRINGCHARLEN + 1];
4419+
4420+ if(in < SET_SIZE)
4421+ {
4422+ out[0] = (char) in;
4423+ out[1] = '\0';
4424+ }
4425+ else
4426+ (void) strcpy(out, hashheader.stringchars[(unsigned) in - SET_SIZE]);
4427+ return out;
4428+}
4429+
4430+#ifndef ICHAR_IS_CHAR
4431+/*
4432+ * Copy an ichar_t.
4433+ */
4434+Public ichar_t *
4435+icharcpy(
4436+ register ichar_t * out, /* Destination */
4437+ register ichar_t * in) /* Source */
4438+{
4439+ ichar_t * origout; /* Copy of destination for return */
4440+
4441+ origout = out;
4442+ while((*out++ = *in++) != 0)
4443+ ;
4444+ return origout;
4445+}
4446+
4447+/*
4448+ * Return the length of an ichar_t.
4449+ */
4450+Public int
4451+icharlen(register ichar_t * in) /* String to count */
4452+{
4453+ register int len; /* Length so far */
4454+
4455+ for(len = 0; *in++ != 0; len++)
4456+ ;
4457+ return len;
4458+}
4459+
4460+/*
4461+ * Compare two ichar_t's.
4462+ */
4463+Public int
4464+icharcmp(
4465+ register ichar_t * s1,
4466+ register ichar_t * s2)
4467+{
4468+
4469+ while(*s1 != 0)
4470+ {
4471+ if(*s1++ != *s2++)
4472+ return *--s1 - *--s2;
4473+ }
4474+ return *s1 - *s2;
4475+}
4476+
4477+/*
4478+ * Strncmp for two ichar_t's.
4479+ */
4480+Public int
4481+icharncmp(
4482+ register ichar_t * s1,
4483+ register ichar_t * s2,
4484+ register int n)
4485+{
4486+
4487+ while(--n >= 0 && *s1 != 0)
4488+ {
4489+ if(*s1++ != *s2++)
4490+ return *--s1 - *--s2;
4491+ }
4492+ if(n < 0)
4493+ return 0;
4494+ else
4495+ return *s1 - *s2;
4496+}
4497+
4498+#endif /* ICHAR_IS_CHAR */
4499+
4500+Public int
4501+findfiletype(
4502+ char * name, /* Name to look up in suffix table */
4503+ int searchnames, /* NZ to search name field of table */
4504+ int * deformatter) /* Where to set deformatter type */
4505+{
4506+ char * cp; /* Pointer into suffix list */
4507+ int cplen; /* Length of current suffix */
4508+ register int i; /* Index into type table */
4509+ int len; /* Length of the name */
4510+
4511+ /*
4512+ * Note: for now, the deformatter is set to 1 for tex, 0 for nroff.
4513+ * Further, we assume that it's one or the other, so that a test
4514+ * for tex is sufficient. This needs to be generalized.
4515+ */
4516+ len = strlen(name);
4517+ if(searchnames)
4518+ {
4519+ for(i = 0; i < hashheader.nstrchartype; i++)
4520+ {
4521+ if(strcmp(name, chartypes[i].name) == 0)
4522+ {
4523+ if(deformatter != NULL)
4524+ *deformatter =
4525+ (strcmp (chartypes[i].deformatter, "tex") == 0);
4526+ return i;
4527+ }
4528+ }
4529+ }
4530+ for(i = 0; i < hashheader.nstrchartype; i++)
4531+ {
4532+ for(cp = chartypes[i].suffixes; *cp != '\0'; cp += cplen + 1)
4533+ {
4534+ cplen = strlen(cp);
4535+ if(len >= cplen && strcmp(&name[len - cplen], cp) == 0)
4536+ {
4537+ if(deformatter != NULL)
4538+ *deformatter =
4539+ (strcmp (chartypes[i].deformatter, "tex") == 0);
4540+ return i;
4541+ }
4542+ }
4543+ }
4544+ return -1;
4545+}
4546+
4547+Public char *
4548+mypath_rindex(char const *str, char c)
4549+{
4550+ register char *x;
4551+
4552+ x = (char *)str + strlen(str);
4553+
4554+ while(x >= str)
4555+ {
4556+ if(*x == '\\' || *x == '/' || *x == ':')
4557+ return(NULL);
4558+ else if(*x == c)
4559+ return(x);
4560+ else
4561+ x--;
4562+ }
4563+ return(NULL);
4564+}
41e3656f 4565diff -ruN vim62./src/spell/msgs.h vim62/src/spell/msgs.h
4566--- vim62./src/spell/msgs.h 1970-01-01 01:00:00.000000000 +0100
4567+++ vim62/src/spell/msgs.h 2003-06-02 19:57:21.000000000 +0200
24ec98f0
JB
4568@@ -0,0 +1,278 @@
4569+/*
4570+ * $Id$
4571+ *
4572+ * Copyright 1992, 1993, Geoff Kuenning, Granada Hills, CA
4573+ * All rights reserved.
4574+ *
4575+ * Redistribution and use in source and binary forms, with or without
4576+ * modification, are permitted provided that the following conditions
4577+ * are met:
4578+ *
4579+ * 1. Redistributions of source code must retain the above copyright
4580+ * notice, this list of conditions and the following disclaimer.
4581+ * 2. Redistributions in binary form must reproduce the above copyright
4582+ * notice, this list of conditions and the following disclaimer in the
4583+ * documentation and/or other materials provided with the distribution.
4584+ * 3. All modifications to the source code must be clearly marked as
4585+ * such. Binary redistributions based on modified source code
4586+ * must be clearly marked as modified versions in the documentation
4587+ * and/or other materials provided with the distribution.
4588+ * 4. All advertising materials mentioning features or use of this software
4589+ * must display the following acknowledgment:
4590+ * This product includes software developed by Geoff Kuenning and
4591+ * other unpaid contributors.
4592+ * 5. The name of Geoff Kuenning may not be used to endorse or promote
4593+ * products derived from this software without specific prior
4594+ * written permission.
4595+ *
4596+ * THIS SOFTWARE IS PROVIDED BY GEOFF KUENNING AND CONTRIBUTORS ``AS IS'' AND
4597+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
4598+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
4599+ * ARE DISCLAIMED. IN NO EVENT SHALL GEOFF KUENNING OR CONTRIBUTORS BE LIABLE
4600+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
4601+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
4602+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
4603+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
4604+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
4605+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
4606+ * SUCH DAMAGE.
4607+ *
4608+ */
4609+
4610+/*
4611+ * Messages header file.
4612+ *
4613+ * This file contains all text strings that are written by any of the
4614+ * C programs in the ispell package. The strings are collected here so that
4615+ * you can have the option of translating them into your local language for
4616+ * the benefit of your users.
4617+ *
4618+ * Anyone who goes to the effort of making a translation may wish to return
4619+ * the translated strings to me, geoff@ITcorp.com, so that I can include
4620+ * them in a later distribution under #ifdef control.
4621+ *
4622+ * Besides the strings in this header file, you may also want to translate
4623+ * the strings in version.h, which give the version and copyright information.
4624+ * However, any translation of these strings MUST accurately preserve the
4625+ * legal rights under international law; you may wish to consult a lawyer
4626+ * about this since you will be responsible for the results of any
4627+ * incorrect translation.
4628+ *
4629+ * Most of the strings below are simple printf format strings. If the printf
4630+ * takes more than one parameter, the string is given as a parameterized
4631+ * macro in case your local language needs a different word order.
4632+ */
4633+
4634+/*
4635+ * $Log$
4636+ * Revision 1.31 1994/12/27 23:08:57 geoff
4637+ * Add a message to be issued if a word contains illegal characters.
4638+ *
4639+ * Revision 1.30 1994/10/25 05:46:40 geoff
4640+ * Improve a couple of error messages relating to affix flags.
4641+ *
4642+ * Revision 1.29 1994/10/04 03:46:23 geoff
4643+ * Add a missing carriage return in the help message
4644+ *
4645+ * Revision 1.28 1994/09/16 05:07:00 geoff
4646+ * Add the BAD_FLAG message, and start a sentence in another message with
4647+ * an uppercase letter.
4648+ *
4649+ * Revision 1.27 1994/07/28 05:11:38 geoff
4650+ * Log message for previous revision: add BHASH_C_ZERO_COUNT.
4651+ *
4652+ * Revision 1.26 1994/07/28 04:53:49 geoff
4653+ *
4654+ * Revision 1.25 1994/05/24 04:54:36 geoff
4655+ * Add error messages for affix-flag checking.
4656+ *
4657+ * Revision 1.24 1994/01/25 07:12:42 geoff
4658+ * Get rid of all old RCS log lines in preparation for the 3.1 release.
4659+ *
4660+ */
4661+
4662+/*
4663+ * The following strings are used in numerous places:
4664+ */
4665+#define BAD_FLAG "\nIllegal affix flag character '%c'\n"
4666+#define CANT_OPEN "Can't open %s"
4667+#define CANT_CREATE "Can't create %s\n"
4668+#define WORD_TOO_LONG(w) "\nWord '%s' too long at line %d of %s, truncated\n", \
4669+ w, __LINE__, __FILE__
4670+
4671+/*
4672+ * The following strings are used in buildhash.c:
4673+ */
4674+#define BHASH_C_NO_DICT "No dictionary (%s)\n"
4675+#define BHASH_C_NO_COUNT "No count file\n"
4676+#define BHASH_C_BAD_COUNT "Bad count file\n"
4677+#define BHASH_C_ZERO_COUNT "No words in dictionary\n"
4678+ /* I think this message looks better when it's nearly 80 characters wide,
4679+ * thus the ugly formatting in the next two defines. GK 9-87 */
4680+#define BHASH_C_BAFF_1(max, excess) \
4681+ " Warning: this language table may exceed the maximum total affix length\nof %d by up to %d bytes. You should either increase MAXAFFIXLEN in config.X\nor shorten your largest affix/strip string difference. (This is the\n", \
4682+ max, excess
4683+#define BHASH_C_BAFF_2 \
4684+ "difference between the affix length and the strip length in a given\nreplacement rule, or the affix length if there is no strip string\nin that rule.)\n"
4685+#define BHASH_C_OVERFLOW "Hash table overflowed by %d words\n"
4686+#define BHASH_C_CANT_OPEN_DICT "Can't open dictionary\n"
4687+#define BHASH_C_NO_SPACE "Couldn't allocate hash table\n"
4688+#define BHASH_C_COLLISION_SPACE "\ncouldn't allocate space for collision\n"
4689+#define BHASH_C_COUNTING "Counting words in dictionary ...\n"
4690+#define BHASH_C_WORD_COUNT "\n%d words\n"
4691+#define BHASH_C_USAGE "Usage: buildhash [-s] dict-file aff-file hash-file\n\tbuildhash -c count aff-file\n"
4692+
4693+/*
4694+ * The following strings are used in correct.c:
4695+ */
4696+#define CORR_C_HELP_1 "Whenever a word is found that is not in the dictionary,\n"
4697+#define CORR_C_HELP_2 "it is printed on the first line of the screen. If the dictionary\n"
4698+#define CORR_C_HELP_3 "contains any similar words, they are listed with a number\n"
4699+#define CORR_C_HELP_4 "next to each one. You have the option of replacing the word\n"
4700+#define CORR_C_HELP_5 "completely, or choosing one of the suggested words.\n"
4701+ /* You may add HELP_6 through HELP_9 if your language needs more lines */
4702+#define CORR_C_HELP_6 ""
4703+#define CORR_C_HELP_7 ""
4704+#define CORR_C_HELP_8 ""
4705+#define CORR_C_HELP_9 ""
4706+#define CORR_C_HELP_COMMANDS "\nCommands are:\n\n"
4707+#define CORR_C_HELP_R_CMD "R Replace the misspelled word completely.\n"
4708+#define CORR_C_HELP_BLANK "Space Accept the word this time only.\n"
4709+#define CORR_C_HELP_A_CMD "A Accept the word for the rest of this session.\n"
4710+#define CORR_C_HELP_I_CMD "I Accept the word, and put it in your private dictionary.\n"
4711+#define CORR_C_HELP_U_CMD "U Accept and add lowercase version to private dictionary.\n"
4712+#define CORR_C_HELP_0_CMD "0-n Replace with one of the suggested words.\n"
4713+#define CORR_C_HELP_L_CMD "L Look up words in system dictionary.\n"
4714+#define CORR_C_HELP_X_CMD "X Write the rest of this file, ignoring misspellings,\n and start next file.\n"
4715+#define CORR_C_HELP_Q_CMD "Q Quit immediately. Asks for confirmation.\n Leaves file unchanged.\n"
4716+#define CORR_C_HELP_BANG "! Shell escape.\n"
4717+#define CORR_C_HELP_REDRAW "^L Redraw screen.\n"
4718+#define CORR_C_HELP_SUSPEND "^Z Suspend program.\n"
4719+#define CORR_C_HELP_HELP "? Show this help screen.\n"
4720+#define CORR_C_HELP_TYPE_SPACE "-- Type space to continue --"
4721+
4722+#define CORR_C_FILE_LABEL " File: %s"
4723+#define CORR_C_READONLY "[READONLY]"
4724+#define CORR_C_MINI_MENU "[SP] <number> R)epl A)ccept I)nsert L)ookup U)ncap Q)uit e(X)it or ? for help\n"
4725+#define CORR_C_CONFIRM_QUIT "Are you sure you want to throw away your changes? "
4726+#define CORR_C_REPLACE_WITH "Replace with: "
4727+#define CORR_C_LOOKUP_PROMPT "Lookup string ('*' is wildcard): "
4728+#define CORR_C_MORE_PROMPT "-- more --"
4729+#define CORR_C_BLANK_MORE " "
4730+#define CORR_C_END_LOOK "--end--"
4731+
4732+/*
4733+ * The following strings are used in defmt.c:
4734+ */
4735+#define DEFMT_C_TEX_MATH_ERROR "****ERROR in parsing TeX math mode!\n"
4736+#define DEFMT_C_LR_MATH_ERROR "***ERROR in LR to math-mode switch.\n"
4737+
4738+/*
4739+ * The following strings are used in icombine.c:
4740+ */
4741+#define ICOMBINE_C_BAD_TYPE "icombine: unrecognized formatter type '%s'\n"
4742+#define ICOMBINE_C_USAGE "Usage: icombine [-T suffix] [aff-file] < wordlist\n"
4743+
4744+/*
4745+ * The following strings are used in ispell.c:
4746+ */
4747+#define ISPELL_C_USAGE1 "Usage: %s [-dfile | -pfile | -wchars | -Wn | -t | -n | -x | -b | -S | -B | -C | -P | -m | -Lcontext | -M | -N | -Ttype | -V] file .....\n"
4748+#define ISPELL_C_USAGE2 " %s [-dfile | -pfile | -wchars | -Wn | -t | -n | -Ttype] -l\n"
4749+#ifndef USG
4750+#define ISPELL_C_USAGE3 " %s [-dfile | -pfile | -ffile | -Wn | -t | -n | -s | -B | -C | -P | -m | -Ttype] {-a | -A}\n"
4751+#else
4752+#define ISPELL_C_USAGE3 " %s [-dfile | -pfile | -ffile | -Wn | -t | -n | -B | -C | -P | -m | -Ttype] {-a | -A}\n"
4753+#endif
4754+#define ISPELL_C_USAGE4 " %s [-dfile] [-wchars | -Wn] -c\n"
4755+#define ISPELL_C_USAGE5 " %s [-dfile] [-wchars] -e[1-4]\n"
4756+#define ISPELL_C_USAGE6 " %s [-dfile] [-wchars] -D\n"
4757+#define ISPELL_C_USAGE7 " %s -v\n"
4758+#define ISPELL_C_TEMP_DISAPPEARED "temporary file disappeared (%s)\n"
4759+#define ISPELL_C_BAD_TYPE "ispell: unrecognized formatter type '%s'\n"
4760+#define ISPELL_C_NO_FILE "ispell: specified file does not exist\n"
4761+#define ISPELL_C_NO_FILES "ispell: specified files do not exist\n"
4762+#define ISPELL_C_CANT_WRITE "Warning: Can't write to %s\n"
4763+#define ISPELL_C_OPTIONS_ARE "Compiled-in options:\n"
4764+#ifdef MSDOS
4765+#define ISPELL_C_NO_OPTIONS_SPACE "ispell: no memory to read default options\n"
4766+#endif
4767+
4768+/*
4769+ * The following strings are used in lookup.c:
4770+ */
4771+#define LOOKUP_C_CANT_READ "Trouble reading hash table %s"
4772+#define LOOKUP_C_NULL_HASH "Null hash table %s"
4773+#define LOOKUP_C_SHORT_HASH(name, gotten, wanted) \
4774+ "Truncated hash table %s: got %d bytes, expected %d", \
4775+ name, gotten, wanted
4776+#define LOOKUP_C_BAD_MAGIC(name, wanted, gotten) \
4777+ "Illegal format hash table %s - expected magic 0x%x, got 0x%x", \
4778+ name, wanted, gotten
4779+#define LOOKUP_C_BAD_MAGIC2(name, wanted, gotten) \
4780+ "Illegal format hash table %s - \nexpected magic2 0x%x, got 0x%x", \
4781+ name, wanted, gotten
4782+#define LOOKUP_C_BAD_OPTIONS(gotopts, gotchars, gotlen, wantedopts, wantedchars, wantedlen) \
4783+ "Hash table options don't agree with buildhash - 0x%x/%d/%d vs. 0x%x/%d/%d", \
4784+ gotopts, gotchars, gotlen, \
4785+ wantedopts, wantedchars, wantedlen
4786+#define LOOKUP_C_NO_HASH_SPACE "Couldn't allocate space for hash table"
4787+#define LOOKUP_C_BAD_FORMAT "Illegal format hash table"
4788+#define LOOKUP_C_NO_LANG_SPACE "Couldn't allocate space for language tables"
4789+
4790+/*
4791+ * The following strings are used in makedent.c:
4792+ */
4793+#define MAKEDENT_C_NO_WORD_SPACE "\nCouldn't allocate space for word '%s'\n"
4794+#define MAKEDENT_C_BAD_WORD_CHAR "\nWord '%s' contains illegal characters\n"
4795+
4796+/*
4797+ * The following strings are used in parse.y:
4798+ */
4799+#define PARSE_Y_8_BIT "Eighth bit ignored (recompile ispell without NO8BIT)"
4800+#define PARSE_Y_NO_WORD_STRINGS "wordchars statement may not specify string characters"
4801+#define PARSE_Y_UNMATCHED "Unmatched charset lengths"
4802+#define PARSE_Y_NO_BOUNDARY_STRINGS "boundarychars statement may not specify string characters"
4803+#define PARSE_Y_LONG_STRING "String character is too long"
4804+#define PARSE_Y_NULL_STRING "String character must have nonzero length"
4805+#define PARSE_Y_MANY_STRINGS "Too many string characters"
4806+#define PARSE_Y_NO_SUCH_STRING "No such string character"
4807+#define PARSE_Y_MULTIPLE_STRINGS "Alternate string character was already defined"
4808+#define PARSE_Y_LENGTH_MISMATCH "Upper and lower versions of string character must be same length"
4809+#define PARSE_Y_WRONG_NROFF "Incorrect character count in nroffchars statement"
4810+#define PARSE_Y_WRONG_TEX "Incorrect character count in TeXchars statement"
4811+#define PARSE_Y_DOUBLE_COMPOUND "Compoundwords option may only appear once"
4812+#define PARSE_Y_LONG_FLAG "Flag must be single character"
4813+#define PARSE_Y_BAD_FLAG "Flag must be alphabetic"
4814+#define PARSE_Y_DUP_FLAG "Duplicate flag"
4815+#define PARSE_Y_NO_SPACE "Out of memory"
4816+#define PARSE_Y_NEED_BLANK "Single characters must be separated by a blank"
4817+#define PARSE_Y_MANY_CONDS "Too many conditions; 8 maximum"
4818+#define PARSE_Y_EOF "Unexpected EOF in quoted string"
4819+#define PARSE_Y_LONG_QUOTE "Quoted string too long, max 256 characters"
4820+#define PARSE_Y_ERROR_FORMAT(file, lineno, error) \
4821+ "%s line %d: %s\n", file, lineno, error
4822+#define PARSE_Y_MALLOC_TROUBLE "yyopen: trouble allocating memory\n"
4823+#define PARSE_Y_UNGRAB_PROBLEM "Internal error: ungrab buffer overflow"
4824+#define PARSE_Y_BAD_DEFORMATTER "Deformatter must be either 'nroff' or 'tex'"
4825+#define PARSE_Y_BAD_NUMBER "Illegal digit in number"
4826+
4827+/*
4828+ * The following strings are used in term.c:
4829+ */
4830+#define TERM_C_SMALL_SCREEN "Screen too small: need at least %d lines\n"
4831+#define TERM_C_NO_BATCH "Can't deal with non-interactive use yet.\n"
4832+#define TERM_C_CANT_FORK "Couldn't fork, try later.\n"
4833+#define TERM_C_TYPE_SPACE "\n-- Type space to continue --"
4834+
4835+/*
4836+ * The following strings are used in tree.c:
4837+ */
4838+#define TREE_C_CANT_UPDATE "Warning: Cannot update personal dictionary (%s)\n"
4839+#define TREE_C_NO_SPACE "Ran out of space for personal dictionary\n"
4840+#define TREE_C_TRY_ANYWAY "Continuing anyway (with reduced performance).\n"
4841+
4842+/*
4843+ * The following strings are used in unsq.c:
4844+ */
4845+#define UNSQ_C_BAD_COUNT "Illegal count character 0x%x\n"
4846+#define UNSQ_C_SURPRISE_EOF "Unexpected EOF\n"
41e3656f 4847diff -ruN vim62./src/spell/tgood.c vim62/src/spell/tgood.c
4848--- vim62./src/spell/tgood.c 1970-01-01 01:00:00.000000000 +0100
4849+++ vim62/src/spell/tgood.c 2003-06-02 19:57:21.000000000 +0200
24ec98f0
JB
4850@@ -0,0 +1,654 @@
4851+/*
4852+ * Copyright 1987, 1988, 1989, 1992, 1993, Geoff Kuenning, Granada Hills, CA
4853+ * All rights reserved.
4854+ *
4855+ * Redistribution and use in source and binary forms, with or without
4856+ * modification, are permitted provided that the following conditions
4857+ * are met:
4858+ *
4859+ * 1. Redistributions of source code must retain the above copyright
4860+ * notice, this list of conditions and the following disclaimer.
4861+ * 2. Redistributions in binary form must reproduce the above copyright
4862+ * notice, this list of conditions and the following disclaimer in the
4863+ * documentation and/or other materials provided with the distribution.
4864+ * 3. All modifications to the source code must be clearly marked as
4865+ * such. Binary redistributions based on modified source code
4866+ * must be clearly marked as modified versions in the documentation
4867+ * and/or other materials provided with the distribution.
4868+ * 4. All advertising materials mentioning features or use of this software
4869+ * must display the following acknowledgment:
4870+ * This product includes software developed by Geoff Kuenning and
4871+ * other unpaid contributors.
4872+ * 5. The name of Geoff Kuenning may not be used to endorse or promote
4873+ * products derived from this software without specific prior
4874+ * written permission.
4875+ *
4876+ * THIS SOFTWARE IS PROVIDED BY GEOFF KUENNING AND CONTRIBUTORS ``AS IS'' AND
4877+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
4878+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
4879+ * ARE DISCLAIMED. IN NO EVENT SHALL GEOFF KUENNING OR CONTRIBUTORS BE LIABLE
4880+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
4881+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
4882+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
4883+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
4884+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
4885+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
4886+ * SUCH DAMAGE.
4887+ */
4888+
4889+/*
4890+ * Table-driven version of good.c.
4891+ *
4892+ * Geoff Kuenning, July 1987
4893+ */
4894+
4895+/*
4896+ * $Log$
4897+ * Revision 1.32 1994/11/02 06:56:16 geoff
4898+ * Remove the anyword feature, which I've decided is a bad idea.
4899+ *
4900+ * Revision 1.31 1994/10/25 05:46:25 geoff
4901+ * Add support for the FF_ANYWORD (affix applies to all words, even if
4902+ * flag bit isn't set) flag option.
4903+ *
4904+ * Revision 1.30 1994/05/24 06:23:08 geoff
4905+ * Don't create a hit if "allhits" is clear and capitalization
4906+ * mismatches. This cures a bug where a word could be in the dictionary
4907+ * and yet not found.
4908+ *
4909+ * Revision 1.29 1994/05/17 06:44:21 geoff
4910+ * Add support for controlled compound formation and the COMPOUNDONLY
4911+ * option to affix flags.
4912+ *
4913+ * Revision 1.28 1994/01/25 07:12:13 geoff
4914+ * Get rid of all old RCS log lines in preparation for the 3.1 release.
4915+ *
4916+ */
4917+
4918+#include <ctype.h>
4919+#include "ispell.h"
4920+
4921+Global void chk_aff (ichar_t * word, ichar_t * ucword, int len,
4922+ int ignoreflagbits, int allhits, int pfxopts, int sfxopts);
4923+Local void pfx_list_chk (ichar_t * word, ichar_t * ucword,
4924+ int len, int optflags, int sfxopts, struct flagptr * ind,
4925+ int ignoreflagbits, int allhits);
4926+Local void chk_suf (ichar_t * word, ichar_t * ucword, int len,
4927+ int optflags, struct flagent * pfxent, int ignoreflagbits,
4928+ int allhits);
4929+Local void suf_list_chk (ichar_t * word, ichar_t * ucword, int len,
4930+ struct flagptr * ind, int optflags, struct flagent * pfxent,
4931+ int ignoreflagbits, int allhits);
4932+Global int expand_pre (char * croot, ichar_t * rootword,
4933+ MASKTYPE mask[], int option, char * extra);
4934+Local int pr_pre_expansion (char * croot, ichar_t * rootword,
4935+ struct flagent * flent, MASKTYPE mask[], int option,
4936+ char * extra);
4937+Global int expand_suf (char * croot, ichar_t * rootword,
4938+ MASKTYPE mask[], int optflags, int option, char * extra);
4939+Local int pr_suf_expansion (char * croot, ichar_t * rootword,
4940+ struct flagent * flent, int option, char * extra);
4941+Local void forcelc (ichar_t * dst, int len);
4942+
4943+/* Check possible affixes */
4944+Public void
4945+chk_aff (
4946+ ichar_t * word, /* Word to be checked */
4947+ ichar_t * ucword, /* Upper-case-only copy of word */
4948+ int len, /* The length of word/ucword */
4949+ int ignoreflagbits, /* Ignore whether affix is legal */
4950+ int allhits, /* Keep going after first hit */
4951+ int pfxopts, /* Options to apply to prefixes */
4952+ int sfxopts) /* Options to apply to suffixes */
4953+ {
4954+ register ichar_t * cp; /* Pointer to char to index on */
4955+ struct flagptr * ind; /* Flag index table to test */
4956+
4957+ pfx_list_chk (word, ucword, len, pfxopts, sfxopts, &pflagindex[0],
4958+ ignoreflagbits, allhits);
4959+ cp = ucword;
4960+ ind = &pflagindex[*cp++];
4961+ while (ind->numents == 0 && ind->pu.fp != NULL)
4962+ {
4963+ if (*cp == 0)
4964+ return;
4965+ if (ind->pu.fp[0].numents)
4966+ {
4967+ pfx_list_chk (word, ucword, len, pfxopts, sfxopts, &ind->pu.fp[0],
4968+ ignoreflagbits, allhits);
4969+ if (numhits && !allhits && !cflag && !ignoreflagbits)
4970+ return;
4971+ }
4972+ ind = &ind->pu.fp[*cp++];
4973+ }
4974+ pfx_list_chk (word, ucword, len, pfxopts, sfxopts, ind, ignoreflagbits,
4975+ allhits);
4976+ if (numhits && !allhits && !cflag && !ignoreflagbits)
4977+ return;
4978+ chk_suf (word, ucword, len, sfxopts, (struct flagent *) NULL,
4979+ ignoreflagbits, allhits);
4980+ }
4981+
4982+/* Check some prefix flags */
4983+Local void
4984+pfx_list_chk(
4985+ ichar_t * word, /* Word to be checked */
4986+ ichar_t * ucword, /* Upper-case-only word */
4987+ int len, /* The length of ucword */
4988+ int optflags, /* Options to apply */
4989+ int sfxopts, /* Options to apply to suffixes */
4990+ struct flagptr * ind, /* Flag index table */
4991+ int ignoreflagbits, /* Ignore whether affix is legal */
4992+ int allhits) /* Keep going after first hit */
4993+ {
4994+ int cond; /* Condition number */
4995+ register ichar_t * cp; /* Pointer into end of ucword */
4996+ struct dent * dent; /* Dictionary entry we found */
4997+ int entcount; /* Number of entries to process */
4998+ register struct flagent *
4999+ flent; /* Current table entry */
5000+ int preadd; /* Length added to tword2 as prefix */
5001+ register int tlen; /* Length of tword */
5002+ ichar_t tword[INPUTWORDLEN + 4 * MAXAFFIXLEN + 4]; /* Tmp cpy */
5003+ ichar_t tword2[sizeof tword]; /* 2nd copy for ins_root_cap */
5004+
5005+ for (flent = ind->pu.ent, entcount = ind->numents;
5006+ entcount > 0; flent++, entcount--)
5007+ {
5008+ /*
5009+ * If this is a compound-only affix, ignore it unless we're
5010+ * looking for that specific thing.
5011+ */
5012+ if ((flent->flagflags & FF_COMPOUNDONLY) != 0
5013+ && (optflags & FF_COMPOUNDONLY) == 0)
5014+ continue;
5015+ /*
5016+ * In COMPOUND_CONTROLLED mode, the FF_COMPOUNDONLY bit must
5017+ * match exactly.
5018+ */
5019+ if (compoundflag == COMPOUND_CONTROLLED
5020+ && ((flent->flagflags ^ optflags) & FF_COMPOUNDONLY) != 0)
5021+ continue;
5022+ /*
5023+ * See if the prefix matches.
5024+ */
5025+ tlen = len - flent->affl;
5026+ if (tlen > 0 && (flent->affl == 0 ||
5027+ icharncmp (flent->affix, ucword, flent->affl) == 0) &&
5028+ tlen + flent->stripl >= flent->numconds)
5029+ {
5030+ /*
5031+ * The prefix matches. Remove it, replace it by the "strip"
5032+ * string (if any), and check the original conditions.
5033+ */
5034+ if (flent->stripl)
5035+ (void) icharcpy (tword, flent->strip);
5036+ (void) icharcpy (tword + flent->stripl, ucword + flent->affl);
5037+ cp = tword;
5038+ for (cond = 0; cond < flent->numconds; cond++)
5039+ {
5040+ if ((flent->conds[*cp++] & (1 << cond)) == 0)
5041+ break;
5042+ }
5043+ if (cond >= flent->numconds)
5044+ {
5045+ /*
5046+ * The conditions match. See if the word is in the
5047+ * dictionary.
5048+ */
5049+ tlen += flent->stripl;
5050+ if (cflag)
5051+ flagpr (tword, BITTOCHAR (flent->flagbit), flent->stripl,
5052+ flent->affl, -1, 0);
5053+ else if (ignoreflagbits)
5054+ {
5055+ if ((dent = lookup (tword, 1)) != NULL)
5056+ {
5057+ cp = tword2;
5058+ if (flent->affl)
5059+ {
5060+ (void) icharcpy (cp, flent->affix);
5061+ cp += flent->affl;
5062+ *cp++ = '+';
5063+ }
5064+ preadd = cp - tword2;
5065+ (void) icharcpy (cp, tword);
5066+ cp += tlen;
5067+ if (flent->stripl)
5068+ {
5069+ *cp++ = '-';
5070+ (void) icharcpy (cp, flent->strip);
5071+ }
5072+ (void) ins_root_cap (tword2, word,
5073+ flent->stripl, preadd,
5074+ 0, (cp - tword2) - tlen - preadd,
5075+ dent, flent, (struct flagent *) NULL);
5076+ }
5077+ }
5078+ else if ((dent = lookup (tword, 1)) != NULL
5079+ && TSTMASKBIT (dent->mask, flent->flagbit))
5080+ {
5081+ if (numhits < MAX_HITS)
5082+ {
5083+ hits[numhits].dictent = dent;
5084+ hits[numhits].prefix = flent;
5085+ hits[numhits].suffix = NULL;
5086+ numhits++;
5087+ }
5088+ if (!allhits)
5089+ {
5090+#ifndef NO_CAPITALIZATION_SUPPORT
5091+ if (cap_ok (word, &hits[0], len))
5092+ return;
5093+ numhits = 0;
5094+#else /* NO_CAPITALIZATION_SUPPORT */
5095+ return;
5096+#endif /* NO_CAPITALIZATION_SUPPORT */
5097+ }
5098+ }
5099+ /*
5100+ * Handle cross-products.
5101+ */
5102+ if (flent->flagflags & FF_CROSSPRODUCT)
5103+ chk_suf (word, tword, tlen, sfxopts | FF_CROSSPRODUCT,
5104+ flent, ignoreflagbits, allhits);
5105+ }
5106+ }
5107+ }
5108+ }
5109+
5110+/* Check possible suffixes */
5111+Local void
5112+chk_suf(
5113+ ichar_t * word, /* Word to be checked */
5114+ ichar_t * ucword, /* Upper-case-only word */
5115+ int len, /* The length of ucword */
5116+ int optflags, /* Affix option flags */
5117+ struct flagent * pfxent, /* Prefix flag entry if cross-prod */
5118+ int ignoreflagbits, /* Ignore whether affix is legal */
5119+ int allhits) /* Keep going after first hit */
5120+ {
5121+ register ichar_t * cp; /* Pointer to char to index on */
5122+ struct flagptr * ind; /* Flag index table to test */
5123+
5124+ suf_list_chk (word, ucword, len, &sflagindex[0], optflags, pfxent,
5125+ ignoreflagbits, allhits);
5126+ cp = ucword + len - 1;
5127+ ind = &sflagindex[*cp];
5128+ while (ind->numents == 0 && ind->pu.fp != NULL)
5129+ {
5130+ if (cp == ucword)
5131+ return;
5132+ if (ind->pu.fp[0].numents)
5133+ {
5134+ suf_list_chk (word, ucword, len, &ind->pu.fp[0],
5135+ optflags, pfxent, ignoreflagbits, allhits);
5136+ if (numhits != 0 && !allhits && !cflag && !ignoreflagbits)
5137+ return;
5138+ }
5139+ ind = &ind->pu.fp[*--cp];
5140+ }
5141+ suf_list_chk (word, ucword, len, ind, optflags, pfxent,
5142+ ignoreflagbits, allhits);
5143+ }
5144+
5145+Local void
5146+suf_list_chk (
5147+ ichar_t * word, /* Word to be checked */
5148+ ichar_t * ucword, /* Upper-case-only word */
5149+ int len, /* The length of ucword */
5150+ struct flagptr * ind, /* Flag index table */
5151+ int optflags, /* Affix option flags */
5152+ struct flagent * pfxent, /* Prefix flag entry if crossonly */
5153+ int ignoreflagbits, /* Ignore whether affix is legal */
5154+ int allhits) /* Keep going after first hit */
5155+{
5156+ register ichar_t * cp; /* Pointer into end of ucword */
5157+ int cond; /* Condition number */
5158+ struct dent * dent; /* Dictionary entry we found */
5159+ int entcount; /* Number of entries to process */
5160+ register struct flagent *
5161+ flent; /* Current table entry */
5162+ int preadd; /* Length added to tword2 as prefix */
5163+ register int tlen; /* Length of tword */
5164+ ichar_t tword[INPUTWORDLEN + 4 * MAXAFFIXLEN + 4]; /* Tmp cpy */
5165+ ichar_t tword2[sizeof tword]; /* 2nd copy for ins_root_cap */
5166+
5167+ (void) icharcpy (tword, ucword);
5168+ for (flent = ind->pu.ent, entcount = ind->numents;
5169+ entcount > 0;
5170+ flent++, entcount--)
5171+ {
5172+ if ((optflags & FF_CROSSPRODUCT) != 0
5173+ && (flent->flagflags & FF_CROSSPRODUCT) == 0)
5174+ continue;
5175+ /*
5176+ * If this is a compound-only affix, ignore it unless we're
5177+ * looking for that specific thing.
5178+ */
5179+ if ((flent->flagflags & FF_COMPOUNDONLY) != 0
5180+ && (optflags & FF_COMPOUNDONLY) == 0)
5181+ continue;
5182+ /*
5183+ * In COMPOUND_CONTROLLED mode, the FF_COMPOUNDONLY bit must
5184+ * match exactly.
5185+ */
5186+ if (compoundflag == COMPOUND_CONTROLLED
5187+ && ((flent->flagflags ^ optflags) & FF_COMPOUNDONLY) != 0)
5188+ continue;
5189+ /*
5190+ * See if the suffix matches.
5191+ */
5192+ tlen = len - flent->affl;
5193+ if (tlen > 0
5194+ && (flent->affl == 0
5195+ || icharcmp (flent->affix, ucword + tlen) == 0)
5196+ && tlen + flent->stripl >= flent->numconds)
5197+ {
5198+ /*
5199+ * The suffix matches. Remove it, replace it by the "strip"
5200+ * string (if any), and check the original conditions.
5201+ */
5202+ (void) icharcpy (tword, ucword);
5203+ cp = tword + tlen;
5204+ if (flent->stripl)
5205+ {
5206+ (void) icharcpy (cp, flent->strip);
5207+ tlen += flent->stripl;
5208+ cp = tword + tlen;
5209+ }
5210+ else
5211+ *cp = '\0';
5212+ for (cond = flent->numconds; --cond >= 0; )
5213+ {
5214+ if ((flent->conds[*--cp] & (1 << cond)) == 0)
5215+ break;
5216+ }
5217+ if (cond < 0)
5218+ {
5219+ /*
5220+ * The conditions match. See if the word is in the
5221+ * dictionary.
5222+ */
5223+ if (cflag)
5224+ {
5225+ if (optflags & FF_CROSSPRODUCT)
5226+ flagpr (tword, BITTOCHAR (pfxent->flagbit),
5227+ pfxent->stripl, pfxent->affl,
5228+ BITTOCHAR (flent->flagbit), flent->affl);
5229+ else
5230+ flagpr (tword, -1, 0, 0,
5231+ BITTOCHAR (flent->flagbit), flent->affl);
5232+ }
5233+ else if (ignoreflagbits)
5234+ {
5235+ if ((dent = lookup (tword, 1)) != NULL)
5236+ {
5237+ cp = tword2;
5238+ if ((optflags & FF_CROSSPRODUCT)
5239+ && pfxent->affl != 0)
5240+ {
5241+ (void) icharcpy (cp, pfxent->affix);
5242+ cp += pfxent->affl;
5243+ *cp++ = '+';
5244+ }
5245+ preadd = cp - tword2;
5246+ (void) icharcpy (cp, tword);
5247+ cp += tlen;
5248+ if ((optflags & FF_CROSSPRODUCT)
5249+ && pfxent->stripl != 0)
5250+ {
5251+ *cp++ = '-';
5252+ (void) icharcpy (cp, pfxent->strip);
5253+ cp += pfxent->stripl;
5254+ }
5255+ if (flent->stripl)
5256+ {
5257+ *cp++ = '-';
5258+ (void) icharcpy (cp, flent->strip);
5259+ cp += flent->stripl;
5260+ }
5261+ if (flent->affl)
5262+ {
5263+ *cp++ = '+';
5264+ (void) icharcpy (cp, flent->affix);
5265+ cp += flent->affl;
5266+ }
5267+ (void) ins_root_cap (tword2, word,
5268+ (optflags & FF_CROSSPRODUCT) ? pfxent->stripl : 0,
5269+ preadd,
5270+ flent->stripl, (cp - tword2) - tlen - preadd,
5271+ dent, pfxent, flent);
5272+ }
5273+ }
5274+ else if ((dent = lookup (tword, 1)) != NULL
5275+ && TSTMASKBIT (dent->mask, flent->flagbit)
5276+ && ((optflags & FF_CROSSPRODUCT) == 0
5277+ || TSTMASKBIT (dent->mask, pfxent->flagbit)))
5278+ {
5279+ if (numhits < MAX_HITS)
5280+ {
5281+ hits[numhits].dictent = dent;
5282+ hits[numhits].prefix = pfxent;
5283+ hits[numhits].suffix = flent;
5284+ numhits++;
5285+ }
5286+ if (!allhits)
5287+ {
5288+#ifndef NO_CAPITALIZATION_SUPPORT
5289+ if (cap_ok (word, &hits[0], len))
5290+ return;
5291+ numhits = 0;
5292+#else /* NO_CAPITALIZATION_SUPPORT */
5293+ return;
5294+#endif /* NO_CAPITALIZATION_SUPPORT */
5295+ }
5296+ }
5297+ }
5298+ }
5299+ }
5300+}
5301+
5302+/*
5303+ * Expand a dictionary prefix entry
5304+ */
5305+Public int
5306+expand_pre(
5307+ char * croot, /* Char version of rootword */
5308+ ichar_t * rootword, /* Root word to expand */
5309+ register MASKTYPE mask[], /* Mask bits to expand on */
5310+ int option, /* Option, see expandmode */
5311+ char * extra) /* Extra info to add to line */
5312+{
5313+ int entcount; /* No. of entries to process */
5314+ int explength; /* Length of expansions */
5315+ register struct flagent *
5316+ flent; /* Current table entry */
5317+
5318+ for (flent = pflaglist, entcount = numpflags, explength = 0;
5319+ entcount > 0; flent++, entcount--)
5320+ {
5321+ if (TSTMASKBIT (mask, flent->flagbit))
5322+ explength +=
5323+ pr_pre_expansion (croot, rootword, flent, mask, option, extra);
5324+ }
5325+ return explength;
5326+}
5327+
5328+/* Print a prefix expansion */
5329+Local int
5330+pr_pre_expansion(
5331+ char * croot, /* Char version of rootword */
5332+ register ichar_t * rootword, /* Root word to expand */
5333+ register struct flagent * flent, /* Current table entry */
5334+ MASKTYPE mask[], /* Mask bits to expand on */
5335+ int option, /* Option, see expandmode */
5336+ char * extra) /* Extra info to add to line */
5337+{
5338+ int cond; /* Current condition number */
5339+ register ichar_t * nextc; /* Next case choice */
5340+ int tlen; /* Length of tword */
5341+ ichar_t tword[INPUTWORDLEN + MAXAFFIXLEN]; /* Temp */
5342+
5343+ tlen = icharlen (rootword);
5344+ if (flent->numconds > tlen)
5345+ return 0;
5346+ tlen -= flent->stripl;
5347+ if (tlen <= 0)
5348+ return 0;
5349+ tlen += flent->affl;
5350+ for (cond = 0, nextc = rootword; cond < flent->numconds; cond++)
5351+ {
5352+ if ((flent->conds[mytoupper (*nextc++)] & (1 << cond)) == 0)
5353+ return 0;
5354+ }
5355+ /*
5356+ * The conditions are satisfied. Copy the word, add the prefix,
5357+ * and make it the proper case. This code is carefully written
5358+ * to match that ins_cap and cap_ok. Note that the affix, as
5359+ * inserted, is uppercase.
5360+ *
5361+ * There is a tricky bit here: if the root is capitalized, we
5362+ * want a capitalized result. If the root is followcase, however,
5363+ * we want to duplicate the case of the first remaining letter
5364+ * of the root. In other words, "Loved/U" should generate "Unloved",
5365+ * but "LOved/U" should generate "UNLOved" and "lOved/U" should
5366+ * produce "unlOved".
5367+ */
5368+ if (flent->affl)
5369+ {
5370+ (void) icharcpy (tword, flent->affix);
5371+ nextc = tword + flent->affl;
5372+ }
5373+ (void) icharcpy (nextc, rootword + flent->stripl);
5374+ if (myupper (rootword[0]))
5375+ {
5376+ /* We must distinguish followcase from capitalized and all-upper */
5377+ for (nextc = rootword + 1; *nextc; nextc++)
5378+ {
5379+ if (!myupper (*nextc))
5380+ break;
5381+ }
5382+ if (*nextc)
5383+ {
5384+ /* It's a followcase or capitalized word. Figure out which. */
5385+ for ( ; *nextc; nextc++)
5386+ {
5387+ if (myupper (*nextc))
5388+ break;
5389+ }
5390+ if (*nextc)
5391+ {
5392+ /* It's followcase. */
5393+ if (!myupper (tword[flent->affl]))
5394+ forcelc (tword, flent->affl);
5395+ }
5396+ else
5397+ {
5398+ /* It's capitalized */
5399+ forcelc (tword + 1, tlen - 1);
5400+ }
5401+ }
5402+ }
5403+ else
5404+ {
5405+ /* Followcase or all-lower, we don't care which */
5406+ if (!myupper (*nextc))
5407+ forcelc (tword, flent->affl);
5408+ }
5409+ if (option == 3)
5410+ (void) printf ("\n%s", croot);
5411+ if (option != 4)
5412+ (void) printf (" %s%s", ichartosstr (tword, 1), extra);
5413+ if (flent->flagflags & FF_CROSSPRODUCT)
5414+ return tlen
5415+ + expand_suf (croot, tword, mask, FF_CROSSPRODUCT, option, extra);
5416+ else
5417+ return tlen;
5418+}
5419+
5420+/*
5421+ * Expand a dictionary suffix entry
5422+ */
5423+int expand_suf (croot, rootword, mask, optflags, option, extra)
5424+ char * croot; /* Char version of rootword */
5425+ ichar_t * rootword; /* Root word to expand */
5426+ register MASKTYPE mask[]; /* Mask bits to expand on */
5427+ int optflags; /* Affix option flags */
5428+ int option; /* Option, see expandmode */
5429+ char * extra; /* Extra info to add to line */
5430+ {
5431+ int entcount; /* No. of entries to process */
5432+ int explength; /* Length of expansions */
5433+ register struct flagent *
5434+ flent; /* Current table entry */
5435+
5436+ for (flent = sflaglist, entcount = numsflags, explength = 0;
5437+ entcount > 0;
5438+ flent++, entcount--)
5439+ {
5440+ if (TSTMASKBIT (mask, flent->flagbit))
5441+ {
5442+ if ((optflags & FF_CROSSPRODUCT) == 0
5443+ || (flent->flagflags & FF_CROSSPRODUCT))
5444+ explength +=
5445+ pr_suf_expansion (croot, rootword, flent, option, extra);
5446+ }
5447+ }
5448+ return explength;
5449+ }
5450+
5451+/* Print a suffix expansion */
5452+static int pr_suf_expansion (croot, rootword, flent, option, extra)
5453+ char * croot; /* Char version of rootword */
5454+ register ichar_t * rootword; /* Root word to expand */
5455+ register struct flagent * flent; /* Current table entry */
5456+ int option; /* Option, see expandmode */
5457+ char * extra; /* Extra info to add to line */
5458+ {
5459+ int cond; /* Current condition number */
5460+ register ichar_t * nextc; /* Next case choice */
5461+ int tlen; /* Length of tword */
5462+ ichar_t tword[INPUTWORDLEN + MAXAFFIXLEN]; /* Temp */
5463+
5464+ tlen = icharlen (rootword);
5465+ cond = flent->numconds;
5466+ if (cond > tlen)
5467+ return 0;
5468+ if (tlen - flent->stripl <= 0)
5469+ return 0;
5470+ for (nextc = rootword + tlen; --cond >= 0; )
5471+ {
5472+ if ((flent->conds[mytoupper (*--nextc)] & (1 << cond)) == 0)
5473+ return 0;
5474+ }
5475+ /*
5476+ * The conditions are satisfied. Copy the word, add the suffix,
5477+ * and make it match the case of the last remaining character of the
5478+ * root. Again, this code carefully matches ins_cap and cap_ok.
5479+ */
5480+ (void) icharcpy (tword, rootword);
5481+ nextc = tword + tlen - flent->stripl;
5482+ if (flent->affl)
5483+ {
5484+ (void) icharcpy (nextc, flent->affix);
5485+ if (!myupper (nextc[-1]))
5486+ forcelc (nextc, flent->affl);
5487+ }
5488+ else
5489+ *nextc = 0;
5490+ if (option == 3)
5491+ (void) printf ("\n%s", croot);
5492+ if (option != 4)
5493+ (void) printf (" %s%s", ichartosstr (tword, 1), extra);
5494+ return tlen + flent->affl - flent->stripl;
5495+ }
5496+
5497+static void forcelc (dst, len) /* Force to lowercase */
5498+ register ichar_t * dst; /* Destination to modify */
5499+ register int len; /* Length to copy */
5500+ {
5501+
5502+ for ( ; --len >= 0; dst++)
5503+ *dst = mytolower (*dst);
5504+ }
41e3656f 5505diff -ruN vim62./src/spell/tree.c vim62/src/spell/tree.c
5506--- vim62./src/spell/tree.c 1970-01-01 01:00:00.000000000 +0100
5507+++ vim62/src/spell/tree.c 2003-06-02 19:57:21.000000000 +0200
24ec98f0
JB
5508@@ -0,0 +1,748 @@
5509+/*
5510+ * tree.c - a hash style dictionary for user's personal words
5511+ *
5512+ * Pace Willisson, 1983
5513+ * Hash support added by Geoff Kuenning, 1987
5514+ *
5515+ * Copyright 1987, 1988, 1989, 1992, 1993, Geoff Kuenning, Granada Hills, CA
5516+ * All rights reserved.
5517+ *
5518+ * Redistribution and use in source and binary forms, with or without
5519+ * modification, are permitted provided that the following conditions
5520+ * are met:
5521+ *
5522+ * 1. Redistributions of source code must retain the above copyright
5523+ * notice, this list of conditions and the following disclaimer.
5524+ * 2. Redistributions in binary form must reproduce the above copyright
5525+ * notice, this list of conditions and the following disclaimer in the
5526+ * documentation and/or other materials provided with the distribution.
5527+ * 3. All modifications to the source code must be clearly marked as
5528+ * such. Binary redistributions based on modified source code
5529+ * must be clearly marked as modified versions in the documentation
5530+ * and/or other materials provided with the distribution.
5531+ * 4. All advertising materials mentioning features or use of this software
5532+ * must display the following acknowledgment:
5533+ * This product includes software developed by Geoff Kuenning and
5534+ * other unpaid contributors.
5535+ * 5. The name of Geoff Kuenning may not be used to endorse or promote
5536+ * products derived from this software without specific prior
5537+ * written permission.
5538+ *
5539+ * THIS SOFTWARE IS PROVIDED BY GEOFF KUENNING AND CONTRIBUTORS ``AS IS'' AND
5540+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
5541+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
5542+ * ARE DISCLAIMED. IN NO EVENT SHALL GEOFF KUENNING OR CONTRIBUTORS BE LIABLE
5543+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
5544+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
5545+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
5546+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
5547+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
5548+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
5549+ * SUCH DAMAGE.
5550+ */
5551+
5552+/*
5553+ * $Log$
5554+ * Revision 1.56 1995/01/08 23:23:49 geoff
5555+ * Support PDICTHOME for DOS purposes.
5556+ *
5557+ * Revision 1.55 1994/10/25 05:46:27 geoff
5558+ * Fix a comment that looked to some compilers like it might be nested.
5559+ *
5560+ * Revision 1.54 1994/01/25 07:12:15 geoff
5561+ * Get rid of all old RCS log lines in preparation for the 3.1 release.
5562+ *
5563+ */
5564+
5565+#include <ctype.h>
5566+#include <stdlib.h>
5567+#include <errno.h>
5568+#include "ispell.h"
5569+#include "msgs.h"
5570+
5571+Local FILE * trydict (char * dictname, char * home,
5572+ char * prefix, char * suffix);
5573+Local void treeload (FILE * dictf);
5574+Local struct dent * tinsert (struct dent * proto);
5575+#if SORTPERSONAL != 0
5576+Local int pdictcmp (struct dent ** enta, struct dent **entb);
5577+#endif /* SORTPERSONAL != 0 */
5578+#ifdef REGEX_LOOKUP
5579+#endif /* REGEX_LOOKUP */
5580+
5581+Local int cantexpand = 0; /* NZ if an expansion fails */
5582+Local struct dent * pershtab; /* Aux hash table for personal dict */
5583+Local int pershsize = 0; /* Space available in aux hash table */
5584+Local int hcount = 0; /* Number of items in hash table */
5585+
5586+/*
5587+ * Hash table sizes. Prime is probably a good idea, though in truth I
5588+ * whipped the algorithm up on the spot rather than looking it up, so
5589+ * who knows what's really best? If we overflow the table, we just
5590+ * use a double-and-add-1 algorithm.
5591+ */
5592+static int goodsizes[] =
5593+ {
5594+ 53, 223, 907, 3631
5595+ };
5596+
5597+Local char personaldict[MAXPATHLEN];
5598+Local FILE * dictf;
5599+Local newwords = 0;
5600+
5601+Public void
5602+treeinit (
5603+ char * p, /* Value specified in -p switch */
5604+ char * LibDict) /* Root of default dict name */
5605+{
5606+ int abspath; /* NZ if p is abs path name */
5607+ char * h; /* Home directory name */
5608+ char seconddict[MAXPATHLEN]; /* Name of secondary dict */
5609+ FILE * secondf; /* Access to second dict file */
5610+
5611+ /*
5612+ ** If -p was not specified, try to get a default name from the
5613+ ** environment. After this point, if p is null, the the value in
5614+ ** personaldict is the only possible name for the personal dictionary.
5615+ ** If p is non-null, then there is a possibility that we should
5616+ ** prepend HOME to get the correct dictionary name.
5617+ */
5618+ if (p == NULL)
5619+ p = getenv (PDICTVAR);
5620+ /*
5621+ ** if p exists and begins with '/' we don't really need HOME,
5622+ ** but it's not very likely that HOME isn't set anyway (on non-DOS
5623+ ** systems).
5624+ */
5625+ {
5626+ int i;
5627+ struct dent *x;
5628+
5629+ for(i = 0; i < pershsize; i++)
5630+ {
5631+ x = &pershtab[i];
5632+ if(x->word != NULL)
5633+ free(x->word);
5634+ for(x = x->next; x != NULL;)
5635+ {
5636+ struct dent *y;
5637+
5638+ if(x->word != NULL)
5639+ free(x->word);
5640+ y = x;
5641+ x = x->next;
5642+ free(y);
5643+ }
5644+ }
5645+ if(pershtab != NULL)
5646+ free(pershtab);
5647+ pershtab = NULL;
5648+ pershsize = 0;
5649+ hcount = 0;
5650+ }
5651+ if ((h = getenv (HOME)) == NULL)
5652+ {
5653+#ifdef PDICTHOME
5654+ h = PDICTHOME;
5655+#else /* PDICTHOME */
5656+ return;
5657+#endif /* PDICTHOME */
5658+ }
5659+
5660+ if (p == NULL)
5661+ {
5662+ /*
5663+ * No -p and no PDICTVAR. We will use LibDict and DEFPAFF to
5664+ * figure out the name of the personal dictionary and where it
5665+ * is. The rules are as follows:
5666+ *
5667+ * (1) If there is a local dictionary and a HOME dictionary,
5668+ * both are loaded, but changes are saved in the local one.
5669+ * The dictionary to save changes in is named "personaldict".
5670+ * (2) Dictionaries named after the affix file take precedence
5671+ * over dictionaries with the default suffix (DEFPAFF).
5672+ * (3) Dictionaries named with the new default names
5673+ * (DEFPDICT/DEFPAFF) take precedence over the old ones
5674+ * (OLDPDICT/OLDPAFF).
5675+ * (4) Dictionaries aren't combined unless they follow the same
5676+ * naming scheme.
5677+ * (5) If no dictionary can be found, a new one is created in
5678+ * the home directory, named after DEFPDICT and the affix
5679+ * file.
5680+ */
5681+ dictf = trydict (personaldict, (char *) NULL, DEFPDICT, LibDict);
5682+ secondf = trydict (seconddict, h, DEFPDICT, LibDict);
5683+ if (dictf == NULL && secondf == NULL)
5684+ {
5685+ dictf = trydict (personaldict, (char *) NULL, DEFPDICT, DEFPAFF);
5686+ secondf = trydict (seconddict, h, DEFPDICT, DEFPAFF);
5687+ }
5688+ if (dictf == NULL && secondf == NULL)
5689+ {
5690+ dictf = trydict (personaldict, (char *) NULL, OLDPDICT, LibDict);
5691+ secondf = trydict (seconddict, h, OLDPDICT, LibDict);
5692+ }
5693+ if (dictf == NULL && secondf == NULL)
5694+ {
5695+ dictf = trydict (personaldict, (char *) NULL, OLDPDICT, OLDPAFF);
5696+ secondf = trydict (seconddict, h, OLDPDICT, OLDPAFF);
5697+ }
5698+ if (personaldict[0] == '\0')
5699+ {
5700+ if (seconddict[0] != '\0')
5701+ (void) strcpy (personaldict, seconddict);
5702+ else
5703+ (void) sprintf (personaldict, "%s/%s%s", h, DEFPDICT, LibDict);
5704+ }
5705+ if (dictf != NULL)
5706+ {
5707+ treeload (dictf);
5708+ (void) fclose (dictf);
5709+ }
5710+ if (secondf != NULL)
5711+ {
5712+ treeload (secondf);
5713+ (void) fclose (secondf);
5714+ }
5715+ }
5716+ else
5717+ {
5718+ /*
5719+ ** Figure out if p is an absolute path name. Note that beginning
5720+ ** with "./" and "../" is considered an absolute path, since this
5721+ ** still means we can't prepend HOME.
5722+ */
5723+ abspath = (*p == '/' || strncmp (p, "./", 2) == 0
5724+ || strncmp (p, "../", 3) == 0);
5725+#ifdef MSDOS
5726+ if (!abspath)
5727+ abspath = (*p == '\\' || strncmp (p, ".\\", 2) == 0
5728+ || strncmp (p, "..\\", 3) == 0
5729+ || (p[0] && p[1] == ':'));
5730+#endif
5731+ if (abspath)
5732+ {
5733+ (void) strcpy (personaldict, p);
5734+ if ((dictf = fopen (personaldict, "r")) != NULL)
5735+ {
5736+ treeload (dictf);
5737+ (void) fclose (dictf);
5738+ }
5739+ }
5740+ else
5741+ {
5742+ /*
5743+ ** The user gave us a relative pathname. We will try it
5744+ ** locally, and if that doesn't work, we'll try the home
5745+ ** directory. If neither exists, it will be created in
5746+ ** the home directory if words are added.
5747+ */
5748+ (void) strcpy (personaldict, p);
5749+ if ((dictf = fopen (personaldict, "r")) != NULL)
5750+ {
5751+ treeload (dictf);
5752+ (void) fclose (dictf);
5753+ }
5754+ else if (!abspath)
5755+ {
5756+ /* Try the home */
5757+ (void) sprintf (personaldict, "%s/%s", h, p);
5758+ if ((dictf = fopen (personaldict, "r")) != NULL)
5759+ {
5760+ treeload (dictf);
5761+ (void) fclose (dictf);
5762+ }
5763+ }
5764+ /*
5765+ * If dictf is null, we couldn't open the dictionary
5766+ * specified in the -p switch. Complain.
5767+ */
5768+ if (dictf == NULL)
5769+ {
5770+ (void) fprintf (stderr, CANT_OPEN, p);
5771+ perror ("");
5772+ return;
5773+ }
5774+ }
5775+ }
5776+
5777+#ifndef FEAT_SPELL_HL
5778+ if (!lflag && !aflag
5779+ && access (personaldict, 2) < 0 && errno != ENOENT)
5780+ {
5781+ (void) fprintf (stderr, TREE_C_CANT_UPDATE, personaldict);
5782+ (void) sleep ((unsigned) 2);
5783+ }
5784+#endif
5785+}
5786+
5787+/*
5788+ * Try to open a dictionary. As a side effect, leaves the dictionary
5789+ * name in "filename" if one is found, and leaves a null string there
5790+ * otherwise.
5791+ */
5792+Local FILE *
5793+trydict (
5794+ char * filename, /* Where to store the file name */
5795+ char * home, /* Home directory */
5796+ char * prefix, /* Prefix for dictionary */
5797+ char * suffix) /* Suffix for dictionary */
5798+{
5799+ FILE * dictf; /* Access to dictionary file */
5800+
5801+ if (home == NULL)
5802+ (void) sprintf (filename, "%s%s", prefix, suffix);
5803+ else
5804+ (void) sprintf (filename, "%s/%s%s", home, prefix, suffix);
5805+ dictf = fopen (filename, "r");
5806+ if (dictf == NULL)
5807+ filename[0] = '\0';
5808+ return dictf;
5809+}
5810+
5811+Local void
5812+treeload (
5813+ register FILE * loadfile) /* File to load words from */
5814+{
5815+ char buf[BUFSIZ]; /* Buffer for reading pers dict */
5816+
5817+ while (fgets (buf, sizeof buf, loadfile) != NULL)
5818+ treeinsert (buf, sizeof(buf), 1);
5819+ newwords = 0;
5820+}
5821+
5822+Public void
5823+treeinsert (
5824+ char * word, /* Word to insert - must be canonical */
5825+ int wordlen, /* Length of the word buffer */
5826+ int keep)
5827+{
5828+ register int i, len;
5829+ struct dent wordent;
5830+ register struct dent * dp;
5831+ struct dent * olddp;
5832+#ifndef NO_CAPITALIZATION_SUPPORT
5833+ struct dent * newdp;
5834+#endif
5835+ struct dent * oldhtab;
5836+ int oldhsize;
5837+ ichar_t nword[INPUTWORDLEN + MAXAFFIXLEN];
5838+#ifndef NO_CAPITALIZATION_SUPPORT
5839+ int isvariant;
5840+#endif
5841+
5842+ len = strlen(word);
5843+ if((word[len - 1] == '\n') || (word[len - 1] == '\r'))
5844+ word[len - 1] = '\0', len--;
5845+ if((word[len - 1] == '\n') || (word[len - 1] == '\r'))
5846+ word[len - 1] = '\0';
5847+ /*
5848+ * Expand hash table when it is MAXPCT % full.
5849+ */
5850+ if (!cantexpand && (hcount * 100) / MAXPCT >= pershsize)
5851+ {
5852+ oldhsize = pershsize;
5853+ oldhtab = pershtab;
5854+ for (i = 0; i < sizeof goodsizes / sizeof (goodsizes[0]); i++)
5855+ if (goodsizes[i] > pershsize)
5856+ break;
5857+ if (i >= sizeof goodsizes / sizeof goodsizes[0])
5858+ pershsize += pershsize + 1;
5859+ else
5860+ pershsize = goodsizes[i];
5861+ pershtab =
5862+ (struct dent *) calloc ((unsigned) pershsize, sizeof (struct dent));
5863+ if (pershtab == NULL)
5864+ {
5865+ (void) fprintf (stderr, TREE_C_NO_SPACE);
5866+ /*
5867+ * Try to continue anyway, since our overflow
5868+ * algorithm can handle an overfull (100%+) table,
5869+ * and the malloc very likely failed because we
5870+ * already have such a huge table, so small mallocs
5871+ * for overflow entries will still work.
5872+ */
5873+ if (oldhtab == NULL)
5874+ exit (1); /* No old table, can't go on */
5875+ (void) fprintf (stderr, TREE_C_TRY_ANYWAY);
5876+ cantexpand = 1; /* Suppress further messages */
5877+ pershsize = oldhsize; /* Put things back */
5878+ pershtab = oldhtab; /* ... */
5879+ newwords = 1; /* And pretend it worked */
5880+ }
5881+ else
5882+ {
5883+ /*
5884+ * Re-insert old entries into new table
5885+ */
5886+ for (i = 0; i < oldhsize; i++)
5887+ {
5888+ dp = &oldhtab[i];
5889+ if (dp->flagfield & USED)
5890+ {
5891+#ifdef NO_CAPITALIZATION_SUPPORT
5892+ (void) tinsert (dp);
5893+#else
5894+ newdp = tinsert (dp);
5895+ isvariant = (dp->flagfield & MOREVARIANTS);
5896+#endif
5897+ dp = dp->next;
5898+#ifdef NO_CAPITALIZATION_SUPPORT
5899+ while (dp != NULL)
5900+ {
5901+ (void) tinsert (dp);
5902+ olddp = dp;
5903+ dp = dp->next;
5904+ free ((char *) olddp);
5905+ }
5906+#else
5907+ while (dp != NULL)
5908+ {
5909+ if (isvariant)
5910+ {
5911+ isvariant = dp->flagfield & MOREVARIANTS;
5912+ olddp = newdp->next;
5913+ newdp->next = dp;
5914+ newdp = dp;
5915+ dp = dp->next;
5916+ newdp->next = olddp;
5917+ }
5918+ else
5919+ {
5920+ isvariant = dp->flagfield & MOREVARIANTS;
5921+ newdp = tinsert (dp);
5922+ olddp = dp;
5923+ dp = dp->next;
5924+ free ((char *) olddp);
5925+ }
5926+ }
5927+#endif
5928+ }
5929+ }
5930+ if (oldhtab != NULL)
5931+ free ((char *) oldhtab);
5932+ }
5933+ }
5934+
5935+ /*
5936+ ** We're ready to do the insertion. Start by creating a sample
5937+ ** entry for the word.
5938+ */
5939+ if (makedent (word, wordlen, &wordent) < 0)
5940+ return; /* Word must be too big or something */
5941+ if (keep)
5942+ wordent.flagfield |= KEEP;
5943+ /*
5944+ ** Now see if word or a variant is already in the table. We use the
5945+ ** capitalized version so we'll find the header, if any.
5946+ **/
5947+ (void) strtoichar (nword, word, sizeof nword, 1);
5948+ upcase (nword);
5949+ if ((dp = lookup (nword, 1)) != NULL)
5950+ {
5951+ /* It exists. Combine caps and set the keep flag. */
5952+ if (combinecaps (dp, &wordent) < 0)
5953+ {
5954+ free (wordent.word);
5955+ return;
5956+ }
5957+ }
5958+ else
5959+ {
5960+ /* It's new. Insert the word. */
5961+ dp = tinsert (&wordent);
5962+#ifndef NO_CAPITALIZATION_SUPPORT
5963+ if (captype (dp->flagfield) == FOLLOWCASE)
5964+ (void) addvheader (dp);
5965+#endif
5966+ }
5967+ newwords |= keep;
5968+ hcount++;
5969+}
5970+
5971+Local struct dent *
5972+tinsert (
5973+ struct dent * proto) /* Prototype entry to copy */
5974+{
5975+ ichar_t iword[INPUTWORDLEN + MAXAFFIXLEN];
5976+ register int hcode;
5977+ register struct dent * hp; /* Next trial entry in hash table */
5978+ register struct dent * php; /* Prev. value of hp, for chaining */
5979+
5980+ if (strtoichar (iword, proto->word, sizeof iword, 1))
5981+ (void) fprintf (stderr, WORD_TOO_LONG (proto->word));
5982+#ifdef NO_CAPITALIZATION_SUPPORT
5983+ upcase (iword);
5984+#endif
5985+ hcode = hash (iword, pershsize);
5986+ php = NULL;
5987+ hp = &pershtab[hcode];
5988+ if (hp->flagfield & USED)
5989+ {
5990+ while (hp != NULL)
5991+ {
5992+ php = hp;
5993+ hp = hp->next;
5994+ }
5995+ hp = (struct dent *) calloc (1, sizeof (struct dent));
5996+ if (hp == NULL)
5997+ {
5998+ (void) fprintf (stderr, TREE_C_NO_SPACE);
5999+ exit (1);
6000+ }
6001+ }
6002+ *hp = *proto;
6003+ if (php != NULL)
6004+ php->next = hp;
6005+ hp->next = NULL;
6006+ return hp;
6007+}
6008+
6009+Public struct dent *
6010+treelookup (register ichar_t * word)
6011+
6012+{
6013+ register int hcode;
6014+ register struct dent * hp;
6015+ char chword[INPUTWORDLEN + MAXAFFIXLEN];
6016+
6017+ if (pershsize <= 0)
6018+ return NULL;
6019+ (void) ichartostr (chword, word, sizeof chword, 1);
6020+ hcode = hash (word, pershsize);
6021+ hp = &pershtab[hcode];
6022+ while (hp != NULL && (hp->flagfield & USED))
6023+ {
6024+ if (strcmp (chword, hp->word) == 0)
6025+ break;
6026+#ifndef NO_CAPITALIZATION_SUPPORT
6027+ while (hp->flagfield & MOREVARIANTS)
6028+ hp = hp->next;
6029+#endif
6030+ hp = hp->next;
6031+ }
6032+ if (hp != NULL && (hp->flagfield & USED))
6033+ return hp;
6034+ else
6035+ return NULL;
6036+}
6037+
6038+#if SORTPERSONAL != 0
6039+/* Comparison routine for sorting the personal dictionary with qsort */
6040+Local int
6041+pdictcmp (
6042+ struct dent ** enta,
6043+ struct dent ** entb)
6044+{
6045+
6046+ /* The parentheses around *enta and *entb below are NECESSARY!
6047+ ** Otherwise the compiler reads it as *(enta->word), or
6048+ ** enta->word[0], which is illegal (but pcc takes it and
6049+ ** produces wrong code).
6050+ **/
6051+ return casecmp ((*enta)->word, (*entb)->word, 1);
6052+}
6053+#endif
6054+
6055+Public void
6056+treeoutput ()
6057+
6058+{
6059+ register struct dent * cent; /* Current entry */
6060+ register struct dent * lent; /* Linked entry */
6061+#if SORTPERSONAL != 0
6062+ int pdictsize; /* Number of entries to write */
6063+ struct dent ** sortlist; /* List of entries to be sorted */
6064+ register struct dent ** sortptr; /* Handy pointer into sortlist */
6065+#endif
6066+ register struct dent * ehtab; /* End of pershtab, for fast looping */
6067+
6068+ if (newwords == 0)
6069+ return;
6070+
6071+ if ((dictf = fopen (personaldict, "w")) == NULL)
6072+ {
6073+ (void) fprintf (stderr, CANT_CREATE, personaldict);
6074+ return;
6075+ }
6076+
6077+#if SORTPERSONAL != 0
6078+ /*
6079+ ** If we are going to sort the personal dictionary, we must know
6080+ ** how many items are going to be sorted.
6081+ */
6082+ pdictsize = 0;
6083+ if (hcount >= SORTPERSONAL)
6084+ sortlist = NULL;
6085+ else
6086+ {
6087+ for (cent = pershtab, ehtab = pershtab + pershsize; cent < ehtab;
6088+ cent++)
6089+ {
6090+ for (lent = cent; lent != NULL; lent = lent->next)
6091+ {
6092+ if ((lent->flagfield & (USED | KEEP)) == (USED | KEEP))
6093+ pdictsize++;
6094+#ifndef NO_CAPITALIZATION_SUPPORT
6095+ while (lent->flagfield & MOREVARIANTS)
6096+ lent = lent->next;
6097+#endif
6098+ }
6099+ }
6100+ for (cent = hashtbl, ehtab = hashtbl + hashsize; cent < ehtab; cent++)
6101+ {
6102+ if ((cent->flagfield & (USED | KEEP)) == (USED | KEEP))
6103+ {
6104+ /*
6105+ ** We only want to count variant headers
6106+ ** and standalone entries. These happen
6107+ ** to share the characteristics in the
6108+ ** test below. This test will appear
6109+ ** several more times in this routine.
6110+ */
6111+#ifndef NO_CAPITALIZATION_SUPPORT
6112+ if (captype (cent->flagfield) != FOLLOWCASE
6113+ && cent->word != NULL)
6114+#endif
6115+ pdictsize++;
6116+ }
6117+ }
6118+ sortlist = (struct dent **) malloc (pdictsize * sizeof (struct dent));
6119+ }
6120+ if (sortlist == NULL)
6121+ {
6122+#endif
6123+ for (cent = pershtab, ehtab = pershtab + pershsize; cent < ehtab;
6124+ cent++)
6125+ {
6126+ for (lent = cent; lent != NULL; lent = lent->next)
6127+ {
6128+ if ((lent->flagfield & (USED | KEEP)) == (USED | KEEP))
6129+ {
6130+ toutent (dictf, lent, 1);
6131+#ifndef NO_CAPITALIZATION_SUPPORT
6132+ while (lent->flagfield & MOREVARIANTS)
6133+ lent = lent->next;
6134+#endif
6135+ }
6136+ }
6137+ }
6138+ for (cent = hashtbl, ehtab = hashtbl + hashsize; cent < ehtab; cent++)
6139+ {
6140+ if ((cent->flagfield & (USED | KEEP)) == (USED | KEEP))
6141+ {
6142+#ifndef NO_CAPITALIZATION_SUPPORT
6143+ if (captype (cent->flagfield) != FOLLOWCASE
6144+ && cent->word != NULL)
6145+#endif
6146+ toutent (dictf, cent, 1);
6147+ }
6148+ }
6149+#if SORTPERSONAL != 0
6150+ return;
6151+ }
6152+ /*
6153+ ** Produce dictionary in sorted order. We used to do this
6154+ ** destructively, but that turns out to fail because in some modes
6155+ ** the dictionary is written more than once. So we build an
6156+ ** auxiliary pointer table (in sortlist) and sort that. This
6157+ ** is faster anyway, though it uses more memory.
6158+ */
6159+ sortptr = sortlist;
6160+ for (cent = pershtab, ehtab = pershtab + pershsize; cent < ehtab; cent++)
6161+ {
6162+ for (lent = cent; lent != NULL; lent = lent->next)
6163+ {
6164+ if ((lent->flagfield & (USED | KEEP)) == (USED | KEEP))
6165+ {
6166+ *sortptr++ = lent;
6167+#ifndef NO_CAPITALIZATION_SUPPORT
6168+ while (lent->flagfield & MOREVARIANTS)
6169+ lent = lent->next;
6170+#endif
6171+ }
6172+ }
6173+ }
6174+ for (cent = hashtbl, ehtab = hashtbl + hashsize; cent < ehtab; cent++)
6175+ {
6176+ if ((cent->flagfield & (USED | KEEP)) == (USED | KEEP))
6177+ {
6178+#ifndef NO_CAPITALIZATION_SUPPORT
6179+ if (captype (cent->flagfield) != FOLLOWCASE
6180+ && cent->word != NULL)
6181+#endif
6182+ *sortptr++ = cent;
6183+ }
6184+ }
6185+ /* Sort the list */
6186+ qsort ((char *) sortlist, (unsigned) pdictsize,
6187+ sizeof (sortlist[0]),
6188+ (int (*) (const void *, const void *)) pdictcmp);
6189+ /* Write it out */
6190+ for (sortptr = sortlist; --pdictsize >= 0; )
6191+ toutent (dictf, *sortptr++, 1);
6192+ free ((char *) sortlist);
6193+#endif
6194+
6195+ newwords = 0;
6196+
6197+ (void) fclose (dictf);
6198+}
6199+
6200+#ifdef REGEX_LOOKUP
6201+
6202+/* check the hashed dictionary for words matching the regex. return the */
6203+/* a matching string if found else return NULL */
6204+char *
6205+do_regex_lookup (
6206+ char * expr, /* regular expression to use in the match */
6207+ int whence) /* 0 = start at the beg with new regx, else */
6208+ /* continue from cur point w/ old regex */
6209+{
6210+ static struct dent * curent;
6211+ static int curindex;
6212+ static struct dent * curpersent;
6213+ static int curpersindex;
6214+ static REGCTYPE cmp_expr = (REGCTYPE)0;
6215+ char dummy[INPUTWORDLEN + MAXAFFIXLEN];
6216+ ichar_t * is;
6217+
6218+ if (whence == 0)
6219+ {
6220+ is = strtosichar (expr, 0);
6221+ upcase (is);
6222+ expr = ichartosstr (is, 1);
6223+ REGFREE (cmp_expr); /* free previous compiled pattern, if any */
6224+ cmp_expr = REGCMP (cmp_expr, expr);
6225+ curent = hashtbl;
6226+ curindex = 0;
6227+ curpersent = pershtab;
6228+ curpersindex = 0;
6229+ }
6230+
6231+ /* search the dictionary until the word is found or the words run out */
6232+ for ( ; curindex < hashsize; curent++, curindex++)
6233+ {
6234+ if (curent->word != NULL
6235+ && REGEX (cmp_expr, curent->word, dummy) != NULL)
6236+ {
6237+ curindex++;
6238+ /* Everybody's gotta write a wierd expression once in a while! */
6239+ return curent++->word;
6240+ }
6241+ }
6242+ /* Try the personal dictionary too */
6243+ for ( ; curpersindex < pershsize; curpersent++, curpersindex++)
6244+ {
6245+ if ((curpersent->flagfield & USED) != 0
6246+ && curpersent->word != NULL
6247+ && REGEX (cmp_expr, curpersent->word, dummy) != NULL)
6248+ {
6249+ curpersindex++;
6250+ /* Everybody's gotta write a wierd expression once in a while! */
6251+ return curpersent++->word;
6252+ }
6253+ }
6254+ return NULL;
6255+}
6256+#endif /* REGEX_LOOKUP */
41e3656f 6257diff -ruN vim62./src/spell/util.c vim62/src/spell/util.c
6258--- vim62./src/spell/util.c 1970-01-01 01:00:00.000000000 +0100
6259+++ vim62/src/spell/util.c 2003-06-02 19:57:21.000000000 +0200
24ec98f0
JB
6260@@ -0,0 +1,351 @@
6261+#include <ctype.h>
6262+#include "ispell.h"
6263+
6264+Local char *myrindex(char *s, char c);
6265+
6266+Public int
6267+casecmp (
6268+ char * a,
6269+ char * b,
6270+ int canonical) /* NZ for canonical string chars */
6271+{
6272+ register ichar_t * ap;
6273+ register ichar_t * bp;
6274+ ichar_t inta[INPUTWORDLEN + 4 * MAXAFFIXLEN + 4];
6275+ ichar_t intb[INPUTWORDLEN + 4 * MAXAFFIXLEN + 4];
6276+
6277+ (void) strtoichar (inta, a, sizeof inta, canonical);
6278+ (void) strtoichar (intb, b, sizeof intb, canonical);
6279+ for (ap = inta, bp = intb; *ap != 0; ap++, bp++)
6280+ {
6281+ if (*ap != *bp)
6282+ {
6283+ if (*bp == '\0')
6284+ return hashheader.sortorder[*ap];
6285+ else if (mylower (*ap))
6286+ {
6287+ if (mylower (*bp) || mytoupper (*ap) != *bp)
6288+ return (int) hashheader.sortorder[*ap] -
6289+ (int) hashheader.sortorder[*bp];
6290+ }
6291+ else
6292+ {
6293+ if (myupper (*bp) || mytolower (*ap) != *bp)
6294+ return (int) hashheader.sortorder[*ap] -
6295+ (int) hashheader.sortorder[*bp];
6296+ }
6297+ }
6298+ }
6299+ if (*bp != '\0')
6300+ return -(int) hashheader.sortorder[*bp];
6301+ for (ap = inta, bp = intb; *ap; ap++, bp++)
6302+ {
6303+ if (*ap != *bp)
6304+ {
6305+ return (int) hashheader.sortorder[*ap] -
6306+ (int) hashheader.sortorder[*bp];
6307+ }
6308+ }
6309+ return 0;
6310+}
6311+
6312+Public int
6313+ins_root_cap (
6314+ register ichar_t * word,
6315+ register ichar_t * pattern,
6316+ int prestrip,
6317+ int preadd,
6318+ int sufstrip,
6319+ int sufadd,
6320+ struct dent * firstdent,
6321+ struct flagent * pfxent,
6322+ struct flagent * sufent)
6323+{
6324+ int i; /* Index into savearea */
6325+ ichar_t savearea[MAX_CAPS][INPUTWORDLEN + MAXAFFIXLEN];
6326+ int nsaved; /* Number of words saved */
6327+
6328+ nsaved = 0;
6329+ save_root_cap (word, pattern, prestrip, preadd, sufstrip, sufadd,
6330+ firstdent, pfxent, sufent, savearea, &nsaved);
6331+ for (i = 0; i < nsaved; i++)
6332+ {
6333+ if (insert (savearea[i]) < 0)
6334+ return -1;
6335+ }
6336+ return 0;
6337+}
6338+
6339+Public void
6340+save_root_cap(
6341+ register ichar_t * word, /* Word to be saved */
6342+ register ichar_t * pattern, /* Capitalization pattern */
6343+ int prestrip, /* No. chars stripped from front */
6344+ int preadd, /* No. chars added to front of root */
6345+ int sufstrip, /* No. chars stripped from back */
6346+ int sufadd, /* No. chars added to back of root */
6347+ struct dent * firstdent, /* First dent for root */
6348+ struct flagent * pfxent, /* Pfx-flag entry for word */
6349+ struct flagent * sufent, /* Sfx-flag entry for word */
6350+ ichar_t savearea[MAX_CAPS][INPUTWORDLEN + MAXAFFIXLEN],
6351+ /* Room to save words */
6352+ int * nsaved) /* Number saved so far (updated) */
6353+{
6354+#ifndef NO_CAPITALIZATION_SUPPORT
6355+ register struct dent * dent;
6356+#endif /* NO_CAPITALIZATION_SUPPORT */
6357+ int firstisupper;
6358+ ichar_t newword[INPUTWORDLEN + 4 * MAXAFFIXLEN + 4];
6359+#ifndef NO_CAPITALIZATION_SUPPORT
6360+ register ichar_t * p;
6361+ int len;
6362+ int i;
6363+ int limit;
6364+#endif /* NO_CAPITALIZATION_SUPPORT */
6365+
6366+ if (*nsaved >= MAX_CAPS)
6367+ return;
6368+ (void) icharcpy (newword, word);
6369+ firstisupper = myupper (pattern[0]);
6370+#ifdef NO_CAPITALIZATION_SUPPORT
6371+ /*
6372+ ** Apply the old, simple-minded capitalization rules.
6373+ */
6374+ if (firstisupper)
6375+ {
6376+ if (myupper (pattern[1]))
6377+ upcase (newword);
6378+ else
6379+ {
6380+ lowcase (newword);
6381+ newword[0] = mytoupper (newword[0]);
6382+ }
6383+ }
6384+ else
6385+ lowcase (newword);
6386+ (void) icharcpy (savearea[*nsaved], newword);
6387+ (*nsaved)++;
6388+ return;
6389+#else /* NO_CAPITALIZATION_SUPPORT */
6390+#define flagsareok(dent) \
6391+ ((pfxent == NULL \
6392+ || TSTMASKBIT (dent->mask, pfxent->flagbit)) \
6393+ && (sufent == NULL \
6394+ || TSTMASKBIT (dent->mask, sufent->flagbit)))
6395+
6396+ dent = firstdent;
6397+ if ((dent->flagfield & (CAPTYPEMASK | MOREVARIANTS)) == ALLCAPS)
6398+ {
6399+ upcase (newword); /* Uppercase required */
6400+ (void) icharcpy (savearea[*nsaved], newword);
6401+ (*nsaved)++;
6402+ return;
6403+ }
6404+ for (p = pattern; *p; p++)
6405+ {
6406+ if (mylower (*p))
6407+ break;
6408+ }
6409+ if (*p == 0)
6410+ {
6411+ upcase (newword); /* Pattern was all caps */
6412+ (void) icharcpy (savearea[*nsaved], newword);
6413+ (*nsaved)++;
6414+ return;
6415+ }
6416+ for (p = pattern + 1; *p; p++)
6417+ {
6418+ if (myupper (*p))
6419+ break;
6420+ }
6421+ if (*p == 0)
6422+ {
6423+ /*
6424+ ** The pattern was all-lower or capitalized. If that's
6425+ ** legal, insert only that version.
6426+ */
6427+ if (firstisupper)
6428+ {
6429+ if (captype (dent->flagfield) == CAPITALIZED
6430+ || captype (dent->flagfield) == ANYCASE)
6431+ {
6432+ lowcase (newword);
6433+ newword[0] = mytoupper (newword[0]);
6434+ (void) icharcpy (savearea[*nsaved], newword);
6435+ (*nsaved)++;
6436+ return;
6437+ }
6438+ }
6439+ else
6440+ {
6441+ if (captype (dent->flagfield) == ANYCASE)
6442+ {
6443+ lowcase (newword);
6444+ (void) icharcpy (savearea[*nsaved], newword);
6445+ (*nsaved)++;
6446+ return;
6447+ }
6448+ }
6449+ while (dent->flagfield & MOREVARIANTS)
6450+ {
6451+ dent = dent->next;
6452+ if (captype (dent->flagfield) == FOLLOWCASE
6453+ || !flagsareok (dent))
6454+ continue;
6455+ if (firstisupper)
6456+ {
6457+ if (captype (dent->flagfield) == CAPITALIZED)
6458+ {
6459+ lowcase (newword);
6460+ newword[0] = mytoupper (newword[0]);
6461+ (void) icharcpy (savearea[*nsaved], newword);
6462+ (*nsaved)++;
6463+ return;
6464+ }
6465+ }
6466+ else
6467+ {
6468+ if (captype (dent->flagfield) == ANYCASE)
6469+ {
6470+ lowcase (newword);
6471+ (void) icharcpy (savearea[*nsaved], newword);
6472+ (*nsaved)++;
6473+ return;
6474+ }
6475+ }
6476+ }
6477+ }
6478+ /*
6479+ ** Either the sample had complex capitalization, or the simple
6480+ ** capitalizations (all-lower or capitalized) are illegal.
6481+ ** Insert all legal capitalizations, including those that are
6482+ ** all-lower or capitalized. If the prototype is capitalized,
6483+ ** capitalized all-lower samples. Watch out for affixes.
6484+ */
6485+ dent = firstdent;
6486+ p = strtosichar (dent->word, 1);
6487+ len = icharlen (p);
6488+ if (dent->flagfield & MOREVARIANTS)
6489+ dent = dent->next; /* Skip place-holder entry */
6490+ for ( ; ; )
6491+ {
6492+ if (flagsareok (dent))
6493+ {
6494+ if (captype (dent->flagfield) != FOLLOWCASE)
6495+ {
6496+ lowcase (newword);
6497+ if (firstisupper || captype (dent->flagfield) == CAPITALIZED)
6498+ newword[0] = mytoupper (newword[0]);
6499+ (void) icharcpy (savearea[*nsaved], newword);
6500+ (*nsaved)++;
6501+ if (*nsaved >= MAX_CAPS)
6502+ return;
6503+ }
6504+ else
6505+ {
6506+ /* Followcase is the tough one. */
6507+ p = strtosichar (dent->word, 1);
6508+ (void) bcopy ((char *) (p + prestrip),
6509+ (char *) (newword + preadd),
6510+ (len - prestrip - sufstrip) * sizeof (ichar_t));
6511+ if (myupper (p[prestrip]))
6512+ {
6513+ for (i = 0; i < preadd; i++)
6514+ newword[i] = mytoupper (newword[i]);
6515+ }
6516+ else
6517+ {
6518+ for (i = 0; i < preadd; i++)
6519+ newword[i] = mytolower (newword[i]);
6520+ }
6521+ limit = len + preadd + sufadd - prestrip - sufstrip;
6522+ i = len + preadd - prestrip - sufstrip;
6523+ p += len - sufstrip - 1;
6524+ if (myupper (*p))
6525+ {
6526+ for (p = newword + i; i < limit; i++, p++)
6527+ *p = mytoupper (*p);
6528+ }
6529+ else
6530+ {
6531+ for (p = newword + i; i < limit; i++, p++)
6532+ *p = mytolower (*p);
6533+ }
6534+ (void) icharcpy (savearea[*nsaved], newword);
6535+ (*nsaved)++;
6536+ if (*nsaved >= MAX_CAPS)
6537+ return;
6538+ }
6539+ }
6540+ if ((dent->flagfield & MOREVARIANTS) == 0)
6541+ break; /* End of the line */
6542+ dent = dent->next;
6543+ }
6544+ return;
6545+#endif /* NO_CAPITALIZATION_SUPPORT */
6546+}
6547+Public int
6548+insert(register ichar_t * word)
6549+{
6550+ register int i;
6551+ register char * realword;
6552+
6553+ realword = ichartosstr (word, 0);
6554+ for (i = 0; i < pcount; i++)
6555+ if (strcmp (possibilities[i], realword) == 0)
6556+ return (0);
6557+
6558+ (void) strcpy (possibilities[pcount++], realword);
6559+ i = strlen (realword);
6560+ if (i > maxposslen)
6561+ maxposslen = i;
6562+ if (pcount >= MAXPOSSIBLE)
6563+ return (-1);
6564+ else
6565+ return (0);
6566+}
6567+/*
6568+** A trivial wrapper for rindex (file '/') on Unix, but
6569+** saves a lot of ifdef-ing on MS-DOS.
6570+*/
6571+
6572+Public char *
6573+last_slash (char *file)
6574+
6575+{
6576+ char *slash = myrindex (file, '/');
6577+#ifdef MSDOS
6578+ /*
6579+ ** Can have a backslash or a colon; both mean the basename
6580+ ** begins right after them.
6581+ */
6582+ char *bs = myrindex (file, '\\');
6583+
6584+ /*
6585+ ** We can have both forward- and backslashes; return the
6586+ ** place of rightmost one of either gender.
6587+ */
6588+ if (slash == NULL || (bs != NULL && bs > slash))
6589+ slash = bs;
6590+ if (slash == NULL && file[0] != '\0' && file[1] == ':')
6591+ slash = file + 1;
6592+#endif
6593+ return slash;
6594+}
6595+
6596+Local char *
6597+myrindex(char *s, register char c)
6598+
6599+{
6600+ register char *x;
6601+
6602+ x = s + strlen(s) - 1;
6603+
6604+ while(x >= s)
6605+ {
6606+ if(*x == c)
6607+ return(x);
6608+ x--;
6609+ }
6610+ return(NULL);
6611+}
41e3656f 6612diff -ruN vim62./src/spell/version.h vim62/src/spell/version.h
6613--- vim62./src/spell/version.h 1970-01-01 01:00:00.000000000 +0100
6614+++ vim62/src/spell/version.h 2003-06-02 19:57:21.000000000 +0200
24ec98f0
JB
6615@@ -0,0 +1,124 @@
6616+/*
6617+ * Since the strings in this file are printed out when the "-v" switch is
6618+ * given to ispell, you may want to translate them into your native language.
6619+ * However, any translation of these strings MUST accurately preserve the
6620+ * legal rights under international law; you may wish to consult a lawyer
6621+ * about this since you will be responsible for the results of any
6622+ * incorrect translation.
6623+ */
6624+
6625+Local char *Version_ID[] = {
6626+ "@(#) International Ispell Version 3.1.20 10/10/95",
6627+ "@(#) Copyright (c), 1983, by Pace Willisson",
6628+ "@(#) International version Copyright (c) 1987, 1988, 1990-1995,",
6629+ "@(#) by Geoff Kuenning, Granada Hills, CA. All rights reserved.",
6630+ "@(#)",
6631+ "@(#) Redistribution and use in source and binary forms, with or without",
6632+ "@(#) modification, are permitted provided that the following conditions",
6633+ "@(#) are met:",
6634+ "@(#)",
6635+ "@(#) 1. Redistributions of source code must retain the above copyright",
6636+ "@(#) notice, this list of conditions and the following disclaimer.",
6637+ "@(#) 2. Redistributions in binary form must reproduce the above",
6638+ "@(#) copyright notice, this list of conditions and the following",
6639+ "@(#) disclaimer in the documentation and/or other materials provided",
6640+ "@(#) with the distribution.",
6641+ "@(#) 3. All modifications to the source code must be clearly marked as",
6642+ "@(#) such. Binary redistributions based on modified source code",
6643+ "@(#) must be clearly marked as modified versions in the documentation",
6644+ "@(#) and/or other materials provided with the distribution.",
6645+ "@(#) 4. All advertising materials mentioning features or use of this",
6646+ "@(#) software must display the following acknowledgment:",
6647+ "@(#) This product includes software developed by Geoff Kuenning and",
6648+ "@(#) other unpaid contributors.",
6649+ "@(#) 5. The name of Geoff Kuenning may not be used to endorse or promote",
6650+ "@(#) products derived from this software without specific prior",
6651+ "@(#) written permission.",
6652+ "@(#)",
6653+ "@(#) THIS SOFTWARE IS PROVIDED BY GEOFF KUENNING AND CONTRIBUTORS ``AS",
6654+ "@(#) IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT",
6655+ "@(#) LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS",
6656+ "@(#) FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL GEOFF",
6657+ "@(#) KUENNING OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,",
6658+ "@(#) INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES",
6659+ "@(#) (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR",
6660+ "@(#) SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)",
6661+ "@(#) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,",
6662+ "@(#) STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)",
6663+ "@(#) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED",
6664+ "@(#) OF THE POSSIBILITY OF SUCH DAMAGE.",
6665+ NULL
6666+};
6667+
6668+static char RCS_Version_ID[] =
6669+ "$Id$";
6670+
6671+/*
6672+ * $Log$
6673+ * Revision 1.44 1995/10/11 05:03:28 geoff
6674+ * Upgrade to patch level 20
6675+ *
6676+ * Revision 1.43 1995/10/11 04:58:26 geoff
6677+ * Upgrade to patch 19
6678+ *
6679+ * Revision 1.42 1995/01/15 01:23:26 geoff
6680+ * Upgrade to patch level 18
6681+ *
6682+ * Revision 1.41 1995/01/15 01:14:30 geoff
6683+ * Upgrade to patch level 17
6684+ *
6685+ * Revision 1.40 1995/01/15 01:03:55 geoff
6686+ * Upgrade to patch level 16
6687+ *
6688+ * Revision 1.39 1995/01/15 01:01:01 geoff
6689+ * Upgrade to patch level 15
6690+ *
6691+ * Revision 1.38 1995/01/15 00:54:19 geoff
6692+ * Upgrade to patch level 14
6693+ *
6694+ * Revision 1.37 1994/11/21 07:03:01 geoff
6695+ * Update to patch level 13.
6696+ *
6697+ * Revision 1.36 1994/11/01 06:28:31 geoff
6698+ * Update to patch level 12
6699+ *
6700+ * Revision 1.35 1994/11/01 06:12:42 geoff
6701+ * Update to patch level 11
6702+ *
6703+ * Revision 1.34 1994/11/01 06:01:15 geoff
6704+ * Update to patch level 10
6705+ *
6706+ * Revision 1.33 1994/11/01 05:36:43 geoff
6707+ * Update to patch level 9
6708+ *
6709+ * Revision 1.32 1994/05/25 04:38:59 geoff
6710+ * Update to patch level 8
6711+ *
6712+ * Revision 1.31 1994/05/18 03:07:26 geoff
6713+ * Update to patch level 7
6714+ *
6715+ * Revision 1.30 1994/05/17 06:21:05 geoff
6716+ * Version update for ispell.el release
6717+ *
6718+ * Revision 1.29 1994/04/27 04:14:18 geoff
6719+ * Update to patch level 5
6720+ *
6721+ * Revision 1.28 1994/03/21 02:00:50 geoff
6722+ * Update to patch level 4
6723+ *
6724+ * Revision 1.27 1994/02/23 04:52:31 geoff
6725+ * Update to latest version.
6726+ *
6727+ * Revision 1.26 1994/02/08 05:59:20 geoff
6728+ * Update version
6729+ *
6730+ * Revision 1.25 1994/02/07 08:58:28 geoff
6731+ * Get rid of a comma that confuses patch
6732+ *
6733+ * Revision 1.24 1994/02/07 08:24:23 geoff
6734+ * Upate patch level
6735+ *
6736+ * Revision 1.23 1994/01/25 07:12:21 geoff
6737+ * Get rid of all old RCS log lines in preparation for the 3.1 release.
6738+ *
6739+ */
41e3656f 6740diff -ruN vim62./src/spell/wm.h vim62/src/spell/wm.h
6741--- vim62./src/spell/wm.h 1970-01-01 01:00:00.000000000 +0100
6742+++ vim62/src/spell/wm.h 2003-06-02 19:57:21.000000000 +0200
24ec98f0
JB
6743@@ -0,0 +1,12 @@
6744+#ifndef Public
6745+enum _logical {False,True};
6746+typedef enum _logical Logical;
6747+
6748+#define EOS '\0'
6749+
6750+typedef unsigned int Word;
6751+typedef unsigned char Byte;
6752+
6753+#define Public
6754+#define Local static
6755+#endif
41e3656f 6756diff -ruN vim62./src/spell.c vim62/src/spell.c
6757--- vim62./src/spell.c 1970-01-01 01:00:00.000000000 +0100
6758+++ vim62/src/spell.c 2003-06-02 19:57:21.000000000 +0200
24ec98f0
JB
6759@@ -0,0 +1,183 @@
6760+#include "spell/wm.h"
6761+#include "vim.h"
6762+#define MAIN 1
6763+#include "ispell.h"
6764+#define MAXWORDLEN 80
6765+
6766+#ifdef FEAT_SPELL_HL
6767+
6768+int spell_flag = 0;
6769+Local char *err;
6770+void
6771+ex_spell(exarg_T *eap)
6772+
6773+{
6774+ if(strcmp(eap->arg, "on") == 0)
6775+ {
6776+ spell_flag = 1;
6777+ if(!inited)
6778+ {
6779+ if(!reload_dict())
6780+ return;
6781+ }
6782+ }
6783+ else if(STRCMP(eap->arg, "off") == 0)
6784+ spell_flag = 0;
6785+ else
6786+ EMSG2("Invalid :spell %s", eap->arg);
6787+ redraw_all_later(NOT_VALID);
6788+ return;
6789+}
6790+
6791+int
6792+reload_dict()
6793+
6794+{
6795+ if(spell_flag == 0)
6796+ return(TRUE);
6797+ spell_save_private_dict();
6798+ inited = 0;
6799+ if(STRCMP(p_spell_lang, "") == 0)
6800+ {
6801+ EMSG("dictionary not defined");
6802+ do_cmdline((char_u *)"spell off", NULL, NULL, DOCMD_VERBOSE);
6803+ spell_flag = 0;
6804+ return(FALSE);
6805+ }
6806+ if ((err = linit(hashname)) != NULL)
6807+ {
6808+ EMSG(err);
6809+ do_cmdline((char_u *)"spell off", NULL, NULL, DOCMD_VERBOSE);
6810+ spell_flag = 0;
6811+ return(FALSE);
6812+ }
6813+ treeinit (NULL, p_spell_lang);
6814+ return(TRUE);
6815+}
6816+
6817+static colnr_T last_col;
6818+static ichar_t curr_word[MAXWORDLEN + 1]; /* assume max. keyword len is 80 */
6819+static char word_to_spell[MAXWORDLEN + 1];
6820+ int last_attr;
6821+static Logical in_word;
6822+
6823+int my_is_char(char_u ccc);
6824+
6825+int
6826+get_spell_attr(spell_col, col, line)
6827+ colnr_T spell_col;
6828+ colnr_T col;
6829+ char_u *line;
6830+{
6831+ char_u *line_ptr;
6832+ colnr_T curr_col;
6833+ unsigned int i;
6834+
6835+ if(spell_col == 0)
6836+ last_col = 0, in_word = False, last_attr = 0;
6837+
6838+ if((spell_col < last_col) && in_word)
6839+ return(last_attr);
6840+ else if(spell_col >= last_col)
6841+ {
6842+ last_attr = 0;
6843+ in_word = False;
6844+ line_ptr = &line[spell_col];
6845+ curr_col = spell_col;
6846+ if(iswordch((ichar_t)(*line_ptr)) && *line_ptr)
6847+ {
6848+ while((spell_col > 0) && my_is_char(*(line_ptr - 1)))
6849+ spell_col--, line_ptr--;
6850+ while(isboundarych((ichar_t)(*(line_ptr))))
6851+ spell_col++, line_ptr++;
6852+
6853+ line_ptr = &line[spell_col];
6854+ curr_col = spell_col;
6855+ while(my_is_char(*line_ptr) && *line_ptr &&
6856+ ((curr_col - spell_col) < MAXWORDLEN))
6857+ curr_col++, line_ptr++;
6858+ while(isboundarych((ichar_t)(*(line_ptr - 1))))
6859+ curr_col--, line_ptr--;
6860+ }
6861+ if(curr_col - spell_col > 1)
6862+ {
6863+ /*for(i = 0; i < curr_col - spell_col; i++)
6864+ curr_word[i] = line[spell_col + i];
6865+ curr_word[curr_col - spell_col] = NUL;*/
6866+ strtoichar(curr_word,line+spell_col,(curr_col-spell_col+1)*sizeof(ichar_t),0);
6867+ in_word = True;
6868+
6869+/* for(i = 0; curr_word[i]; i++)
6870+ fprintf(stderr, "%c", curr_word[i]);
6871+ fprintf(stderr, "-%d\n", good((ichar_t *)curr_word, 0, 0, 0, 0)); wm */
6872+ if(good((ichar_t *)curr_word, 0, 0, 0, 0) == 0)
6873+ last_attr = hl_attr(HLF_SPELL);
6874+ last_col = curr_col;
6875+ }
6876+ }
6877+ return(last_attr);
6878+}
6879+
6880+int
6881+my_is_char(ccc)
6882+ char_u ccc;
6883+{
6884+ if(iswordch((ichar_t)ccc) || isboundarych((ichar_t)ccc))
6885+ return(TRUE);
6886+ else
6887+ return(FALSE);
6888+
6889+}
6890+
6891+static ichar_t *itok;
6892+
6893+int
6894+set_to_private_dict(char *line, int cursor_col, int convert_to_lower)
6895+
6896+{
6897+ int i;
6898+ char_u *b,
6899+ *e;
6900+
6901+ b = line + cursor_col;
6902+ e = b;
6903+ if(inited == 0)
6904+ return(TRUE);
6905+ if(iswordch((ichar_t)(*b)) || isboundarych((ichar_t)(*b)))
6906+ {
6907+ while((iswordch((ichar_t)(*(b - 1))) ||
6908+ isboundarych((ichar_t)(*(b - 1)))) &&
6909+ cursor_col > 0)
6910+ b--, cursor_col--;
6911+ while(isboundarych((ichar_t)(*b)))
6912+ b++;
6913+ while((iswordch((ichar_t)(*(e))) || isboundarych((ichar_t)(*(e)))) &&
6914+ *e)
6915+ e++;
6916+ while(isboundarych((ichar_t)(*(e - 1))))
6917+ e--;
6918+ for(i = 0; b < e;)
6919+ word_to_spell[i++] = *b++;
6920+ word_to_spell[i] = '\0';
6921+ if(!convert_to_lower)
6922+ treeinsert (ichartosstr (strtosichar (word_to_spell, 0), 1),
6923+ ICHARTOSSTR_SIZE, 1);
6924+ else
6925+ {
6926+ itok = strtosichar (word_to_spell, 0);
6927+ lowcase (itok);
6928+ treeinsert (ichartosstr (itok, 1), ICHARTOSSTR_SIZE, 1);
6929+ }
6930+ redraw_all_later(NOT_VALID);
6931+ }
6932+ return(FALSE);
6933+}
6934+
6935+void
6936+spell_save_private_dict(void)
6937+
6938+{
6939+ if(inited)
6940+ treeoutput ();
6941+}
6942+#endif
41e3656f 6943diff -ruN vim62./src/syntax.c vim62/src/syntax.c
6944--- vim62./src/syntax.c 2003-05-02 20:50:03.000000000 +0200
6945+++ vim62/src/syntax.c 2003-06-02 19:57:21.000000000 +0200
6946@@ -5887,6 +5887,9 @@
24ec98f0
JB
6947 "VertSplit term=reverse cterm=reverse gui=reverse",
6948 "Visual term=reverse cterm=reverse gui=reverse guifg=Grey guibg=fg",
6949 "VisualNOS term=underline,bold cterm=underline,bold gui=underline,bold",
6950+#ifdef FEAT_SPELL_HL
6951+ "Spell term=reverse ctermbg=NONE ctermfg=White guibg=NONE guifg=Red",
6952+#endif
6953 "DiffText term=reverse cterm=bold ctermbg=Red gui=bold guibg=Red",
6954 NULL
6955 };
41e3656f 6956@@ -5906,6 +5909,9 @@
24ec98f0
JB
6957 "Folded term=standout ctermbg=Grey ctermfg=DarkBlue guibg=LightGrey guifg=DarkBlue",
6958 "FoldColumn term=standout ctermbg=Grey ctermfg=DarkBlue guibg=Grey guifg=DarkBlue",
6959 "DiffAdd term=bold ctermbg=LightBlue guibg=LightBlue",
6960+#ifdef FEAT_SPELL_HL
6961+ "Spell term=reverse ctermbg=NONE ctermfg=White guibg=NONE guifg=Red",
6962+#endif
6963 "DiffChange term=bold ctermbg=LightMagenta guibg=LightMagenta",
6964 "DiffDelete term=bold ctermfg=Blue ctermbg=LightCyan gui=bold guifg=Blue guibg=LightCyan",
6965 NULL
41e3656f 6966@@ -5926,6 +5932,9 @@
24ec98f0
JB
6967 "Folded term=standout ctermbg=DarkGrey ctermfg=Cyan guibg=DarkGrey guifg=Cyan",
6968 "FoldColumn term=standout ctermbg=DarkGrey ctermfg=Cyan guibg=Grey guifg=Cyan",
6969 "DiffAdd term=bold ctermbg=DarkBlue guibg=DarkBlue",
6970+#ifdef FEAT_SPELL_HL
6971+ "Spell term=reverse ctermbg=NONE ctermfg=White guibg=NONE guifg=Red",
6972+#endif
6973 "DiffChange term=bold ctermbg=DarkMagenta guibg=DarkMagenta",
6974 "DiffDelete term=bold ctermfg=Blue ctermbg=DarkCyan gui=bold guifg=Blue guibg=DarkCyan",
6975 NULL
41e3656f 6976diff -ruN vim62./src/version.c vim62/src/version.c
6977--- vim62./src/version.c 2003-06-01 12:18:15.000000000 +0200
6978+++ vim62/src/version.c 2003-06-02 19:57:21.000000000 +0200
6979@@ -470,6 +470,11 @@
24ec98f0
JB
6980 #else
6981 "-syntax",
6982 #endif
6983+#ifdef FEAT_SPELL_HL
6984+ "+spell",
6985+#else
6986+ "-spell",
6987+#endif
6988 /* only interesting on Unix systems */
6989 #if defined(USE_SYSTEM) && (defined(UNIX) || defined(__EMX__))
6990 "+system()",
41e3656f 6991@@ -1103,7 +1108,7 @@
24ec98f0
JB
6992 int add_version;
6993 int attr;
6994 {
6995- char_u vers[20];
6996+ char_u vers[80];
6997 int col;
6998 char_u *p;
6999 int l;
41e3656f 7000diff -ruN vim62./src/version.h vim62/src/version.h
7001--- vim62./src/version.h 2003-06-01 12:19:20.000000000 +0200
7002+++ vim62/src/version.h 2003-06-02 20:03:17.000000000 +0200
98f80704 7003@@ -35,6 +35,10 @@
24ec98f0 7004 */
41e3656f 7005 #define VIM_VERSION_NODOT "vim62"
7006 #define VIM_VERSION_SHORT "6.2"
24ec98f0 7007+#ifdef FEAT_SPELL_HL
41e3656f 7008+#define VIM_VERSION_MEDIUM "6.2 + ispell 3.1.20 WM-3"
24ec98f0 7009+#else
41e3656f 7010 #define VIM_VERSION_MEDIUM "6.2"
7011+#endif
7012 #define VIM_VERSION_LONG "VIM - Vi IMproved 6.2 (2003 Jun 1)"
7013 #define VIM_VERSION_LONG_DATE "VIM - Vi IMproved 6.2 (2003 Jun 1, compiled "
7014diff -ruN vim62./src/vim.h vim62/src/vim.h
7015--- vim62./src/vim.h 2003-05-29 11:32:47.000000000 +0200
7016+++ vim62/src/vim.h 2003-06-02 19:57:21.000000000 +0200
7017@@ -1059,13 +1059,14 @@
24ec98f0
JB
7018 , HLF_CHD /* Changed diff line */
7019 , HLF_DED /* Deleted diff line */
7020 , HLF_TXD /* Text Changed in diff line */
7021+ , HLF_SPELL /* spell - string not in dictionary WM */
7022 , HLF_COUNT /* MUST be the last one */
7023 };
7024
7025 /* the HL_FLAGS must be in the same order as the HLF_ enums! */
7026 #define HL_FLAGS {'8', '@', 'd', 'e', 'h', 'i', 'l', 'm', 'M', \
7027 'n', 'r', 's', 'S', 'c', 't', 'v', 'V', 'w', 'W', \
7028- 'f', 'F', 'A', 'C', 'D', 'T'}
7029+ 'f', 'F', 'A', 'C', 'D', 'T', 'Z'}
7030
7031 /*
7032 * Boolean constants
This page took 0.931417 seconds and 4 git commands to generate.