]>
Commit | Line | Data |
---|---|---|
98f80704 | 1 | diff -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 | 99 | diff -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 | 136 | diff -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 | 148 | diff -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 | 174 | diff -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 | 190 | diff -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 | 203 | diff -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 | 216 | diff -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 | 277 | diff -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); |
376 | diff -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 | 388 | diff -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 | 397 | diff -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 |
410 | diff -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 | 482 | diff -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 | 1332 | diff -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 | 1736 | diff -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 | 1831 | diff -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 | 1947 | diff -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 | 2570 | diff -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 | 2912 | diff -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 | 3450 | diff -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 | 4561 | diff -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 | 4843 | diff -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 | 5501 | diff -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 | 6253 | diff -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 | 6608 | diff -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 | 6736 | diff -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 | 6752 | diff -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 | 6939 | diff -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 | 6972 | diff -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 | 6996 | diff -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 " | |
7010 | diff -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 |