Fixes for code smells from cppcheck static code analysis tool. Also includes some function refactoring.master
| @@ -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 | |||
| @@ -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; | |||
| } | |||
| *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); | |||
| } | |||
| } | |||
| @@ -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] == ' ') | |||