| @@ -100,7 +100,7 @@ CXXFLAGS+=-I ./ -I ../ -I ../src/include/espeak-ng | |||
| #CXXFLAGS+=-s USE_PTHREADS=1 | |||
| # NOTE: extra flags for emscripten | |||
| EM_CXXFLAGS=-s RESERVED_FUNCTION_POINTERS=2 --memory-init-file 0 -s FORCE_FILESYSTEM=1 -s WASM=0 | |||
| EM_CXXFLAGS=-s RESERVED_FUNCTION_POINTERS=2 --memory-init-file 0 -s FORCE_FILESYSTEM=1 -s WASM=0 -s ERROR_ON_UNDEFINED_SYMBOLS=0 | |||
| @@ -119,6 +119,8 @@ eSpeakNGWorker.prototype.synthesize_ipa = function (aText, aCallback) { | |||
| if (typeof WorkerGlobalScope !== 'undefined') { | |||
| var worker; | |||
| Module.postRun = Module.postRun || []; | |||
| Module.postRun.push(function () { | |||
| worker = new eSpeakNGWorker(); | |||
| @@ -142,7 +142,7 @@ static void InitGroups(Translator *tr) | |||
| // a RULE_GROUP_END. | |||
| if (*p != RULE_GROUP_END) while (*p != 0) { | |||
| if (*p != RULE_GROUP_START) { | |||
| fprintf(stderr, "Bad rules data in '%s_dict' at 0x%x (%c)\n", dictionary_name, (unsigned int)(p - tr->data_dictrules), p); | |||
| fprintf(stderr, "Bad rules data in '%s_dict' at 0x%x (%c)\n", dictionary_name, (unsigned int)(p - tr->data_dictrules), *p); | |||
| break; | |||
| } | |||
| p++; | |||
| @@ -150,8 +150,11 @@ static void InitGroups(Translator *tr) | |||
| if (p[0] == RULE_REPLACEMENTS) { | |||
| p = (char *)(((intptr_t)p+4) & ~3); // advance to next word boundary | |||
| tr->langopts.replace_chars = (unsigned char *)p; | |||
| while (*(unsigned int *)p != 0) | |||
| while ( !is_str_totally_null(p, 4) ) { | |||
| p++; | |||
| } | |||
| while (*p != RULE_GROUP_END) p++; | |||
| p++; | |||
| continue; | |||
| @@ -132,6 +132,14 @@ int clause_type_from_codepoint(uint32_t c) | |||
| return CLAUSE_NONE; | |||
| } | |||
| int is_str_totally_null(const char* str, int size) { | |||
| // Tests if all bytes of str are null up to size | |||
| // This should never be reimplemented with integers, because | |||
| // this function has to work with unaligned char* | |||
| // (casting to int when unaligned may result in ungaranteed behaviors) | |||
| return (*str == 0 && memcmp(str, str+1, size-1) == 0); | |||
| } | |||
| int towlower2(unsigned int c, Translator *translator) | |||
| { | |||
| // check for non-standard upper to lower case conversions | |||
| @@ -34,7 +34,10 @@ typedef struct { | |||
| extern PARAM_STACK param_stack[]; | |||
| int clause_type_from_codepoint(uint32_t c); | |||
| // Tests if all bytes of str up to size are null | |||
| int is_str_totally_null(const char* str, int size); | |||
| int clause_type_from_codepoint(uint32_t c); | |||
| int towlower2(unsigned int c, Translator *translator); // Supports Turkish I | |||
| int Eof(void); | |||
| const char *WordToString2(unsigned int word); | |||
| @@ -52,6 +55,7 @@ int ReadClause(Translator *tr, | |||
| #ifdef __cplusplus | |||
| } | |||
| #endif | |||
| @@ -1793,7 +1793,7 @@ static int EmbeddedCommand(unsigned int *source_index_out) | |||
| static const char *FindReplacementChars(Translator *tr, const char **pfrom, unsigned int c, const char *next, int *ignore_next_n) | |||
| { | |||
| const char *from = *pfrom; | |||
| while (*(unsigned int *)from != 0) { | |||
| while ( !is_str_totally_null(from, 4) ) { | |||
| unsigned int fc = 0; // from character | |||
| unsigned int nc = c; // next character | |||
| const char *match_next = next; | |||