1 /*
2 * CDDL HEADER START
3 *
4 * The contents of this file are subject to the terms of the
5 * Common Development and Distribution License, Version 1.0 only
6 * (the "License"). You may not use this file except in compliance
7 * with the License.
8 *
9 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
10 * or http://www.opensolaris.org/os/licensing.
11 * See the License for the specific language governing permissions
12 * and limitations under the License.
13 *
14 * When distributing Covered Code, include this CDDL HEADER in each
15 * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
16 * If applicable, add the following below this CDDL HEADER, with the
17 * fields enclosed by brackets "[]" replaced with your own identifying
18 * information: Portions Copyright [yyyy] [name of copyright owner]
19 *
20 * CDDL HEADER END
21 */
22 /*
23 * Copyright 2003 Sun Microsystems, Inc. All rights reserved.
24 * Use is subject to license terms.
25 */
26
27 /* Copyright (c) 1984, 1986, 1987, 1988, 1989 AT&T */
28 /* All Rights Reserved */
29
30 /*
31 * University Copyright- Copyright (c) 1982, 1986, 1988
32 * The Regents of the University of California
33 * All Rights Reserved
34 *
35 * University Acknowledgment- Portions of this document are derived from
36 * software developed by the University of California, Berkeley, and its
37 * contributors.
38 */
39
40 #include <ctype.h>
41 #include "tdef.h"
42 #include "ext.h"
43 #define HY_BIT 0200 /* stuff in here only works for ascii */
44
45 /*
46 * troff8.c
47 *
48 * hyphenation
49 */
50
51 char hbuf[NHEX];
52 char *nexth = hbuf;
53 tchar *hyend;
54 #define THRESH 160 /*digram goodness threshold*/
55 int thresh = THRESH;
56
57 int
hyphen(wp)58 hyphen(wp)
59 tchar *wp;
60 {
61 int j;
62 tchar *i;
63
64 i = wp;
65 while (punct(cbits(*i++)))
66 ;
67 if (!alph(cbits(*--i)))
68 return (0);
69 wdstart = i++;
70 while (alph(cbits(*i++)))
71 ;
72 hyend = wdend = --i - 1;
73 while (punct(cbits(*i++)))
74 ;
75 if (*--i)
76 return (0);
77 if ((wdend - wdstart - 4) < 0)
78 return (0);
79 hyp = hyptr;
80 *hyp = 0;
81 hyoff = 2;
82 if (!exword() && !suffix())
83 digram();
84 *hyp++ = 0;
85 if (*hyptr)
86 for (j = 1; j; ) {
87 j = 0;
88 for (hyp = hyptr + 1; *hyp != 0; hyp++) {
89 if (*(hyp - 1) > *hyp) {
90 j++;
91 i = *hyp;
92 *hyp = *(hyp - 1);
93 *(hyp - 1) = i;
94 }
95 }
96 }
97
98 return (0);
99 }
100
101
102 int
punct(int i)103 punct(int i)
104 {
105 if (!i || alph(i))
106 return(0);
107 else
108 return(1);
109 }
110
111
112 int
alph(int i)113 alph(int i)
114 {
115 if (i >= 'a' && i <= 'z' || i >= 'A' && i <= 'Z')
116 return(1);
117 else
118 return(0);
119 }
120
121
122 int
caseht()123 caseht()
124 {
125 thresh = THRESH;
126 if (skip())
127 return (0);
128 noscale++;
129 thresh = atoi();
130 noscale = 0;
131
132 return (0);
133 }
134
135
136 int
casehw()137 casehw()
138 {
139 int i, k;
140 char *j;
141 tchar t;
142
143 k = 0;
144 while (!skip()) {
145 if ((j = nexth) >= (hbuf + NHEX - 2))
146 goto full;
147 for (; ; ) {
148 if (ismot(t = getch()))
149 continue;
150 i = cbits(t);
151 if (i == ' ' || i == '\n') {
152 *j++ = 0;
153 nexth = j;
154 *j = 0;
155 if (i == ' ')
156 break;
157 else
158 return (0);
159 }
160 if (i == '-') {
161 k = HY_BIT;
162 continue;
163 }
164 *j++ = maplow(i) | k;
165 k = 0;
166 if (j >= (hbuf + NHEX - 2))
167 goto full;
168 }
169 }
170 return (0);
171 full:
172 errprint(gettext("exception word list full."));
173 *nexth = 0;
174
175 return (0);
176 }
177
178
179 int
exword()180 exword()
181 {
182 tchar *w;
183 char *e;
184 char *save;
185
186 e = hbuf;
187 while (1) {
188 save = e;
189 if (*e == 0)
190 return(0);
191 w = wdstart;
192 while (*e && w <= hyend && (*e & 0177) == maplow(cbits(*w))) {
193 e++;
194 w++;
195 };
196 if (!*e) {
197 if (w-1 == hyend || (w == wdend && maplow(cbits(*w)) == 's')) {
198 w = wdstart;
199 for (e = save; *e; e++) {
200 if (*e & HY_BIT)
201 *hyp++ = w;
202 if (hyp > (hyptr + NHYP - 1))
203 hyp = hyptr + NHYP - 1;
204 w++;
205 }
206 return(1);
207 } else {
208 e++;
209 continue;
210 }
211 } else
212 while (*e++)
213 ;
214 }
215
216 return (0);
217 }
218
219
220 int
suffix()221 suffix()
222 {
223 tchar *w;
224 char *s, *s0;
225 tchar i;
226 extern char *suftab[];
227 extern tchar *chkvow();
228
229 again:
230 if (!alph(cbits(i = cbits(*hyend))))
231 return(0);
232 if (i < 'a')
233 i -= 'A' - 'a';
234 if ((s0 = suftab[i-'a']) == 0)
235 return(0);
236 for (; ; ) {
237 if ((i = *s0 & 017) == 0)
238 return(0);
239 s = s0 + i - 1;
240 w = hyend - 1;
241 while (s > s0 && w >= wdstart && (*s & 0177) == maplow(cbits(*w))) {
242 s--;
243 w--;
244 }
245 if (s == s0)
246 break;
247 s0 += i;
248 }
249 s = s0 + i - 1;
250 w = hyend;
251 if (*s0 & HY_BIT)
252 goto mark;
253 while (s > s0) {
254 w--;
255 if (*s-- & HY_BIT) {
256 mark:
257 hyend = w - 1;
258 if (*s0 & 0100)
259 continue;
260 if (!chkvow(w))
261 return(0);
262 *hyp++ = w;
263 }
264 }
265 if (*s0 & 040)
266 return(0);
267 if (exword())
268 return(1);
269 goto again;
270 }
271
272
273 int
maplow(i)274 maplow(i)
275 int i;
276 {
277 if (ischar(i) && isupper(i))
278 i = tolower(i);
279 return(i);
280 }
281
282
283 int
vowel(i)284 vowel(i)
285 int i;
286 {
287 switch (maplow(i)) {
288 case 'a':
289 case 'e':
290 case 'i':
291 case 'o':
292 case 'u':
293 case 'y':
294 return(1);
295 default:
296 return(0);
297 }
298 }
299
300
chkvow(w)301 tchar *chkvow(w)
302 tchar *w;
303 {
304 while (--w >= wdstart)
305 if (vowel(cbits(*w)))
306 return(w);
307 return(0);
308 }
309
310
311 int
digram()312 digram()
313 {
314 tchar *w;
315 int val;
316 tchar * nhyend, *maxw;
317 int maxval;
318 extern char bxh[26][13], bxxh[26][13], xxh[26][13], xhx[26][13], hxx[26][13];
319
320 again:
321 if (!(w = chkvow(hyend + 1)))
322 return (0);
323 hyend = w;
324 if (!(w = chkvow(hyend)))
325 return (0);
326 nhyend = w;
327 maxval = 0;
328 w--;
329 while ((++w < hyend) && (w < (wdend - 1))) {
330 val = 1;
331 if (w == wdstart)
332 val *= dilook('a', cbits(*w), bxh);
333 else if (w == wdstart + 1)
334 val *= dilook(cbits(*(w-1)), cbits(*w), bxxh);
335 else
336 val *= dilook(cbits(*(w-1)), cbits(*w), xxh);
337 val *= dilook(cbits(*w), cbits(*(w+1)), xhx);
338 val *= dilook(cbits(*(w+1)), cbits(*(w+2)), hxx);
339 if (val > maxval) {
340 maxval = val;
341 maxw = w + 1;
342 }
343 }
344 hyend = nhyend;
345 if (maxval > thresh)
346 *hyp++ = maxw;
347 goto again;
348 }
349
350
351 int
dilook(a,b,t)352 dilook(a, b, t)
353 int a, b;
354 char t[26][13];
355 {
356 int i, j;
357
358 i = t[maplow(a)-'a'][(j = maplow(b)-'a')/2];
359 if (!(j & 01))
360 i >>= 4;
361 return(i & 017);
362 }
363
364
365