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