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