342b936751349367a0d62c1c711d0c4b55200aac
[platform/upstream/aspell.git] / modules / speller / default / speller_impl.hpp
1 // Aspell main C++ include file
2 // Copyright 1998-2000 by Kevin Atkinson under the terms of the LGPL.
3
4 #ifndef __aspeller_speller__
5 #define __aspeller_speller__
6
7 #include <vector>
8
9 #include "clone_ptr.hpp"
10 #include "copy_ptr.hpp"
11 #include "data.hpp"
12 #include "enumeration.hpp"
13 #include "speller.hpp"
14 #include "check_list.hpp"
15
16 using namespace acommon;
17
18 namespace acommon {
19   class StringMap;
20   class Config;
21   class WordList;
22 }
23 // The speller class is responsible for keeping track of the
24 // dictionaries coming up with suggestions and the like. Its methods
25 // are NOT meant to be used my multiple threads and/or documents.
26
27 namespace aspeller {
28
29   class Language;
30   class SensitiveCompare;
31   class Suggest;
32
33   enum SpecialId {main_id, personal_id, session_id, 
34                   personal_repl_id, none_id};
35
36   struct SpellerDict
37   {
38     Dict *            dict;
39     bool              use_to_check;
40     bool              use_to_suggest;
41     bool              save_on_saveall;
42     SpecialId         special_id;
43     SpellerDict     * next;
44     SpellerDict(Dict *);
45     SpellerDict(Dict *, const Config &, SpecialId id = none_id);
46     ~SpellerDict() {if (dict) dict->release();}
47   };
48
49   class SpellerImpl : public Speller
50   {
51   public:
52     SpellerImpl(); // does not set anything up. 
53     ~SpellerImpl();
54
55     PosibErr<void> setup(Config *);
56
57     void setup_tokenizer(Tokenizer *);
58
59     //
60     // Low level Word List Management methods
61     //
62
63   public:
64
65     typedef Enumeration<Dict *> * WordLists;
66
67     WordLists wordlists() const;
68     int num_wordlists() const;
69
70     const SpellerDict * locate (const Dict::Id &) const;
71
72     //
73     // Add a single dictionary that has not been previously added
74     //
75     PosibErr<void> add_dict(SpellerDict *);
76
77     PosibErr<const WordList *> personal_word_list  () const;
78     PosibErr<const WordList *> session_word_list   () const;
79     PosibErr<const WordList *> main_word_list      () const;
80
81     //
82     // Language methods
83     //
84     
85     char * to_lower(char *);
86
87     const char * lang_name() const;
88
89     const Language & lang() const {return *lang_;}
90
91     //
92     // Spelling methods
93     //
94   
95     PosibErr<bool> check(char * word, char * word_end, /* it WILL modify word */
96                          bool try_uppercase,
97                          unsigned run_together_limit,
98                          CheckInfo *, GuessInfo *);
99
100     PosibErr<bool> check(MutableString word) {
101       guess_info.reset();
102       return check(word.begin(), word.end(), false,
103                    unconditional_run_together_ ? run_together_limit_ : 0,
104                    check_inf, &guess_info);
105     }
106     PosibErr<bool> check(ParmString word)
107     {
108       std::vector<char> w(word.size()+1);
109       strncpy(&*w.begin(), word, w.size());
110       return check(MutableString(&w.front(), w.size() - 1));
111     }
112
113     PosibErr<bool> check(const char * word) {return check(ParmString(word));}
114
115     bool check2(char * word, /* it WILL modify word */
116                 bool try_uppercase,
117                 CheckInfo & ci, GuessInfo * gi);
118
119     bool check_affix(ParmString word, CheckInfo & ci, GuessInfo * gi);
120
121     bool check_simple(ParmString, WordEntry &);
122
123     const CheckInfo * check_info() {
124       if (check_inf[0].word)
125         return check_inf;
126       else if (guess_info.head)
127         return guess_info.head;
128       else
129         return 0;
130     }
131     
132     //
133     // High level Word List management methods
134     //
135
136     PosibErr<void> add_to_personal(MutableString word);
137     PosibErr<void> add_to_session(MutableString word);
138
139     PosibErr<void> save_all_word_lists();
140
141     PosibErr<void> clear_session();
142
143     PosibErr<const WordList *> suggest(MutableString word);
144     // the suggestion list and the elements in it are only 
145     // valid until the next call to suggest.
146
147     PosibErr<void> store_replacement(MutableString mis, 
148                                      MutableString cor);
149
150     PosibErr<void> store_replacement(const String & mis, const String & cor,
151                                      bool memory);
152
153     //
154     // Private Stuff (from here to the end of the class)
155     //
156
157     class DictCollection;
158     class ConfigNotifier;
159
160   private:
161     friend class ConfigNotifier;
162
163     CachePtr<const Language>   lang_;
164     CopyPtr<SensitiveCompare>  sensitive_compare_;
165     //CopyPtr<DictCollection> wls_;
166     ClonePtr<Suggest>       suggest_;
167     ClonePtr<Suggest>       intr_suggest_;
168     unsigned int            ignore_count;
169     bool                    ignore_repl;
170     String                  prev_mis_repl_;
171     String                  prev_cor_repl_;
172
173     void operator= (const SpellerImpl &other);
174     SpellerImpl(const SpellerImpl &other);
175
176     SpellerDict * dicts_;
177     
178     Dictionary       * personal_;
179     Dictionary       * session_;
180     ReplacementDict  * repl_;
181     Dictionary       * main_;
182
183   public:
184     // these are public so that other classes and functions can use them, 
185     // DO NOT USE
186
187     const SensitiveCompare & sensitive_compare() const {return *sensitive_compare_;}
188
189     //const DictCollection & data_set_collection() const {return *wls_;}
190
191     PosibErr<void> set_check_lang(ParmString lang, ParmString lang_dir);
192   
193     double distance (const char *, const char *, 
194                      const char *, const char *) const;
195
196     CheckInfo check_inf[8];
197     GuessInfo guess_info;
198
199     SensitiveCompare s_cmp;
200     SensitiveCompare s_cmp_begin;
201     SensitiveCompare s_cmp_middle;
202     SensitiveCompare s_cmp_end;
203
204     typedef Vector<const Dict *> WS;
205     WS check_ws, affix_ws, suggest_ws, suggest_affix_ws;
206
207     bool                    unconditional_run_together_;
208     unsigned int            run_together_limit_;
209     unsigned int            run_together_min_;
210
211     bool affix_info, affix_compress;
212
213     bool have_repl;
214
215     bool have_soundslike;
216
217     bool invisible_soundslike, soundslike_root_only;
218
219     bool fast_scan, fast_lookup;
220
221     bool run_together;
222
223   };
224
225   struct LookupInfo {
226     SpellerImpl * sp;
227     enum Mode {Word, Guess, Clean, Soundslike, AlwaysTrue} mode;
228     SpellerImpl::WS::const_iterator begin;
229     SpellerImpl::WS::const_iterator end;
230     inline LookupInfo(SpellerImpl * s, Mode m);
231     // returns 0 if nothing found
232     // 1 if a match is found
233     // -1 if a word is found but affix doesn't match and "gi"
234     int lookup (ParmString word, const SensitiveCompare * c, char aff, 
235                 WordEntry & o, GuessInfo * gi) const;
236   };
237
238   inline LookupInfo::LookupInfo(SpellerImpl * s, Mode m) 
239     : sp(s), mode(m) 
240   {
241     switch (m) { 
242     case Word: 
243       begin = sp->affix_ws.begin(); 
244       end = sp->affix_ws.end();
245       return;
246     case Guess:
247       begin = sp->check_ws.begin(); 
248       end = sp->check_ws.end(); 
249       mode = Word; 
250       return;
251     case Clean:
252     case Soundslike: 
253       begin = sp->suggest_affix_ws.begin(); 
254       end = sp->suggest_affix_ws.end(); 
255       return;
256     case AlwaysTrue: 
257       return; 
258     }
259   }
260 }
261
262 #endif