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/apply_stress.h"
22 
23 #include <stdio.h>
24 #include <string.h>
25 
26 #include "en/letter_to_sound/stresstables.h"
27 
28 
29 
30 namespace {
31 
32 int stress_suffix(const char* orthography, int* type);
33 int light(const char* sb);
34 int prefix(const char* orthography);
35 
36 
37 
38 /******************************************************************************
39 *
40 *	function:	stress_suffix
41 *
42 *	purpose:
43 *
44 ******************************************************************************/
45 int
stress_suffix(const char * orthography,int * type)46 stress_suffix(const char* orthography, int* type)
47 {
48 	int t = 0, a, c;
49 	const char* b;
50 
51 	c = strlen(orthography);
52 	while (suffix_list[t].suff) {
53 		b = suffix_list[t].suff;
54 		a = strlen(b);
55 		if ((a <= c) && !strcmp(b, orthography + c - a)) {
56 			*type = suffix_list[t].type;
57 			return suffix_list[t].sylls;
58 		}
59 		t++;
60 	}
61 	return 0;
62 }
63 
64 /******************************************************************************
65 *
66 *	function:	light
67 *
68 *	purpose:	Determine if a syllable is light.
69 *
70 ******************************************************************************/
71 int
light(const char * sb)72 light(const char* sb)
73 {
74 	while (!isvowel(*sb)) {
75 		sb++;
76 	}
77 
78 	while (isvowel(*sb) || (*sb == '_') || (*sb == '.')) {
79 		sb++;
80 	}
81 
82 	if (!*sb) {
83 		return 1;
84 	}
85 
86 	while ((*sb != '_') && (*sb != '.') && *sb) {
87 		sb++;
88 	}
89 
90 	if (!*sb) {
91 		return 1;
92 	}
93 
94 	while (((*sb == '_') || (*sb == '.')) && *sb) {
95 		sb++;
96 	}
97 
98 	if (!*sb) {
99 		return 1;
100 	}
101 
102 	return isvowel(*sb);
103 }
104 
105 /******************************************************************************
106 *
107 *	function:	prefix
108 *
109 *	purpose:
110 *
111 ******************************************************************************/
112 int
prefix(const char * orthography)113 prefix(const char* orthography)
114 {
115 	int t = 0, l, m;
116 	const char* a;
117 
118 	m = strlen(orthography);
119 	while ( (a = prefices[t++]) ) {
120 		if (((l = strlen(a)) <= m) && !strncmp(a, orthography, l)) {
121 			return 1;
122 		}
123 	}
124 
125 	return 0;
126 }
127 
128 } /* namespace */
129 
130 //==============================================================================
131 
132 namespace GS {
133 namespace En {
134 
135 /******************************************************************************
136 *
137 *	function:	apply_stress
138 *
139 *	purpose:	Find all syllables and make an array of pointers to
140 *                       them.  Mark each as either weak or strong in a separate
141 *                       array;  use the table of stress-affecting affices to
142 *                       find any.  If none, look for stress-repellent prefices.
143 *                       Decide which syllable gets the stress marker;  insert
144 *                       it at the pointer to that syllable.  Returns nonzero
145 *                       if an error occurred.
146 *
147 ******************************************************************************/
148 int
apply_stress(char * buffer,const char * orthography)149 apply_stress(char* buffer, const char* orthography)
150 {
151 	char* syll_array[MAX_SYLLS];
152 	char* spt;
153 	char ich, temp = '\0';
154 	int index;
155 	int type, t, syll = (-1);
156 	int last_was_break = 1;
157 
158 	for (index = 0, spt = buffer; *spt; spt++) {
159 		if (last_was_break) {
160 			last_was_break = 0;
161 			syll_array[index++] = spt;
162 		}
163 		if (*spt == '.') {
164 			last_was_break = 1;
165 		}
166 	}
167 
168 	if (index > MAX_SYLLS) {
169 		return 1;
170 	}
171 
172 	/*  RETURNS SYLLABLE NO. (FROM THE END) THAT IS THE START OF A STRESS-AFFECTING
173 	SUFFIX, 0 IF NONE; AND TYPE  */
174 	t = stress_suffix(orthography, &type);
175 	if (t) {
176 		if (type == AUTOSTRESSED) {
177 			syll = index - t;
178 		} else if (type == PRESTRESS1) {
179 			syll = index - t - 1;
180 		} else if (type == PRESTRESS2) {
181 			syll = index - t - 2;
182 		} else if (type == PRESTRESS3) {
183 			syll = index - t - 1;
184 			if (syll >= 0 && light(syll_array[syll])) {
185 				syll--;
186 			}
187 		} else if (type == NEUTRAL) {
188 			index -= t;
189 		}
190 	}
191 
192 	if ((syll < 0) && prefix(orthography) && (index >= 2)) {
193 		syll = 1;
194 	}
195 
196 	if (syll < 0) {		/* if as yet unsuccessful */
197 		syll = index - 2;
198 		if (syll < 0) {
199 			syll = 0;
200 		}
201 		if (light(syll_array[syll])) {
202 			syll--;
203 		}
204 	}
205 
206 	if (syll < 0) {
207 		syll = 0;
208 	}
209 
210 	spt = syll_array[syll];
211 	/*  strcpy(spt+1,spt); */
212 	ich = '\'';
213 	while (ich) {
214 		temp = *spt;
215 		*spt = ich;
216 		ich = temp;
217 		spt++;
218 	}
219 	*spt = '\0';
220 	return 0;
221 }
222 
223 } /* namespace En */
224 } /* namespace GS */
225