Browse Source

Staticanalysis (#1457)

Fixes for code smells from cppcheck static code analysis tool.

Also includes some function refactoring.
master
Juho Hiltunen 2 years ago
parent
commit
5db96bd845
No account linked to committer's email address

+ 3
- 5
src/libespeak-ng/common.c View File



int c1; int c1;
int n_bytes; int n_bytes;
int ix;
static const unsigned char mask[4] = { 0xff, 0x1f, 0x0f, 0x07 }; static const unsigned char mask[4] = { 0xff, 0x1f, 0x0f, 0x07 };


// find the start of the next/previous character // find the start of the next/previous character
n_bytes = 3; n_bytes = 3;


c1 &= mask[n_bytes]; c1 &= mask[n_bytes];
int ix;
for (ix = 0; ix < n_bytes; ix++) for (ix = 0; ix < n_bytes; ix++)
{ {
if (!*buf) if (!*buf)
int isspace2(unsigned int c) int isspace2(unsigned int c)
{ {
// can't use isspace() because on Windows, isspace(0xe1) gives TRUE ! // 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 0;
return 1; return 1;
} }
{ {
// Read 4 bytes (least significant first) into a word // Read 4 bytes (least significant first) into a word
int ix; int ix;
unsigned char c;
int acc = 0; int acc = 0;


for (ix = 0; ix < 4; ix++) { for (ix = 0; ix < 4; ix++) {
unsigned char c;
c = fgetc(f) & 0xff; c = fgetc(f) & 0xff;
acc += (c << (ix*8)); acc += (c << (ix*8));
} }

+ 1
- 1
src/libespeak-ng/compiledata.c View File

fseek(f, 40, SEEK_SET); fseek(f, 40, SEEK_SET);


if ((sr1 != samplerate_native) || (sr2 != sr1*2)) { if ((sr1 != samplerate_native) || (sr2 != sr1*2)) {
int fd_temp;
char command[sizeof(path_home)+250]; char command[sizeof(path_home)+250];


failed = false; failed = false;


#ifdef HAVE_MKSTEMP #ifdef HAVE_MKSTEMP
strcpy(fname_temp, "/tmp/espeakXXXXXX"); strcpy(fname_temp, "/tmp/espeakXXXXXX");
int fd_temp;
if ((fd_temp = mkstemp(fname_temp)) >= 0) if ((fd_temp = mkstemp(fname_temp)) >= 0)
close(fd_temp); close(fd_temp);
#else #else

+ 8
- 9
src/libespeak-ng/readclause.c View File

{ {
unsigned int flags[2]; unsigned int flags[2];
char phonemes[55]; char phonemes[55];
char phonemes2[55];
char *string1 = (char *)string; char *string1 = (char *)string;


flags[0] = flags[1] = 0; flags[0] = flags[1] = 0;
if (LookupDictList(tr, &string1, phonemes, flags, 0, NULL)) { if (LookupDictList(tr, &string1, phonemes, flags, 0, NULL)) {
char phonemes2[55];
SetWordStress(tr, phonemes, flags, -1, 0); SetWordStress(tr, phonemes, flags, -1, 0);
DecodePhonemes(phonemes, phonemes2); DecodePhonemes(phonemes, phonemes2);
sprintf(text_out, "[\002%s]]", phonemes2); sprintf(text_out, "[\002%s]]", phonemes2);
unsigned int flags[2]; unsigned int flags[2];
char single_letter[24]; char single_letter[24];
char phonemes[60]; char phonemes[60];
char phonemes2[60];
const char *lang_name = NULL; const char *lang_name = NULL;
char *string; char *string;
static char buf[60]; static char buf[60];
} }


if (phonemes[0]) { if (phonemes[0]) {
char phonemes2[60];
if (lang_name) { if (lang_name) {
SetWordStress(translator2, phonemes, flags, -1, 0); SetWordStress(translator2, phonemes, flags, -1, 0);
DecodePhonemes(phonemes, phonemes2); DecodePhonemes(phonemes, phonemes2);
// c1: the punctuation character // c1: the punctuation character
// c2: the following character // c2: the following character


int punct_count;
const char *punctname = NULL; const char *punctname = NULL;
int soundicon; int soundicon;
int attributes; int attributes;
int len; int len;
int bufix1; int bufix1;
char buf[200]; char buf[200];
char buf2[80];
char ph_buf[30]; char ph_buf[30];


c2 = *c2_ptr; c2 = *c2_ptr;
if (punctname == NULL) if (punctname == NULL)
return -1; return -1;



if ((*bufix == 0) || (end_clause == 0) || (tr->langopts.param[LOPT_ANNOUNCE_PUNCT] & 2)) { 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 while (!Eof() && (c2 == c1) && (c1 != '<')) { // don't eat extra '<', it can miss XML tags
punct_count++; punct_count++;
c2 = GetC(); c2 = GetC();
if (embedded_value[EMBED_S] < 300) 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 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) { while (punct_count-- > 0) {
sprintf(buf2, " %s", punctname); sprintf(buf2, " %s", punctname);
strcat(buf, buf2); strcat(buf, buf2);


int ix; int ix;
int len; int len;
void *vp;


if (wide) { if (wide) {
len = (wcslen((const wchar_t *)name)+1)*sizeof(wchar_t); len = (wcslen((const wchar_t *)name)+1)*sizeof(wchar_t);


if (namedata_ix+len >= n_namedata) { if (namedata_ix+len >= n_namedata) {
// allocate more space for marker names // allocate more space for marker names
void *vp;
if ((vp = realloc(namedata, namedata_ix+len + 1000)) == NULL) if ((vp = realloc(namedata, namedata_ix+len + 1000)) == NULL)
return -1; // failed to allocate, original data is unchanged but ignore this new name 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 // !!! Bug?? If the allocated data shifts position, then pointers given to user application will be invalid
int c1 = ' '; // current character int c1 = ' '; // current character
int c2; // next character int c2; // next character
int cprev = ' '; // previous character int cprev = ' '; // previous character
int cprev2 = ' ';
int c_next; int c_next;
int parag; int parag;
int ix = 0; int ix = 0;
return CLAUSE_NONE; return CLAUSE_NONE;
} }
} }

cprev2 = cprev;
int cprev2 = cprev;
cprev = c1; cprev = c1;
c1 = c2; c1 = c2;



+ 1
- 1
src/libespeak-ng/soundicon.c View File

f = NULL; f = NULL;
if ((f = fopen(fname, "rb")) != NULL) { if ((f = fopen(fname, "rb")) != NULL) {
int ix; int ix;
int fd_temp;
int header[3]; int header[3];
char command[sizeof(fname2)+sizeof(fname2)+40]; char command[sizeof(fname2)+sizeof(fname2)+40];




#ifdef HAVE_MKSTEMP #ifdef HAVE_MKSTEMP
strcpy(fname_temp, "/tmp/espeakXXXXXX"); strcpy(fname_temp, "/tmp/espeakXXXXXX");
int fd_temp;
if ((fd_temp = mkstemp(fname_temp)) >= 0) if ((fd_temp = mkstemp(fname_temp)) >= 0)
close(fd_temp); close(fd_temp);
#else #else

+ 22
- 21
src/libespeak-ng/ssml.c View File

static int attrcopy_utf8(char *buf, const wchar_t *pw, int len) 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 // Convert attribute string into utf8, write to buf, and return its utf8 length
unsigned int c;
int ix = 0; int ix = 0;
int n;
int prev_c = 0;


if (pw != NULL) { if (pw != NULL) {
unsigned int c;
int prev_c = 0;
while ((ix < (len-4)) && ((c = *pw++) != 0)) { while ((ix < (len-4)) && ((c = *pw++) != 0)) {
if ((c == '"') && (prev_c != '\\')) if ((c == '"') && (prev_c != '\\'))
break; // " indicates end of attribute, unless preceded by backstroke break; // " indicates end of attribute, unless preceded by backstroke
n = utf8_out(c, &buf[ix]);

int n = utf8_out(c, &buf[ix]);
ix += n; ix += n;
prev_c = c; prev_c = c;
} }
const char *p; const char *p;
SSML_STACK *sp; SSML_STACK *sp;
const char *v_id; const char *v_id;
int voice_name_specified;
int voice_found; int voice_found;
espeak_VOICE voice_select; espeak_VOICE voice_select;
static char voice_name[40]; static char voice_name[40];
char language[40]; char language[40];
char buf[80];


MAKE_MEM_UNDEFINED(&voice_name, sizeof(voice_name)); MAKE_MEM_UNDEFINED(&voice_name, sizeof(voice_name));




for (ix = 0; ix < n_ssml_stack; ix++) { for (ix = 0; ix < n_ssml_stack; ix++) {
sp = &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)) { if ((sp->voice_name[0] != 0) && (SelectVoiceByName(NULL, sp->voice_name) != NULL)) {
voice_name_specified = 1; voice_name_specified = 1;


if ((strchr(v_id, '+') == NULL) && ((voice_select.gender == ENGENDER_UNKNOWN) || (voice_select.gender == base_voice->gender)) && (base_voice_variant_name[0] != 0)) { 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 // 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); sprintf(buf, "%s+%s", v_id, base_voice_variant_name);
strncpy0(voice_name, buf, sizeof(voice_name)); strncpy0(voice_name, buf, sizeof(voice_name));
return voice_name; return voice_name;
// a voice change. // a voice change.
// Returns CLAUSE_TYPE_VOICE_CHANGE if there is 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; const char *new_voice_id;


static const MNEM_TAB mnem_gender[] = { static const MNEM_TAB mnem_gender[] = {
if (n_ssml_stack > 1) if (n_ssml_stack > 1)
n_ssml_stack--; n_ssml_stack--;
} else { } 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 // add a stack frame if any voice details are specified
lang = GetSsmlAttribute(pw, "xml:lang"); lang = GetSsmlAttribute(pw, "xml:lang");




ssml_sp = &ssml_stack[n_ssml_stack++]; ssml_sp = &ssml_stack[n_ssml_stack++];


int value;

attrcopy_utf8(ssml_sp->language, lang, sizeof(ssml_sp->language)); attrcopy_utf8(ssml_sp->language, lang, sizeof(ssml_sp->language));
attrcopy_utf8(ssml_sp->voice_name, name, sizeof(ssml_sp->voice_name)); attrcopy_utf8(ssml_sp->voice_name, name, sizeof(ssml_sp->voice_name));
if ((value = attrnumber(variant, 1, 0)) > 0) if ((value = attrnumber(variant, 1, 0)) > 0)
// Set the speech parameters from the parameter stack // Set the speech parameters from the parameter stack
int param; int param;
int ix; int ix;
int value;
char buf[20]; char buf[20];
int new_parameters[N_SPEECH_PARAM]; 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 static const char cmd_letter[N_SPEECH_PARAM] = { 0, 'S', 'A', 'P', 'R', 0, 'C', 0, 0, 0, 0, 0, 'F' }; // embedded command letters
} }


for (param = 0; param < N_SPEECH_PARAM; param++) { for (param = 0; param < N_SPEECH_PARAM; param++) {
int value;
if ((value = new_parameters[param]) != speech_parameters[param]) { if ((value = new_parameters[param]) != speech_parameters[param]) {
buf[0] = 0; buf[0] = 0;


{ NULL, 0 } { NULL, 0 }
}; };


int ix;
int letter; int letter;
char *p; char *p;


p = &outbuf[index]; p = &outbuf[index];


if ((letter = LookupMnem(keynames, p)) != 0) { if ((letter = LookupMnem(keynames, p)) != 0) {
ix = utf8_out(letter, p);
int ix;
ix = utf8_out(letter, p);
*outix = index + ix; *outix = index + ix;
return letter; return letter;
} }
static void SetProsodyParameter(int param_type, const wchar_t *attr1, PARAM_STACK *sp, PARAM_STACK *param_stack, int *speech_parameters) static void SetProsodyParameter(int param_type, const wchar_t *attr1, PARAM_STACK *sp, PARAM_STACK *param_stack, int *speech_parameters)
{ {
int value; int value;
int sign;


static const MNEM_TAB mnem_volume[] = { static const MNEM_TAB mnem_volume[] = {
{ "default", 100 }, { "default", 100 },
// mnemonic specifies a value as a percentage of the base pitch/range/rate/volume // 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; sp->parameter[param_type] = (param_stack[0].parameter[param_type] * value)/100;
} else { } else {
sign = attr_prosody_value(param_type, attr1, &value);
int sign = attr_prosody_value(param_type, attr1, &value);


if (sign == 0) if (sign == 0)
sp->parameter[param_type] = value; // absolute value in Hz sp->parameter[param_type] = value; // absolute value in Hz


unsigned int ix; unsigned int ix;
int index; int index;
int c;
int tag_type; int tag_type;
int value; int value;
int value2; int value2;
const wchar_t *attr2; const wchar_t *attr2;
const wchar_t *attr3; const wchar_t *attr3;
int terminator; int terminator;
char *uri;
int param_type; int param_type;
char tag_name[40]; char tag_name[40];
char buf[160]; char buf[160];
}; };


for (ix = 0; ix < (sizeof(tag_name)-1); ix++) { for (ix = 0; ix < (sizeof(tag_name)-1); ix++) {
int c;
if (((c = xml_buf[ix]) == 0) || iswspace(c)) if (((c = xml_buf[ix]) == 0) || iswspace(c))
break; break;
tag_name[ix] = tolower((char)c); tag_name[ix] = tolower((char)c);
sp = PushParamStack(tag_type, n_param_stack, (PARAM_STACK *)param_stack); sp = PushParamStack(tag_type, n_param_stack, (PARAM_STACK *)param_stack);


if ((attr1 = GetSsmlAttribute(px, "src")) != NULL) { if ((attr1 = GetSsmlAttribute(px, "src")) != NULL) {
char fname[256];
attrcopy_utf8(buf, attr1, sizeof(buf)); attrcopy_utf8(buf, attr1, sizeof(buf));


if (uri_callback == NULL) { if (uri_callback == NULL) {
if ((xmlbase != NULL) && (buf[0] != '/')) { if ((xmlbase != NULL) && (buf[0] != '/')) {
char fname[256];
sprintf(fname, "%s/%s", xmlbase, buf); sprintf(fname, "%s/%s", xmlbase, buf);
index = LoadSoundFile2(fname); index = LoadSoundFile2(fname);
} else } else
} }
} else { } else {
if ((index = AddNameData(buf, 0)) >= 0) { if ((index = AddNameData(buf, 0)) >= 0) {
char *uri;
uri = &namedata[index]; uri = &namedata[index];
if (uri_callback(1, uri, xmlbase) == 0) { if (uri_callback(1, uri, xmlbase) == 0) {
sprintf(buf, "%c%dU", CTRL_EMBEDDED, index); sprintf(buf, "%c%dU", CTRL_EMBEDDED, index);

+ 65
- 69
src/libespeak-ng/translate.c View File

#include "speech.h" // for MAKE_MEM_UNDEFINED #include "speech.h" // for MAKE_MEM_UNDEFINED
#include "translateword.h" #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 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 *translator = NULL; // the main translator
Translator *translator2 = NULL; // secondary translator for certain words Translator *translator2 = NULL; // secondary translator for certain words
{ {
char words_phonemes[N_WORD_PHONEMES]; // a word translated into phoneme codes char words_phonemes[N_WORD_PHONEMES]; // a word translated into phoneme codes
char *phonemes = words_phonemes; 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)); 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) { if (flags & FLAG_TEXTMODE && word_out) {
strcpy(word+2, word_out); strcpy(word+2, word_out);
word_out = word+2; word_out = word+2;


bool first_word = true;
int available = N_WORD_PHONEMES;
while (*word_out && available > 1) { while (*word_out && available > 1) {
int c; int c;
utf8_in(&c, word_out); utf8_in(&c, word_out);
{ {
// Process embedded commands for emphasis, sayas, and break // Process embedded commands for emphasis, sayas, and break
int embedded_cmd; int embedded_cmd;
int value;

do { do {
embedded_cmd = embedded_list[embedded_read++]; embedded_cmd = embedded_list[embedded_read++];
value = embedded_cmd >> 8;
int value = embedded_cmd >> 8;


switch (embedded_cmd & 0x1f) switch (embedded_cmd & 0x1f)
{ {
bool first_phoneme = true; bool first_phoneme = true;
int source_ix; int source_ix;
int len; int len;
int ix;
const char *new_language;
int bad_phoneme; int bad_phoneme;
int word_flags; int word_flags;
int word_copy_len;
char word_copy[N_WORD_BYTES+1]; char word_copy[N_WORD_BYTES+1];
char word_replaced[N_WORD_BYTES+1]; char word_replaced[N_WORD_BYTES+1];
char old_dictionary_name[40]; char old_dictionary_name[40];
if ((word[0] == 0) || (word_flags & FLAG_DELETE_WORD)) { if ((word[0] == 0) || (word_flags & FLAG_DELETE_WORD)) {
// nothing to translate. Add a dummy phoneme to carry any embedded commands // nothing to translate. Add a dummy phoneme to carry any embedded commands
if (embedded_flag) { 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].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++; n_ph_list2++;
embedded_flag = 0; embedded_flag = 0;
} }
p = (unsigned char *)word_phonemes; p = (unsigned char *)word_phonemes;
if (word_flags & FLAG_PHONEMES) { if (word_flags & FLAG_PHONEMES) {
// The input is in phoneme mnemonics, not language text // The input is in phoneme mnemonics, not language text
int c1;
char lang_name[12];


if (memcmp(word, "_^_", 3) == 0) { 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); EncodePhonemes(word, word_phonemes, &bad_phoneme);
}

flags = FLAG_FOUND; flags = FLAG_FOUND;
} else { } else {
int c2; 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++; while (((c2 = word_copy[ix] = word[ix]) != ' ') && (c2 != 0) && (ix < N_WORD_BYTES)) ix++;
word_copy_len = ix; word_copy_len = ix;


// this word uses a different language // this word uses a different language
memcpy(word, word_copy, word_copy_len); memcpy(word, word_copy, word_copy_len);


const char *new_language;
new_language = (char *)(&p[1]); new_language = (char *)(&p[1]);
if (new_language[0] == 0) if (new_language[0] == 0)
new_language = ESPEAKNG_DEFAULT_VOICE; new_language = ESPEAKNG_DEFAULT_VOICE;
// To allow language specific examination and replacement of characters // To allow language specific examination and replacement of characters


int code; int code;
int initial;
int medial;
int final;
int next2; int next2;


static const unsigned char hangul_compatibility[0x34] = { static const unsigned char hangul_compatibility[0x34] = {
// check for Korean Hangul letters // check for Korean Hangul letters
if (((code = c - 0xac00) >= 0) && (c <= 0xd7af)) { if (((code = c - 0xac00) >= 0) && (c <= 0xd7af)) {
// break a syllable hangul into 2 or 3 individual jamo // 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) { if (initial == 11) {
// null initial // null initial


static int UpperCaseInWord(Translator *tr, char *word, int c) static int UpperCaseInWord(Translator *tr, char *word, int c)
{ {
int ix;
int len;
const char *p;

if (tr->translator_name == L('g', 'a')) { if (tr->translator_name == L('g', 'a')) {
// Irish
int ix;
const char *p;

for (ix = 0;; ix++) { for (ix = 0;; ix++) {
int len;
if ((p = UCase_ga[ix]) == NULL) if ((p = UCase_ga[ix]) == NULL)
break; break;


int c; int c;
int cc = 0; int cc = 0;
unsigned int source_index = 0; unsigned int source_index = 0;
unsigned int prev_source_index = 0;
int source_index_word = 0; int source_index_word = 0;
int prev_in; int prev_in;
int prev_out = ' '; int prev_out = ' ';
int prev_out2;
int prev_in_save = 0; int prev_in_save = 0;
int next_in; int next_in;
int next_in_nbytes; int next_in_nbytes;
words[0].start = ix; words[0].start = ix;
words[0].flags = 0; 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)) { while (!finished && (ix < (int)sizeof(sbuf) - 1)) {
prev_out2 = prev_out; prev_out2 = prev_out;
utf8_in2(&prev_out, &sbuf[ix-1], 1); utf8_in2(&prev_out, &sbuf[ix-1], 1);
} else if (source_index > 0) } else if (source_index > 0)
utf8_in2(&prev_in, &source[source_index-1], 1); utf8_in2(&prev_in, &source[source_index-1], 1);


prev_source_index = source_index;
unsigned int prev_source_index = source_index;


if (char_inserted) { if (char_inserted) {
c = char_inserted; c = char_inserted;
words[word_count].start = ix; words[word_count].start = ix;
words[word_count].flags = 0; 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; word_flags = next_word_flags;
next_word_flags = 0; next_word_flags = 0;
int c_temp; int c_temp;
char *pn; char *pn;
char *pw; char *pw;
int nw;
char number_buf[150]; char number_buf[150];
WORD_TAB num_wtab[50]; // copy of 'words', when splitting numbers into parts WORD_TAB num_wtab[50]; // copy of 'words', when splitting numbers into parts




if (n_digits > 4 && n_digits <= 32) { if (n_digits > 4 && n_digits <= 32) {
// word is entirely digits, insert commas and break into 3 digit "words" // word is entirely digits, insert commas and break into 3 digit "words"
int nw = 0;

number_buf[0] = ' '; number_buf[0] = ' ';
number_buf[1] = ' '; number_buf[1] = ' ';
number_buf[2] = ' '; number_buf[2] = ' ';
pn = &number_buf[3]; pn = &number_buf[3];
nx = n_digits; nx = n_digits;
nw = 0;


if ((n_digits > tr->langopts.max_digits) || (word[0] == '0')) if ((n_digits > tr->langopts.max_digits) || (word[0] == '0'))
words[ix].flags |= FLAG_INDIVIDUAL_DIGITS; words[ix].flags |= FLAG_INDIVIDUAL_DIGITS;
} }
} }


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) { 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 // combine a preposition with the following word
} }
} }


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) void InitText(int control)
{ {
count_sentences = 0; count_sentences = 0;


if ((control & espeakKEEP_NAMEDATA) == 0) if ((control & espeakKEEP_NAMEDATA) == 0)
InitNamedata(); InitNamedata();
}
}

+ 48
- 53
src/libespeak-ng/translateword.c View File

void ApplySpecialAttribute2(Translator *tr, char *phonemes, int dict_flags) void ApplySpecialAttribute2(Translator *tr, char *phonemes, int dict_flags)
{ {
// apply after the translation is complete // apply after the translation is complete

int ix;
int len; int len;
char *p;



len = strlen(phonemes); len = strlen(phonemes);


if (tr->langopts.param[LOPT_ALT] & 2) { 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) { if (phonemes[ix] == phonSTRESS_P) {
char *p;
p = &phonemes[ix+1]; p = &phonemes[ix+1];
if ((dict_flags & FLAG_ALT2_TRANS) != 0) { if ((dict_flags & FLAG_ALT2_TRANS) != 0) {
if (*p == PhonemeCode('E')) if (*p == PhonemeCode('E'))
int n_bytes; int n_bytes;
int letter; int letter;
int len; int len;
int ix;
int c;
char *p2;
char *pbuf;
const char *modifier;
ALPHABET *alphabet; ALPHABET *alphabet;
int al_offset; int al_offset;
int al_flags; int al_flags;
int language;
int number; int number;
int phontab_1; int phontab_1;
int speak_letter_number;
char capital[30]; char capital[30];
char ph_buf[80]; char ph_buf[80];
char ph_buf2[80]; char ph_buf2[80];


if (ph_buf[0] == 0) { if (ph_buf[0] == 0) {
// is this a subscript or superscript letter ? // is this a subscript or superscript letter ?
int c;
if ((c = IsSuperscript(letter)) != 0) { if ((c = IsSuperscript(letter)) != 0) {
letter = c & 0x3fff; letter = c & 0x3fff;

const char *modifier;
if ((control & 4 ) && ((modifier = modifiers[c >> 14]) != NULL)) { if ((control & 4 ) && ((modifier = modifiers[c >> 14]) != NULL)) {
// don't say "superscript" during normal text reading // don't say "superscript" during normal text reading
Lookup(tr, modifier, capital); Lookup(tr, modifier, capital);
// caution: SetWordStress() etc don't expect phonSWITCH + phoneme table number // caution: SetWordStress() etc don't expect phonSWITCH + phoneme table number


if (ph_buf[0] == 0) { if (ph_buf[0] == 0) {
int language;
if ((al_offset != 0) && (al_offset == translator->langopts.alt_alphabet)) if ((al_offset != 0) && (al_offset == translator->langopts.alt_alphabet))
language = translator->langopts.alt_alphabet_lang; language = translator->langopts.alt_alphabet_lang;
else if ((alphabet != NULL) && (alphabet->language != 0) && !(al_flags & AL_NOT_LETTERS)) else if ((alphabet != NULL) && (alphabet->language != 0) && !(al_flags & AL_NOT_LETTERS))


if ((language != tr->translator_name) || (language == L('k', 'o'))) { if ((language != tr->translator_name) || (language == L('k', 'o'))) {
char *p3; char *p3;
int initial, code;
//int initial, code;
char hangul_buf[12]; char hangul_buf[12];


// speak in the language for this alphabet (or English) // speak in the language for this alphabet (or English)
ph_buf[2] = SetTranslator3(WordToString2(language)); ph_buf[2] = SetTranslator3(WordToString2(language));


if (translator3 != NULL) { if (translator3 != NULL) {
int code;
if (((code = letter - 0xac00) >= 0) && (letter <= 0xd7af)) { if (((code = letter - 0xac00) >= 0) && (letter <= 0xd7af)) {
// Special case for Korean letters. // Special case for Korean letters.
// break a syllable hangul into 2 or 3 individual jamo // break a syllable hangul into 2 or 3 individual jamo


hangul_buf[0] = ' '; hangul_buf[0] = ' ';
p3 = &hangul_buf[1]; p3 = &hangul_buf[1];
int initial;
if ((initial = (code/28)/21) != 11) { if ((initial = (code/28)/21) != 11) {
p3 += utf8_out(initial + 0x1100, p3); p3 += utf8_out(initial + 0x1100, p3);
} }


if (ph_buf[0] == 0) { if (ph_buf[0] == 0) {
// character name not found // 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;
} }
*p2 = 0;
} else {
// speak the hexadecimal number of the character code
sprintf(hexbuf, "%x", letter);
}


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);
}
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);
} }
strcat(pbuf, pause_string);
} }
} }


{ {
int wc; int wc;
int count = 0; int count = 0;
int nbytes;
int ok;
int ix; int ix;
char *word; char *word;
char *wbuf; char *wbuf;
wbuf = word_buf; wbuf = word_buf;


for (;;) { 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] == ' ') && IsAlpha(wc)) {
if (word[nbytes+1] == '.') { if (word[nbytes+1] == '.') {
if (word[nbytes+2] == ' ') if (word[nbytes+2] == ' ')

Loading…
Cancel
Save