mirror of
https://github.com/rhasspy/espeak-ng.git
synced 2026-10-31 13:38:47 +00:00
Staticanalysis (#1457)
Fixes for code smells from cppcheck static code analysis tool. Also includes some function refactoring.
This commit is contained in:
@@ -132,7 +132,6 @@ int utf8_in2(int *c, const char *buf, int backwards)
|
||||
|
||||
int c1;
|
||||
int n_bytes;
|
||||
int ix;
|
||||
static const unsigned char mask[4] = { 0xff, 0x1f, 0x0f, 0x07 };
|
||||
|
||||
// find the start of the next/previous character
|
||||
@@ -155,6 +154,7 @@ int utf8_in2(int *c, const char *buf, int backwards)
|
||||
n_bytes = 3;
|
||||
|
||||
c1 &= mask[n_bytes];
|
||||
int ix;
|
||||
for (ix = 0; ix < n_bytes; ix++)
|
||||
{
|
||||
if (!*buf)
|
||||
@@ -271,9 +271,7 @@ int IsSpace(unsigned int c)
|
||||
int isspace2(unsigned int c)
|
||||
{
|
||||
// can't use isspace() because on Windows, isspace(0xe1) gives TRUE !
|
||||
int c2;
|
||||
|
||||
if (((c2 = (c & 0xff)) == 0) || (c > ' '))
|
||||
if ( ((c & 0xff) == 0) || (c > ' '))
|
||||
return 0;
|
||||
return 1;
|
||||
}
|
||||
@@ -290,10 +288,10 @@ int Read4Bytes(FILE *f)
|
||||
{
|
||||
// Read 4 bytes (least significant first) into a word
|
||||
int ix;
|
||||
unsigned char c;
|
||||
int acc = 0;
|
||||
|
||||
for (ix = 0; ix < 4; ix++) {
|
||||
unsigned char c;
|
||||
c = fgetc(f) & 0xff;
|
||||
acc += (c << (ix*8));
|
||||
}
|
||||
|
||||
@@ -1207,13 +1207,13 @@ static int LoadWavefile(FILE *f, const char *fname)
|
||||
fseek(f, 40, SEEK_SET);
|
||||
|
||||
if ((sr1 != samplerate_native) || (sr2 != sr1*2)) {
|
||||
int fd_temp;
|
||||
char command[sizeof(path_home)+250];
|
||||
|
||||
failed = false;
|
||||
|
||||
#ifdef HAVE_MKSTEMP
|
||||
strcpy(fname_temp, "/tmp/espeakXXXXXX");
|
||||
int fd_temp;
|
||||
if ((fd_temp = mkstemp(fname_temp)) >= 0)
|
||||
close(fd_temp);
|
||||
#else
|
||||
|
||||
@@ -186,11 +186,11 @@ static const char *LookupSpecial(Translator *tr, const char *string, char *text_
|
||||
{
|
||||
unsigned int flags[2];
|
||||
char phonemes[55];
|
||||
char phonemes2[55];
|
||||
char *string1 = (char *)string;
|
||||
|
||||
flags[0] = flags[1] = 0;
|
||||
if (LookupDictList(tr, &string1, phonemes, flags, 0, NULL)) {
|
||||
char phonemes2[55];
|
||||
SetWordStress(tr, phonemes, flags, -1, 0);
|
||||
DecodePhonemes(phonemes, phonemes2);
|
||||
sprintf(text_out, "[\002%s]]", phonemes2);
|
||||
@@ -208,7 +208,6 @@ static const char *LookupCharName(Translator *tr, int c, int only)
|
||||
unsigned int flags[2];
|
||||
char single_letter[24];
|
||||
char phonemes[60];
|
||||
char phonemes2[60];
|
||||
const char *lang_name = NULL;
|
||||
char *string;
|
||||
static char buf[60];
|
||||
@@ -255,6 +254,7 @@ static const char *LookupCharName(Translator *tr, int c, int only)
|
||||
}
|
||||
|
||||
if (phonemes[0]) {
|
||||
char phonemes2[60];
|
||||
if (lang_name) {
|
||||
SetWordStress(translator2, phonemes, flags, -1, 0);
|
||||
DecodePhonemes(phonemes, phonemes2);
|
||||
@@ -277,7 +277,7 @@ static int AnnouncePunctuation(Translator *tr, int c1, int *c2_ptr, char *output
|
||||
// c1: the punctuation character
|
||||
// c2: the following character
|
||||
|
||||
int punct_count;
|
||||
|
||||
const char *punctname = NULL;
|
||||
int soundicon;
|
||||
int attributes;
|
||||
@@ -286,7 +286,6 @@ static int AnnouncePunctuation(Translator *tr, int c1, int *c2_ptr, char *output
|
||||
int len;
|
||||
int bufix1;
|
||||
char buf[200];
|
||||
char buf2[80];
|
||||
char ph_buf[30];
|
||||
|
||||
c2 = *c2_ptr;
|
||||
@@ -307,8 +306,9 @@ static int AnnouncePunctuation(Translator *tr, int c1, int *c2_ptr, char *output
|
||||
if (punctname == NULL)
|
||||
return -1;
|
||||
|
||||
|
||||
if ((*bufix == 0) || (end_clause == 0) || (tr->langopts.param[LOPT_ANNOUNCE_PUNCT] & 2)) {
|
||||
punct_count = 1;
|
||||
int punct_count = 1;
|
||||
while (!Eof() && (c2 == c1) && (c1 != '<')) { // don't eat extra '<', it can miss XML tags
|
||||
punct_count++;
|
||||
c2 = GetC();
|
||||
@@ -324,6 +324,7 @@ static int AnnouncePunctuation(Translator *tr, int c1, int *c2_ptr, char *output
|
||||
if (embedded_value[EMBED_S] < 300)
|
||||
sprintf(buf, "\001+10S"); // Speak punctuation name faster, unless we are already speaking fast. It would upset Sonic SpeedUp
|
||||
|
||||
char buf2[80];
|
||||
while (punct_count-- > 0) {
|
||||
sprintf(buf2, " %s", punctname);
|
||||
strcat(buf, buf2);
|
||||
@@ -381,7 +382,6 @@ int AddNameData(const char *name, int wide)
|
||||
|
||||
int ix;
|
||||
int len;
|
||||
void *vp;
|
||||
|
||||
if (wide) {
|
||||
len = (wcslen((const wchar_t *)name)+1)*sizeof(wchar_t);
|
||||
@@ -391,6 +391,7 @@ int AddNameData(const char *name, int wide)
|
||||
|
||||
if (namedata_ix+len >= n_namedata) {
|
||||
// allocate more space for marker names
|
||||
void *vp;
|
||||
if ((vp = realloc(namedata, namedata_ix+len + 1000)) == NULL)
|
||||
return -1; // failed to allocate, original data is unchanged but ignore this new name
|
||||
// !!! Bug?? If the allocated data shifts position, then pointers given to user application will be invalid
|
||||
@@ -490,7 +491,6 @@ int ReadClause(Translator *tr, char *buf, short *charix, int *charix_top, int n_
|
||||
int c1 = ' '; // current character
|
||||
int c2; // next character
|
||||
int cprev = ' '; // previous character
|
||||
int cprev2 = ' ';
|
||||
int c_next;
|
||||
int parag;
|
||||
int ix = 0;
|
||||
@@ -548,8 +548,7 @@ int ReadClause(Translator *tr, char *buf, short *charix, int *charix_top, int n_
|
||||
return CLAUSE_NONE;
|
||||
}
|
||||
}
|
||||
|
||||
cprev2 = cprev;
|
||||
int cprev2 = cprev;
|
||||
cprev = c1;
|
||||
c1 = c2;
|
||||
|
||||
|
||||
@@ -72,7 +72,6 @@ static espeak_ng_STATUS LoadSoundFile(const char *fname, int index, espeak_ng_ER
|
||||
f = NULL;
|
||||
if ((f = fopen(fname, "rb")) != NULL) {
|
||||
int ix;
|
||||
int fd_temp;
|
||||
int header[3];
|
||||
char command[sizeof(fname2)+sizeof(fname2)+40];
|
||||
|
||||
@@ -92,6 +91,7 @@ static espeak_ng_STATUS LoadSoundFile(const char *fname, int index, espeak_ng_ER
|
||||
|
||||
#ifdef HAVE_MKSTEMP
|
||||
strcpy(fname_temp, "/tmp/espeakXXXXXX");
|
||||
int fd_temp;
|
||||
if ((fd_temp = mkstemp(fname_temp)) >= 0)
|
||||
close(fd_temp);
|
||||
#else
|
||||
|
||||
+22
-21
@@ -132,16 +132,16 @@ static int attrnumber(const wchar_t *pw, int default_value, int type)
|
||||
static int attrcopy_utf8(char *buf, const wchar_t *pw, int len)
|
||||
{
|
||||
// Convert attribute string into utf8, write to buf, and return its utf8 length
|
||||
unsigned int c;
|
||||
int ix = 0;
|
||||
int n;
|
||||
int prev_c = 0;
|
||||
|
||||
if (pw != NULL) {
|
||||
unsigned int c;
|
||||
int prev_c = 0;
|
||||
while ((ix < (len-4)) && ((c = *pw++) != 0)) {
|
||||
if ((c == '"') && (prev_c != '\\'))
|
||||
break; // " indicates end of attribute, unless preceded by backstroke
|
||||
n = utf8_out(c, &buf[ix]);
|
||||
|
||||
int n = utf8_out(c, &buf[ix]);
|
||||
ix += n;
|
||||
prev_c = c;
|
||||
}
|
||||
@@ -208,12 +208,10 @@ static const char *VoiceFromStack(SSML_STACK *ssml_stack, int n_ssml_stack, espe
|
||||
const char *p;
|
||||
SSML_STACK *sp;
|
||||
const char *v_id;
|
||||
int voice_name_specified;
|
||||
int voice_found;
|
||||
espeak_VOICE voice_select;
|
||||
static char voice_name[40];
|
||||
char language[40];
|
||||
char buf[80];
|
||||
|
||||
MAKE_MEM_UNDEFINED(&voice_name, sizeof(voice_name));
|
||||
|
||||
@@ -226,7 +224,7 @@ static const char *VoiceFromStack(SSML_STACK *ssml_stack, int n_ssml_stack, espe
|
||||
|
||||
for (ix = 0; ix < n_ssml_stack; ix++) {
|
||||
sp = &ssml_stack[ix];
|
||||
voice_name_specified = 0;
|
||||
int voice_name_specified = 0;
|
||||
|
||||
if ((sp->voice_name[0] != 0) && (SelectVoiceByName(NULL, sp->voice_name) != NULL)) {
|
||||
voice_name_specified = 1;
|
||||
@@ -270,6 +268,7 @@ static const char *VoiceFromStack(SSML_STACK *ssml_stack, int n_ssml_stack, espe
|
||||
|
||||
if ((strchr(v_id, '+') == NULL) && ((voice_select.gender == ENGENDER_UNKNOWN) || (voice_select.gender == base_voice->gender)) && (base_voice_variant_name[0] != 0)) {
|
||||
// a voice variant has not been selected, use the original voice variant
|
||||
char buf[80];
|
||||
sprintf(buf, "%s+%s", v_id, base_voice_variant_name);
|
||||
strncpy0(voice_name, buf, sizeof(voice_name));
|
||||
return voice_name;
|
||||
@@ -318,12 +317,6 @@ static int GetVoiceAttributes(wchar_t *pw, int tag_type, SSML_STACK *ssml_sp, SS
|
||||
// a voice change.
|
||||
// Returns CLAUSE_TYPE_VOICE_CHANGE if there is a voice change
|
||||
|
||||
const wchar_t *lang;
|
||||
const wchar_t *gender;
|
||||
const wchar_t *name;
|
||||
const wchar_t *age;
|
||||
const wchar_t *variant;
|
||||
int value;
|
||||
const char *new_voice_id;
|
||||
|
||||
static const MNEM_TAB mnem_gender[] = {
|
||||
@@ -338,6 +331,12 @@ static int GetVoiceAttributes(wchar_t *pw, int tag_type, SSML_STACK *ssml_sp, SS
|
||||
if (n_ssml_stack > 1)
|
||||
n_ssml_stack--;
|
||||
} else {
|
||||
const wchar_t *lang;
|
||||
const wchar_t *gender;
|
||||
const wchar_t *name;
|
||||
const wchar_t *age;
|
||||
const wchar_t *variant;
|
||||
|
||||
// add a stack frame if any voice details are specified
|
||||
lang = GetSsmlAttribute(pw, "xml:lang");
|
||||
|
||||
@@ -359,6 +358,8 @@ static int GetVoiceAttributes(wchar_t *pw, int tag_type, SSML_STACK *ssml_sp, SS
|
||||
|
||||
ssml_sp = &ssml_stack[n_ssml_stack++];
|
||||
|
||||
int value;
|
||||
|
||||
attrcopy_utf8(ssml_sp->language, lang, sizeof(ssml_sp->language));
|
||||
attrcopy_utf8(ssml_sp->voice_name, name, sizeof(ssml_sp->voice_name));
|
||||
if ((value = attrnumber(variant, 1, 0)) > 0)
|
||||
@@ -384,7 +385,6 @@ static void ProcessParamStack(char *outbuf, int *outix, int n_param_stack, PARAM
|
||||
// Set the speech parameters from the parameter stack
|
||||
int param;
|
||||
int ix;
|
||||
int value;
|
||||
char buf[20];
|
||||
int new_parameters[N_SPEECH_PARAM];
|
||||
static const char cmd_letter[N_SPEECH_PARAM] = { 0, 'S', 'A', 'P', 'R', 0, 'C', 0, 0, 0, 0, 0, 'F' }; // embedded command letters
|
||||
@@ -400,6 +400,7 @@ static void ProcessParamStack(char *outbuf, int *outix, int n_param_stack, PARAM
|
||||
}
|
||||
|
||||
for (param = 0; param < N_SPEECH_PARAM; param++) {
|
||||
int value;
|
||||
if ((value = new_parameters[param]) != speech_parameters[param]) {
|
||||
buf[0] = 0;
|
||||
|
||||
@@ -471,14 +472,14 @@ static int ReplaceKeyName(char *outbuf, int index, int *outix)
|
||||
{ NULL, 0 }
|
||||
};
|
||||
|
||||
int ix;
|
||||
int letter;
|
||||
char *p;
|
||||
|
||||
p = &outbuf[index];
|
||||
|
||||
if ((letter = LookupMnem(keynames, p)) != 0) {
|
||||
ix = utf8_out(letter, p);
|
||||
int ix;
|
||||
ix = utf8_out(letter, p);
|
||||
*outix = index + ix;
|
||||
return letter;
|
||||
}
|
||||
@@ -488,7 +489,7 @@ static int ReplaceKeyName(char *outbuf, int index, int *outix)
|
||||
static void SetProsodyParameter(int param_type, const wchar_t *attr1, PARAM_STACK *sp, PARAM_STACK *param_stack, int *speech_parameters)
|
||||
{
|
||||
int value;
|
||||
int sign;
|
||||
|
||||
|
||||
static const MNEM_TAB mnem_volume[] = {
|
||||
{ "default", 100 },
|
||||
@@ -539,7 +540,7 @@ static void SetProsodyParameter(int param_type, const wchar_t *attr1, PARAM_STAC
|
||||
// mnemonic specifies a value as a percentage of the base pitch/range/rate/volume
|
||||
sp->parameter[param_type] = (param_stack[0].parameter[param_type] * value)/100;
|
||||
} else {
|
||||
sign = attr_prosody_value(param_type, attr1, &value);
|
||||
int sign = attr_prosody_value(param_type, attr1, &value);
|
||||
|
||||
if (sign == 0)
|
||||
sp->parameter[param_type] = value; // absolute value in Hz
|
||||
@@ -560,7 +561,6 @@ int ProcessSsmlTag(wchar_t *xml_buf, char *outbuf, int *outix, int n_outbuf, con
|
||||
|
||||
unsigned int ix;
|
||||
int index;
|
||||
int c;
|
||||
int tag_type;
|
||||
int value;
|
||||
int value2;
|
||||
@@ -571,7 +571,6 @@ int ProcessSsmlTag(wchar_t *xml_buf, char *outbuf, int *outix, int n_outbuf, con
|
||||
const wchar_t *attr2;
|
||||
const wchar_t *attr3;
|
||||
int terminator;
|
||||
char *uri;
|
||||
int param_type;
|
||||
char tag_name[40];
|
||||
char buf[160];
|
||||
@@ -653,6 +652,7 @@ int ProcessSsmlTag(wchar_t *xml_buf, char *outbuf, int *outix, int n_outbuf, con
|
||||
};
|
||||
|
||||
for (ix = 0; ix < (sizeof(tag_name)-1); ix++) {
|
||||
int c;
|
||||
if (((c = xml_buf[ix]) == 0) || iswspace(c))
|
||||
break;
|
||||
tag_name[ix] = tolower((char)c);
|
||||
@@ -815,11 +815,11 @@ int ProcessSsmlTag(wchar_t *xml_buf, char *outbuf, int *outix, int n_outbuf, con
|
||||
sp = PushParamStack(tag_type, n_param_stack, (PARAM_STACK *)param_stack);
|
||||
|
||||
if ((attr1 = GetSsmlAttribute(px, "src")) != NULL) {
|
||||
char fname[256];
|
||||
attrcopy_utf8(buf, attr1, sizeof(buf));
|
||||
|
||||
if (uri_callback == NULL) {
|
||||
if ((xmlbase != NULL) && (buf[0] != '/')) {
|
||||
char fname[256];
|
||||
sprintf(fname, "%s/%s", xmlbase, buf);
|
||||
index = LoadSoundFile2(fname);
|
||||
} else
|
||||
@@ -832,6 +832,7 @@ int ProcessSsmlTag(wchar_t *xml_buf, char *outbuf, int *outix, int n_outbuf, con
|
||||
}
|
||||
} else {
|
||||
if ((index = AddNameData(buf, 0)) >= 0) {
|
||||
char *uri;
|
||||
uri = &namedata[index];
|
||||
if (uri_callback(1, uri, xmlbase) == 0) {
|
||||
sprintf(buf, "%c%dU", CTRL_EMBEDDED, index);
|
||||
|
||||
@@ -45,7 +45,9 @@
|
||||
#include "speech.h" // for MAKE_MEM_UNDEFINED
|
||||
#include "translateword.h"
|
||||
|
||||
static int CalcWordLength(int source_index, int charix_top, short int *charix, WORD_TAB *words, int word_count);
|
||||
static void CombineFlag(Translator *tr, WORD_TAB *wtab, char *word, int *flags, unsigned char *p, char *word_phonemes);
|
||||
static void SwitchLanguage(char *word, char *word_phonemes);
|
||||
|
||||
Translator *translator = NULL; // the main translator
|
||||
Translator *translator2 = NULL; // secondary translator for certain words
|
||||
@@ -143,8 +145,7 @@ int TranslateWord(Translator *tr, char *word_start, WORD_TAB *wtab, char *word_o
|
||||
{
|
||||
char words_phonemes[N_WORD_PHONEMES]; // a word translated into phoneme codes
|
||||
char *phonemes = words_phonemes;
|
||||
int available = N_WORD_PHONEMES;
|
||||
bool first_word = true;
|
||||
|
||||
|
||||
int flags = TranslateWord3(tr, word_start, wtab, word_out, &any_stressed_words, current_alphabet, word_phonemes, sizeof(word_phonemes));
|
||||
if (flags & FLAG_TEXTMODE && word_out) {
|
||||
@@ -156,6 +157,8 @@ int TranslateWord(Translator *tr, char *word_start, WORD_TAB *wtab, char *word_o
|
||||
strcpy(word+2, word_out);
|
||||
word_out = word+2;
|
||||
|
||||
bool first_word = true;
|
||||
int available = N_WORD_PHONEMES;
|
||||
while (*word_out && available > 1) {
|
||||
int c;
|
||||
utf8_in(&c, word_out);
|
||||
@@ -232,11 +235,9 @@ static void Word_EmbeddedCmd()
|
||||
{
|
||||
// Process embedded commands for emphasis, sayas, and break
|
||||
int embedded_cmd;
|
||||
int value;
|
||||
|
||||
do {
|
||||
embedded_cmd = embedded_list[embedded_read++];
|
||||
value = embedded_cmd >> 8;
|
||||
int value = embedded_cmd >> 8;
|
||||
|
||||
switch (embedded_cmd & 0x1f)
|
||||
{
|
||||
@@ -318,11 +319,8 @@ static int TranslateWord2(Translator *tr, char *word, WORD_TAB *wtab, int pre_pa
|
||||
bool first_phoneme = true;
|
||||
int source_ix;
|
||||
int len;
|
||||
int ix;
|
||||
const char *new_language;
|
||||
int bad_phoneme;
|
||||
int word_flags;
|
||||
int word_copy_len;
|
||||
char word_copy[N_WORD_BYTES+1];
|
||||
char word_replaced[N_WORD_BYTES+1];
|
||||
char old_dictionary_name[40];
|
||||
@@ -347,12 +345,8 @@ static int TranslateWord2(Translator *tr, char *word, WORD_TAB *wtab, int pre_pa
|
||||
if ((word[0] == 0) || (word_flags & FLAG_DELETE_WORD)) {
|
||||
// nothing to translate. Add a dummy phoneme to carry any embedded commands
|
||||
if (embedded_flag) {
|
||||
ph_list2[n_ph_list2].phcode = phonEND_WORD;
|
||||
ph_list2[n_ph_list2].stresslevel = 0;
|
||||
SetPlist2(&ph_list2[n_ph_list2], phonEND_WORD);
|
||||
ph_list2[n_ph_list2].wordstress = 0;
|
||||
ph_list2[n_ph_list2].tone_ph = 0;
|
||||
ph_list2[n_ph_list2].synthflags = embedded_flag;
|
||||
ph_list2[n_ph_list2].sourceix = 0;
|
||||
n_ph_list2++;
|
||||
embedded_flag = 0;
|
||||
}
|
||||
@@ -391,32 +385,18 @@ static int TranslateWord2(Translator *tr, char *word, WORD_TAB *wtab, int pre_pa
|
||||
p = (unsigned char *)word_phonemes;
|
||||
if (word_flags & FLAG_PHONEMES) {
|
||||
// The input is in phoneme mnemonics, not language text
|
||||
int c1;
|
||||
char lang_name[12];
|
||||
|
||||
if (memcmp(word, "_^_", 3) == 0) {
|
||||
// switch languages
|
||||
word += 3;
|
||||
for (ix = 0;;) {
|
||||
c1 = *word++;
|
||||
if ((c1 == ' ') || (c1 == 0))
|
||||
break;
|
||||
lang_name[ix++] = tolower(c1);
|
||||
}
|
||||
lang_name[ix] = 0;
|
||||
|
||||
if ((ix = LookupPhonemeTable(lang_name)) > 0) {
|
||||
SelectPhonemeTable(ix);
|
||||
word_phonemes[0] = phonSWITCH;
|
||||
word_phonemes[1] = ix;
|
||||
word_phonemes[2] = 0;
|
||||
}
|
||||
} else
|
||||
SwitchLanguage(word, word_phonemes);
|
||||
} else {
|
||||
EncodePhonemes(word, word_phonemes, &bad_phoneme);
|
||||
}
|
||||
|
||||
flags = FLAG_FOUND;
|
||||
} else {
|
||||
int c2;
|
||||
ix = 0;
|
||||
int ix = 0;
|
||||
int word_copy_len;
|
||||
while (((c2 = word_copy[ix] = word[ix]) != ' ') && (c2 != 0) && (ix < N_WORD_BYTES)) ix++;
|
||||
word_copy_len = ix;
|
||||
|
||||
@@ -440,6 +420,7 @@ static int TranslateWord2(Translator *tr, char *word, WORD_TAB *wtab, int pre_pa
|
||||
// this word uses a different language
|
||||
memcpy(word, word_copy, word_copy_len);
|
||||
|
||||
const char *new_language;
|
||||
new_language = (char *)(&p[1]);
|
||||
if (new_language[0] == 0)
|
||||
new_language = ESPEAKNG_DEFAULT_VOICE;
|
||||
@@ -853,9 +834,6 @@ static int TranslateChar(Translator *tr, char *ptr, int prev_in, unsigned int c,
|
||||
// To allow language specific examination and replacement of characters
|
||||
|
||||
int code;
|
||||
int initial;
|
||||
int medial;
|
||||
int final;
|
||||
int next2;
|
||||
|
||||
static const unsigned char hangul_compatibility[0x34] = {
|
||||
@@ -871,9 +849,9 @@ static int TranslateChar(Translator *tr, char *ptr, int prev_in, unsigned int c,
|
||||
// check for Korean Hangul letters
|
||||
if (((code = c - 0xac00) >= 0) && (c <= 0xd7af)) {
|
||||
// break a syllable hangul into 2 or 3 individual jamo
|
||||
initial = (code/28)/21;
|
||||
medial = (code/28) % 21;
|
||||
final = code % 28;
|
||||
int initial = (code/28)/21;
|
||||
int medial = (code/28) % 21;
|
||||
int final = code % 28;
|
||||
|
||||
if (initial == 11) {
|
||||
// null initial
|
||||
@@ -922,13 +900,12 @@ static const char *UCase_ga[] = { "bp", "bhf", "dt", "gc", "hA", "mb", "nd", "ng
|
||||
|
||||
static int UpperCaseInWord(Translator *tr, char *word, int c)
|
||||
{
|
||||
int ix;
|
||||
int len;
|
||||
const char *p;
|
||||
|
||||
if (tr->translator_name == L('g', 'a')) {
|
||||
// Irish
|
||||
int ix;
|
||||
const char *p;
|
||||
|
||||
for (ix = 0;; ix++) {
|
||||
int len;
|
||||
if ((p = UCase_ga[ix]) == NULL)
|
||||
break;
|
||||
|
||||
@@ -948,11 +925,9 @@ void TranslateClause(Translator *tr, int *tone_out, char **voice_change)
|
||||
int c;
|
||||
int cc = 0;
|
||||
unsigned int source_index = 0;
|
||||
unsigned int prev_source_index = 0;
|
||||
int source_index_word = 0;
|
||||
int prev_in;
|
||||
int prev_out = ' ';
|
||||
int prev_out2;
|
||||
int prev_in_save = 0;
|
||||
int next_in;
|
||||
int next_in_nbytes;
|
||||
@@ -1082,16 +1057,9 @@ void TranslateClause(Translator *tr, int *tone_out, char **voice_change)
|
||||
words[0].start = ix;
|
||||
words[0].flags = 0;
|
||||
|
||||
for (j = 0; charix[j] <= 0; j++) ;
|
||||
words[0].sourceix = charix[j];
|
||||
k = 0;
|
||||
while (charix[j] != 0) {
|
||||
// count the number of characters (excluding multibyte continuation bytes)
|
||||
if (charix[j++] != -1)
|
||||
k++;
|
||||
}
|
||||
words[0].length = k;
|
||||
words[0].length = CalcWordLength(source_index, charix_top, charix, words, 0);
|
||||
|
||||
int prev_out2;
|
||||
while (!finished && (ix < (int)sizeof(sbuf) - 1)) {
|
||||
prev_out2 = prev_out;
|
||||
utf8_in2(&prev_out, &sbuf[ix-1], 1);
|
||||
@@ -1107,7 +1075,7 @@ void TranslateClause(Translator *tr, int *tone_out, char **voice_change)
|
||||
} else if (source_index > 0)
|
||||
utf8_in2(&prev_in, &source[source_index-1], 1);
|
||||
|
||||
prev_source_index = source_index;
|
||||
unsigned int prev_source_index = source_index;
|
||||
|
||||
if (char_inserted) {
|
||||
c = char_inserted;
|
||||
@@ -1467,16 +1435,7 @@ void TranslateClause(Translator *tr, int *tone_out, char **voice_change)
|
||||
words[word_count].start = ix;
|
||||
words[word_count].flags = 0;
|
||||
|
||||
for (j = source_index; j < charix_top && charix[j] <= 0; j++) // skip blanks
|
||||
;
|
||||
words[word_count].sourceix = charix[j];
|
||||
k = 0;
|
||||
while (charix[j] != 0) {
|
||||
// count the number of characters (excluding multibyte continuation bytes)
|
||||
if (charix[j++] != -1)
|
||||
k++;
|
||||
}
|
||||
words[word_count].length = k;
|
||||
words[word_count].length = CalcWordLength(source_index, charix_top, charix, words, word_count);
|
||||
|
||||
word_flags = next_word_flags;
|
||||
next_word_flags = 0;
|
||||
@@ -1530,7 +1489,6 @@ void TranslateClause(Translator *tr, int *tone_out, char **voice_change)
|
||||
int c_temp;
|
||||
char *pn;
|
||||
char *pw;
|
||||
int nw;
|
||||
char number_buf[150];
|
||||
WORD_TAB num_wtab[50]; // copy of 'words', when splitting numbers into parts
|
||||
|
||||
@@ -1575,12 +1533,13 @@ void TranslateClause(Translator *tr, int *tone_out, char **voice_change)
|
||||
|
||||
if (n_digits > 4 && n_digits <= 32) {
|
||||
// word is entirely digits, insert commas and break into 3 digit "words"
|
||||
int nw = 0;
|
||||
|
||||
number_buf[0] = ' ';
|
||||
number_buf[1] = ' ';
|
||||
number_buf[2] = ' ';
|
||||
pn = &number_buf[3];
|
||||
nx = n_digits;
|
||||
nw = 0;
|
||||
|
||||
if ((n_digits > tr->langopts.max_digits) || (word[0] == '0'))
|
||||
words[ix].flags |= FLAG_INDIVIDUAL_DIGITS;
|
||||
@@ -1711,6 +1670,20 @@ void TranslateClause(Translator *tr, int *tone_out, char **voice_change)
|
||||
}
|
||||
}
|
||||
|
||||
static int CalcWordLength(int source_index, int charix_top, short int *charix, WORD_TAB *words, int word_count) {
|
||||
int j;
|
||||
int k;
|
||||
|
||||
for (j = source_index; j < charix_top && charix[j] <= 0; j++); // skip blanks
|
||||
words[word_count].sourceix = charix[j];
|
||||
k = 0;
|
||||
while (charix[j] != 0) {
|
||||
// count the number of characters (excluding multibyte continuation bytes)
|
||||
if (charix[j++] != -1)
|
||||
k++;
|
||||
}
|
||||
return k;
|
||||
}
|
||||
|
||||
static void CombineFlag(Translator *tr, WORD_TAB *wtab, char *word, int *flags, unsigned char *p, char *word_phonemes) {
|
||||
// combine a preposition with the following word
|
||||
@@ -1775,6 +1748,29 @@ static void CombineFlag(Translator *tr, WORD_TAB *wtab, char *word, int *flags,
|
||||
}
|
||||
}
|
||||
|
||||
static void SwitchLanguage(char *word, char *word_phonemes) {
|
||||
char lang_name[12];
|
||||
int ix;
|
||||
|
||||
word += 3;
|
||||
|
||||
for (ix = 0;;) {
|
||||
int c1;
|
||||
c1 = *word++;
|
||||
if ((c1 == ' ') || (c1 == 0))
|
||||
break;
|
||||
lang_name[ix++] = tolower(c1);
|
||||
}
|
||||
lang_name[ix] = 0;
|
||||
|
||||
if ((ix = LookupPhonemeTable(lang_name)) > 0) {
|
||||
SelectPhonemeTable(ix);
|
||||
word_phonemes[0] = phonSWITCH;
|
||||
word_phonemes[1] = ix;
|
||||
word_phonemes[2] = 0;
|
||||
}
|
||||
}
|
||||
|
||||
void InitText(int control)
|
||||
{
|
||||
count_sentences = 0;
|
||||
@@ -1797,4 +1793,4 @@ void InitText(int control)
|
||||
|
||||
if ((control & espeakKEEP_NAMEDATA) == 0)
|
||||
InitNamedata();
|
||||
}
|
||||
}
|
||||
@@ -674,16 +674,15 @@ int TranslateWord3(Translator *tr, char *word_start, WORD_TAB *wtab, char *word_
|
||||
void ApplySpecialAttribute2(Translator *tr, char *phonemes, int dict_flags)
|
||||
{
|
||||
// apply after the translation is complete
|
||||
|
||||
int ix;
|
||||
int len;
|
||||
char *p;
|
||||
|
||||
|
||||
len = strlen(phonemes);
|
||||
|
||||
if (tr->langopts.param[LOPT_ALT] & 2) {
|
||||
for (ix = 0; ix < (len-1); ix++) {
|
||||
for (int ix = 0; ix < (len-1); ix++) {
|
||||
if (phonemes[ix] == phonSTRESS_P) {
|
||||
char *p;
|
||||
p = &phonemes[ix+1];
|
||||
if ((dict_flags & FLAG_ALT2_TRANS) != 0) {
|
||||
if (*p == PhonemeCode('E'))
|
||||
@@ -795,18 +794,11 @@ static int TranslateLetter(Translator *tr, char *word, char *phonemes, int contr
|
||||
int n_bytes;
|
||||
int letter;
|
||||
int len;
|
||||
int ix;
|
||||
int c;
|
||||
char *p2;
|
||||
char *pbuf;
|
||||
const char *modifier;
|
||||
ALPHABET *alphabet;
|
||||
int al_offset;
|
||||
int al_flags;
|
||||
int language;
|
||||
int number;
|
||||
int phontab_1;
|
||||
int speak_letter_number;
|
||||
char capital[30];
|
||||
char ph_buf[80];
|
||||
char ph_buf2[80];
|
||||
@@ -834,8 +826,11 @@ static int TranslateLetter(Translator *tr, char *word, char *phonemes, int contr
|
||||
|
||||
if (ph_buf[0] == 0) {
|
||||
// is this a subscript or superscript letter ?
|
||||
int c;
|
||||
if ((c = IsSuperscript(letter)) != 0) {
|
||||
letter = c & 0x3fff;
|
||||
|
||||
const char *modifier;
|
||||
if ((control & 4 ) && ((modifier = modifiers[c >> 14]) != NULL)) {
|
||||
// don't say "superscript" during normal text reading
|
||||
Lookup(tr, modifier, capital);
|
||||
@@ -909,6 +904,7 @@ static int TranslateLetter(Translator *tr, char *word, char *phonemes, int contr
|
||||
// caution: SetWordStress() etc don't expect phonSWITCH + phoneme table number
|
||||
|
||||
if (ph_buf[0] == 0) {
|
||||
int language;
|
||||
if ((al_offset != 0) && (al_offset == translator->langopts.alt_alphabet))
|
||||
language = translator->langopts.alt_alphabet_lang;
|
||||
else if ((alphabet != NULL) && (alphabet->language != 0) && !(al_flags & AL_NOT_LETTERS))
|
||||
@@ -918,19 +914,21 @@ static int TranslateLetter(Translator *tr, char *word, char *phonemes, int contr
|
||||
|
||||
if ((language != tr->translator_name) || (language == L('k', 'o'))) {
|
||||
char *p3;
|
||||
int initial, code;
|
||||
//int initial, code;
|
||||
char hangul_buf[12];
|
||||
|
||||
// speak in the language for this alphabet (or English)
|
||||
ph_buf[2] = SetTranslator3(WordToString2(language));
|
||||
|
||||
if (translator3 != NULL) {
|
||||
int code;
|
||||
if (((code = letter - 0xac00) >= 0) && (letter <= 0xd7af)) {
|
||||
// Special case for Korean letters.
|
||||
// break a syllable hangul into 2 or 3 individual jamo
|
||||
|
||||
hangul_buf[0] = ' ';
|
||||
p3 = &hangul_buf[1];
|
||||
int initial;
|
||||
if ((initial = (code/28)/21) != 11) {
|
||||
p3 += utf8_out(initial + 0x1100, p3);
|
||||
}
|
||||
@@ -966,51 +964,50 @@ static int TranslateLetter(Translator *tr, char *word, char *phonemes, int contr
|
||||
|
||||
if (ph_buf[0] == 0) {
|
||||
// character name not found
|
||||
int speak_letter_number = 1;
|
||||
if (!(al_flags & AL_NO_SYMBOL)) {
|
||||
if (iswalpha(letter))
|
||||
Lookup(translator, "_?A", ph_buf);
|
||||
|
||||
if (ph_buf[0] == 0) {
|
||||
speak_letter_number = 1;
|
||||
if (!(al_flags & AL_NO_SYMBOL)) {
|
||||
if (iswalpha(letter))
|
||||
Lookup(translator, "_?A", ph_buf);
|
||||
if ((ph_buf[0] == 0) && !iswspace(letter))
|
||||
Lookup(translator, "_??", ph_buf);
|
||||
|
||||
if ((ph_buf[0] == 0) && !iswspace(letter))
|
||||
Lookup(translator, "_??", ph_buf);
|
||||
if (ph_buf[0] == 0)
|
||||
EncodePhonemes("l'et@", ph_buf, NULL);
|
||||
}
|
||||
|
||||
if (ph_buf[0] == 0)
|
||||
EncodePhonemes("l'et@", ph_buf, NULL);
|
||||
}
|
||||
if (!(control & 4) && (al_flags & AL_NOT_CODE)) {
|
||||
// don't speak the character code number, unless we want full details of this character
|
||||
speak_letter_number = 0;
|
||||
}
|
||||
|
||||
if (!(control & 4) && (al_flags & AL_NOT_CODE)) {
|
||||
// don't speak the character code number, unless we want full details of this character
|
||||
speak_letter_number = 0;
|
||||
}
|
||||
|
||||
if (speak_letter_number) {
|
||||
if (al_offset == 0x2800) {
|
||||
// braille dots symbol, list the numbered dots
|
||||
p2 = hexbuf;
|
||||
for (ix = 0; ix < 8; ix++) {
|
||||
if (letter & (1 << ix))
|
||||
*p2++ = '1'+ix;
|
||||
}
|
||||
*p2 = 0;
|
||||
} else {
|
||||
// speak the hexadecimal number of the character code
|
||||
sprintf(hexbuf, "%x", letter);
|
||||
if (speak_letter_number) {
|
||||
char *p2;
|
||||
if (al_offset == 0x2800) {
|
||||
// braille dots symbol, list the numbered dots
|
||||
p2 = hexbuf;
|
||||
for (int ix = 0; ix < 8; ix++) {
|
||||
if (letter & (1 << ix))
|
||||
*p2++ = '1'+ix;
|
||||
}
|
||||
|
||||
pbuf = ph_buf;
|
||||
for (p2 = hexbuf; *p2 != 0; p2++) {
|
||||
pbuf += strlen(pbuf);
|
||||
*pbuf++ = phonPAUSE_VSHORT;
|
||||
LookupLetter(translator, *p2, 0, pbuf, 1);
|
||||
if (((pbuf[0] == 0) || (pbuf[0] == phonSWITCH)) && (*p2 >= 'a')) {
|
||||
// This language has no translation for 'a' to 'f', speak English names using base phonemes
|
||||
EncodePhonemes(hex_letters[*p2 - 'a'], pbuf, NULL);
|
||||
}
|
||||
}
|
||||
strcat(pbuf, pause_string);
|
||||
*p2 = 0;
|
||||
} else {
|
||||
// speak the hexadecimal number of the character code
|
||||
sprintf(hexbuf, "%x", letter);
|
||||
}
|
||||
|
||||
char *pbuf;
|
||||
pbuf = ph_buf;
|
||||
for (p2 = hexbuf; *p2 != 0; p2++) {
|
||||
pbuf += strlen(pbuf);
|
||||
*pbuf++ = phonPAUSE_VSHORT;
|
||||
LookupLetter(translator, *p2, 0, pbuf, 1);
|
||||
if (((pbuf[0] == 0) || (pbuf[0] == phonSWITCH)) && (*p2 >= 'a')) {
|
||||
// This language has no translation for 'a' to 'f', speak English names using base phonemes
|
||||
EncodePhonemes(hex_letters[*p2 - 'a'], pbuf, NULL);
|
||||
}
|
||||
}
|
||||
strcat(pbuf, pause_string);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1049,8 +1046,6 @@ static int CheckDottedAbbrev(char *word1)
|
||||
{
|
||||
int wc;
|
||||
int count = 0;
|
||||
int nbytes;
|
||||
int ok;
|
||||
int ix;
|
||||
char *word;
|
||||
char *wbuf;
|
||||
@@ -1060,8 +1055,8 @@ static int CheckDottedAbbrev(char *word1)
|
||||
wbuf = word_buf;
|
||||
|
||||
for (;;) {
|
||||
ok = 0;
|
||||
nbytes = utf8_in(&wc, word);
|
||||
int ok = 0;
|
||||
int nbytes = utf8_in(&wc, word);
|
||||
if ((word[nbytes] == ' ') && IsAlpha(wc)) {
|
||||
if (word[nbytes+1] == '.') {
|
||||
if (word[nbytes+2] == ' ')
|
||||
|
||||
Reference in New Issue
Block a user