1 /***************************************************************************
2  *  Copyright 1991, 1992, 1993, 1994, 1995, 1996, 2001, 2002               *
3  *    David R. Hill, Leonard Manzara, Craig Schock                         *
4  *                                                                         *
5  *  This program is free software: you can redistribute it and/or modify   *
6  *  it under the terms of the GNU General Public License as published by   *
7  *  the Free Software Foundation, either version 3 of the License, or      *
8  *  (at your option) any later version.                                    *
9  *                                                                         *
10  *  This program is distributed in the hope that it will be useful,        *
11  *  but WITHOUT ANY WARRANTY; without even the implied warranty of         *
12  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the          *
13  *  GNU General Public License for more details.                           *
14  *                                                                         *
15  *  You should have received a copy of the GNU General Public License      *
16  *  along with this program.  If not, see <http://www.gnu.org/licenses/>.  *
17  ***************************************************************************/
18 // 2014-09
19 // This file was copied from Gnuspeech and modified by Marcelo Y. Matuda.
20 
21 #include "en/letter_to_sound/mark_final_e.h"
22 
23 #include "en/letter_to_sound/vowel_before.h"
24 #include "en/letter_to_sound/ends_with.h"
25 #include "en/letter_to_sound/member.h"
26 #include "en/letter_to_sound/insert_mark.h"
27 #include "en/letter_to_sound/suffix.h"
28 
29 
30 
31 namespace {
32 
33 /*  GLOBAL VARIABLES (LOCAL TO THIS FILE)  ***********************************/
34 const char* suffix_list_1 =
35 	"elba/ylba/de/ne/re/yre/tse/ye/gni/ssel/yl/tnem/ssen/ro/luf/";
36 
37 const char* suffix_list_2 =
38 	"ci/laci/";
39 
40 } /* namespace */
41 
42 //==============================================================================
43 
44 namespace GS {
45 namespace En {
46 
47 /******************************************************************************
48 *
49 *	function:	mark_final_e
50 *
51 *	purpose:
52 *
53 *
54 *       arguments:      in, eow
55 *
56 *	internal
57 *	functions:	vowel_before, ends_with, member, insert_mark, suffix
58 *
59 *	library
60 *	functions:	none
61 *
62 ******************************************************************************/
63 int
mark_final_e(char * in,char ** eow)64 mark_final_e(char *in, char **eow)
65 {
66 	char* end = *eow;
67 	char* prior_char;
68 	char* temp;
69 
70 	/*  McIlroy 4.3 - a)  */
71 	/*  IF ONLY ONE VOWEL IN WORD && IT IS AN 'e' AT THE END  */
72 	if ((*(end - 1) == 'e') && !vowel_before(in, end - 1)) {
73 		*(end - 1) = 'E';
74 		return(1);
75 	}
76 
77 	/*  McIlroy 4.3 - g)  */
78 	/*  LOOK FOR #^[aeiouy]* [aeiouy] ^[aeiouywx] [al | le | re | us | y]  */
79 	/*  IF FOUND CHANGE       ------   TO UPPER CASE */
80 	if ( (prior_char = (char *)ends_with(in, end, "#la/#el/#er/#su/#y/")) ) {
81 		if (!member(*prior_char, "aeiouywx")) {
82 			if (member(*--prior_char, "aeiouy")) {
83 				if (!vowel_before(in, prior_char)) {
84 					*prior_char &= 0xdf;
85 				}
86 			}
87 		}
88 	}
89 
90 	/* McIlroy 4.3 - a)  */
91 	temp = prior_char = end - 1;
92 	while ( (prior_char = (char *)suffix(in, prior_char, suffix_list_1)) ) {
93 		insert_mark(&end, prior_char);
94 		temp = prior_char;
95 	}
96 
97 	prior_char = temp;
98 	if ( (prior_char = (char *)suffix(in, prior_char, suffix_list_2)) ) {
99 		insert_mark(&end, prior_char);
100 		*eow = end;
101 		return(0);
102 	}
103 
104 	prior_char = temp;
105 	if ( (prior_char = (char *)suffix(in, prior_char, "e/")) ) {
106 		if (prior_char[2] != 'e') {
107 			if (prior_char[2] != '|')
108 				insert_mark(&end, prior_char);
109 		}
110 		else {
111 			*eow = end;
112 			return(0);
113 		}
114 	}
115 	else
116 		prior_char = temp;
117 
118 	/*  McIlroy 4.3 -b)  */
119 	if (((*(prior_char + 1) == '|') && (member(*(prior_char + 2), "aeio")))
120 			|| (member(*(prior_char + 1), "aeio"))) {
121 		if (!member(*prior_char, "aeiouywx")) {
122 			if (member(*(prior_char - 1), "aeiouy")) {
123 				if (!member(*(prior_char - 2), "aeo")) {
124 					*(prior_char - 1) &= 0xdf;
125 				}
126 			}
127 		}
128 
129 		/*  McIlroy 4.3 -c)  */
130 		if ((*prior_char == 'h') && (*(prior_char - 1) == 't')) {
131 			if (member(*(prior_char - 2), "aeiouy")) {
132 				if (!member(*(prior_char - 3), "aeo"))
133 					*(prior_char - 2) &= 0xdf;
134 				*(prior_char - 1) = 'T';
135 				*prior_char = 'H';
136 			}
137 		}
138 	}
139 
140 	/*  McIlroy 4.3 - d)  */
141 	if ((member(*prior_char, "iuy")) && !vowel_before(in, prior_char)) {
142 		*prior_char &= 0xdf;
143 		*eow = end;
144 		return(0);
145 	}
146 
147 	/*  McIlroy 4.3 - e)  */
148 	if ((*(prior_char + 1) == 'e') && (member(*prior_char, "cg"))) {
149 		temp = (char *)vowel_before(in, prior_char);
150 		if (vowel_before(in, temp)) {
151 			*temp |= 0x20;
152 			*eow = end;
153 			return(0);
154 		}
155 	}
156 
157 	/*  McIlroy 4.3 - f)  */
158 	if ((*prior_char == 'l') && (*(prior_char - 1) == 'E'))
159 		*(prior_char - 1) |= 0x20;
160 	*eow = end;
161 
162 	return(0);
163 }
164 
165 } /* namespace En */
166 } /* namespace GS */
167