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