Line data Source code
1 : /* ***** BEGIN LICENSE BLOCK *****
2 : * Version: MPL 1.1/GPL 2.0/LGPL 2.1
3 : *
4 : * Copyright (C) 2002-2017 Németh László
5 : *
6 : * The contents of this file are subject to the Mozilla Public License Version
7 : * 1.1 (the "License"); you may not use this file except in compliance with
8 : * the License. You may obtain a copy of the License at
9 : * http://www.mozilla.org/MPL/
10 : *
11 : * Software distributed under the License is distributed on an "AS IS" basis,
12 : * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
13 : * for the specific language governing rights and limitations under the
14 : * License.
15 : *
16 : * Hunspell is based on MySpell which is Copyright (C) 2002 Kevin Hendricks.
17 : *
18 : * Contributor(s): David Einstein, Davide Prina, Giuseppe Modugno,
19 : * Gianluca Turconi, Simon Brouwer, Noll János, Bíró Árpád,
20 : * Goldman Eleonóra, Sarlós Tamás, Bencsáth Boldizsár, Halácsy Péter,
21 : * Dvornik László, Gefferth András, Nagy Viktor, Varga Dániel, Chris Halls,
22 : * Rene Engelhard, Bram Moolenaar, Dafydd Jones, Harri Pitkänen
23 : *
24 : * Alternatively, the contents of this file may be used under the terms of
25 : * either the GNU General Public License Version 2 or later (the "GPL"), or
26 : * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
27 : * in which case the provisions of the GPL or the LGPL are applicable instead
28 : * of those above. If you wish to allow use of your version of this file only
29 : * under the terms of either the GPL or the LGPL, and not to allow others to
30 : * use your version of this file under the terms of the MPL, indicate your
31 : * decision by deleting the provisions above and replace them with the notice
32 : * and other provisions required by the GPL or the LGPL. If you do not delete
33 : * the provisions above, a recipient may use your version of this file under
34 : * the terms of any one of the MPL, the GPL or the LGPL.
35 : *
36 : * ***** END LICENSE BLOCK ***** */
37 : /*
38 : * Copyright 2002 Kevin B. Hendricks, Stratford, Ontario, Canada
39 : * And Contributors. All rights reserved.
40 : *
41 : * Redistribution and use in source and binary forms, with or without
42 : * modification, are permitted provided that the following conditions
43 : * are met:
44 : *
45 : * 1. Redistributions of source code must retain the above copyright
46 : * notice, this list of conditions and the following disclaimer.
47 : *
48 : * 2. Redistributions in binary form must reproduce the above copyright
49 : * notice, this list of conditions and the following disclaimer in the
50 : * documentation and/or other materials provided with the distribution.
51 : *
52 : * 3. All modifications to the source code must be clearly marked as
53 : * such. Binary redistributions based on modified source code
54 : * must be clearly marked as modified versions in the documentation
55 : * and/or other materials provided with the distribution.
56 : *
57 : * THIS SOFTWARE IS PROVIDED BY KEVIN B. HENDRICKS AND CONTRIBUTORS
58 : * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
59 : * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
60 : * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL
61 : * KEVIN B. HENDRICKS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
62 : * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
63 : * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
64 : * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
65 : * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
66 : * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
67 : * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
68 : * SUCH DAMAGE.
69 : */
70 :
71 : #include <stdlib.h>
72 : #include <string.h>
73 : #include <stdio.h>
74 : #include <limits>
75 :
76 : #include "replist.hxx"
77 : #include "csutil.hxx"
78 :
79 0 : RepList::RepList(int n) {
80 0 : dat = (replentry**)malloc(sizeof(replentry*) * n);
81 0 : if (dat == 0)
82 0 : size = 0;
83 : else
84 0 : size = n;
85 0 : pos = 0;
86 0 : }
87 :
88 0 : RepList::~RepList() {
89 0 : for (int i = 0; i < pos; i++) {
90 0 : delete dat[i];
91 : }
92 0 : free(dat);
93 0 : }
94 :
95 0 : replentry* RepList::item(int n) {
96 0 : return dat[n];
97 : }
98 :
99 0 : int RepList::find(const char* word) {
100 0 : int p1 = 0;
101 0 : int p2 = pos - 1;
102 0 : int ret = -1;
103 0 : while (p1 <= p2) {
104 0 : int m = ((unsigned)p1 + (unsigned)p2) >> 1;
105 0 : int c = strncmp(word, dat[m]->pattern.c_str(), dat[m]->pattern.size());
106 0 : if (c < 0)
107 0 : p2 = m - 1;
108 0 : else if (c > 0)
109 0 : p1 = m + 1;
110 : else { // scan in the right half for a longer match
111 0 : ret = m;
112 0 : p1 = m + 1;
113 : }
114 : }
115 0 : return ret;
116 : }
117 :
118 0 : std::string RepList::replace(const char* word, int ind, bool atstart) {
119 0 : int type = atstart ? 1 : 0;
120 0 : if (ind < 0)
121 0 : return std::string();
122 0 : if (strlen(word) == dat[ind]->pattern.size())
123 0 : type = atstart ? 3 : 2;
124 0 : while (type && dat[ind]->outstrings[type].empty())
125 0 : type = (type == 2 && !atstart) ? 0 : type - 1;
126 0 : return dat[ind]->outstrings[type];
127 : }
128 :
129 0 : int RepList::add(const std::string& in_pat1, const std::string& pat2) {
130 0 : if (pos >= size || in_pat1.empty() || pat2.empty()) {
131 0 : return 1;
132 : }
133 : // analyse word context
134 0 : int type = 0;
135 0 : std::string pat1(in_pat1);
136 0 : if (pat1[0] == '_') {
137 0 : pat1.erase(0, 1);
138 0 : type = 1;
139 : }
140 0 : if (!pat1.empty() && pat1[pat1.size() - 1] == '_') {
141 0 : type = type + 2;
142 0 : pat1.erase(pat1.size() - 1);
143 : }
144 0 : mystrrep(pat1, "_", " ");
145 :
146 : // find existing entry
147 0 : int m = find(pat1.c_str());
148 0 : if (m >= 0 && dat[m]->pattern == pat1) {
149 : // since already used
150 0 : dat[m]->outstrings[type] = pat2;
151 0 : mystrrep(dat[m]->outstrings[type], "_", " ");
152 0 : return 0;
153 : }
154 :
155 : // make a new entry if none exists
156 0 : replentry* r = new replentry;
157 0 : if (r == NULL)
158 0 : return 1;
159 0 : r->pattern = pat1;
160 0 : r->outstrings[type] = pat2;
161 0 : mystrrep(r->outstrings[type], "_", " ");
162 0 : dat[pos++] = r;
163 : // sort to the right place in the list
164 : int i;
165 0 : for (i = pos - 1; i > 0; i--) {
166 0 : if (strcmp(r->pattern.c_str(), dat[i - 1]->pattern.c_str()) < 0) {
167 0 : dat[i] = dat[i - 1];
168 : } else
169 0 : break;
170 : }
171 0 : dat[i] = r;
172 0 : return 0;
173 : }
174 :
175 0 : bool RepList::conv(const std::string& in_word, std::string& dest) {
176 0 : dest.clear();
177 :
178 0 : size_t wordlen = in_word.size();
179 0 : const char* word = in_word.c_str();
180 :
181 0 : bool change = false;
182 0 : for (size_t i = 0; i < wordlen; ++i) {
183 0 : int n = find(word + i);
184 0 : std::string l = replace(word + i, n, i == 0);
185 0 : if (!l.empty()) {
186 0 : dest.append(l);
187 0 : i += dat[n]->pattern.size() - 1;
188 0 : change = true;
189 : } else {
190 0 : dest.push_back(word[i]);
191 : }
192 : }
193 :
194 0 : return change;
195 : }
196 :
|