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