mirror of
https://github.com/rhasspy/espeak-ng.git
synced 2026-10-31 05:35:35 +00:00
code cleanup: compiledict: do not use temp file
This commit is contained in:
@@ -145,8 +145,8 @@ static const MNEM_TAB mnem_flags[] = {
|
|||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
char name[LEN_GROUP_NAME+1];
|
char name[LEN_GROUP_NAME+1];
|
||||||
unsigned int start;
|
void *start;
|
||||||
unsigned int length;
|
size_t length;
|
||||||
int group3_ix;
|
int group3_ix;
|
||||||
} RGROUP;
|
} RGROUP;
|
||||||
|
|
||||||
@@ -1191,10 +1191,10 @@ static int __cdecl rgroup_sorter(RGROUP *a, RGROUP *b)
|
|||||||
if (ix != 0) return ix;
|
if (ix != 0) return ix;
|
||||||
ix = strcmp(a->name, b->name);
|
ix = strcmp(a->name, b->name);
|
||||||
if (ix != 0) return ix;
|
if (ix != 0) return ix;
|
||||||
return a->start-b->start;
|
return (uintptr_t)a->start - (uintptr_t)b->start;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void output_rule_group(FILE *f_out, int n_rules, char **rules, char *name)
|
static void* output_rule_group(int n_rules, char **rules, char *name, size_t *outsize)
|
||||||
{
|
{
|
||||||
int ix;
|
int ix;
|
||||||
int len1;
|
int len1;
|
||||||
@@ -1203,6 +1203,8 @@ static void output_rule_group(FILE *f_out, int n_rules, char **rules, char *name
|
|||||||
char *p;
|
char *p;
|
||||||
char *p2, *p3;
|
char *p2, *p3;
|
||||||
const char *common;
|
const char *common;
|
||||||
|
char *outptr = NULL;
|
||||||
|
size_t outpos, outlen = 0;
|
||||||
|
|
||||||
short nextchar_count[256];
|
short nextchar_count[256];
|
||||||
memset(nextchar_count, 0, sizeof(nextchar_count));
|
memset(nextchar_count, 0, sizeof(nextchar_count));
|
||||||
@@ -1225,20 +1227,30 @@ static void output_rule_group(FILE *f_out, int n_rules, char **rules, char *name
|
|||||||
|
|
||||||
nextchar_count[(unsigned char)(p2[0])]++; // the next byte after the group name
|
nextchar_count[(unsigned char)(p2[0])]++; // the next byte after the group name
|
||||||
|
|
||||||
|
outpos = outlen;
|
||||||
if ((common[0] != 0) && (strcmp(p, common) == 0)) {
|
if ((common[0] != 0) && (strcmp(p, common) == 0)) {
|
||||||
fwrite(p2, len2, 1, f_out);
|
outlen += len2 + 1;
|
||||||
fputc(0, f_out); // no phoneme string, it's the same as previous rule
|
outptr = realloc(outptr, outlen);
|
||||||
|
memmove(outptr + outpos, p2, len2);
|
||||||
|
outptr[outlen-1] = 0;
|
||||||
} else {
|
} else {
|
||||||
if ((ix < n_rules-1) && (strcmp(p, rules[ix+1]) == 0)) {
|
if ((ix < n_rules-1) && (strcmp(p, rules[ix+1]) == 0)) {
|
||||||
|
outlen ++;
|
||||||
|
outptr = realloc(outptr, outlen);
|
||||||
common = rules[ix]; // phoneme string is same as next, set as common
|
common = rules[ix]; // phoneme string is same as next, set as common
|
||||||
fputc(RULE_PH_COMMON, f_out);
|
outptr[outpos++] = RULE_PH_COMMON;
|
||||||
}
|
}
|
||||||
|
|
||||||
fwrite(p2, len2, 1, f_out);
|
outlen += len2 + 1 + len1;
|
||||||
fputc(RULE_PHONEMES, f_out);
|
outptr = realloc(outptr, outlen);
|
||||||
fwrite(p, len1, 1, f_out);
|
memmove(outptr + outpos, p2, len2);
|
||||||
|
outpos += len2;
|
||||||
|
outptr[outpos++] = RULE_PHONEMES;
|
||||||
|
memmove(outptr + outpos, p, len1);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
if (outsize) *outsize = outlen;
|
||||||
|
return outptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int compile_lettergroup(CompileContext *ctx, char *input, FILE *f_out)
|
static int compile_lettergroup(CompileContext *ctx, char *input, FILE *f_out)
|
||||||
@@ -1320,14 +1332,13 @@ static void free_rules(char **rules, int n_rules)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static espeak_ng_STATUS compile_dictrules(CompileContext *ctx, FILE *f_in, FILE *f_out, char *fname_temp, espeak_ng_ERROR_CONTEXT *context)
|
static espeak_ng_STATUS compile_dictrules(CompileContext *ctx, FILE *f_in, FILE *f_out)
|
||||||
{
|
{
|
||||||
char *prule;
|
char *prule;
|
||||||
unsigned char *p;
|
unsigned char *p;
|
||||||
int ix;
|
int ix;
|
||||||
int c;
|
int c;
|
||||||
int gp;
|
int gp;
|
||||||
FILE *f_temp;
|
|
||||||
int n_rules = 0;
|
int n_rules = 0;
|
||||||
int count = 0;
|
int count = 0;
|
||||||
int different;
|
int different;
|
||||||
@@ -1347,9 +1358,6 @@ static espeak_ng_STATUS compile_dictrules(CompileContext *ctx, FILE *f_in, FILE
|
|||||||
ctx->linenum = 0;
|
ctx->linenum = 0;
|
||||||
ctx->group_name[0] = 0;
|
ctx->group_name[0] = 0;
|
||||||
|
|
||||||
if ((f_temp = fopen(fname_temp, "wb")) == NULL)
|
|
||||||
return create_file_error_context(context, errno, fname_temp);
|
|
||||||
|
|
||||||
for (;;) {
|
for (;;) {
|
||||||
ctx->linenum++;
|
ctx->linenum++;
|
||||||
buf = fgets(buf1, sizeof(buf1), f_in);
|
buf = fgets(buf1, sizeof(buf1), f_in);
|
||||||
@@ -1366,9 +1374,7 @@ static espeak_ng_STATUS compile_dictrules(CompileContext *ctx, FILE *f_in, FILE
|
|||||||
if (n_rules > 0) {
|
if (n_rules > 0) {
|
||||||
strcpy(rgroup[n_rgroups].name, ctx->group_name);
|
strcpy(rgroup[n_rgroups].name, ctx->group_name);
|
||||||
rgroup[n_rgroups].group3_ix = ctx->group3_ix;
|
rgroup[n_rgroups].group3_ix = ctx->group3_ix;
|
||||||
rgroup[n_rgroups].start = ftell(f_temp);
|
rgroup[n_rgroups].start = output_rule_group(n_rules, rules, ctx->group_name, &rgroup[n_rgroups].length);
|
||||||
output_rule_group(f_temp, n_rules, rules, ctx->group_name);
|
|
||||||
rgroup[n_rgroups].length = ftell(f_temp) - rgroup[n_rgroups].start;
|
|
||||||
n_rgroups++;
|
n_rgroups++;
|
||||||
|
|
||||||
count += n_rules;
|
count += n_rules;
|
||||||
@@ -1479,20 +1485,12 @@ static espeak_ng_STATUS compile_dictrules(CompileContext *ctx, FILE *f_in, FILE
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
fclose(f_temp);
|
|
||||||
|
|
||||||
qsort((void *)rgroup, n_rgroups, sizeof(rgroup[0]), (int(__cdecl *)(const void *, const void *))rgroup_sorter);
|
qsort((void *)rgroup, n_rgroups, sizeof(rgroup[0]), (int(__cdecl *)(const void *, const void *))rgroup_sorter);
|
||||||
|
|
||||||
if ((f_temp = fopen(fname_temp, "rb")) == NULL) {
|
|
||||||
free_rules(rules, n_rules);
|
|
||||||
return create_file_error_context(context, errno, fname_temp);
|
|
||||||
}
|
|
||||||
|
|
||||||
prev_rgroup_name = "\n";
|
prev_rgroup_name = "\n";
|
||||||
|
|
||||||
for (gp = 0; gp < n_rgroups; gp++) {
|
for (gp = 0; gp < n_rgroups; gp++) {
|
||||||
fseek(f_temp, rgroup[gp].start, SEEK_SET);
|
|
||||||
|
|
||||||
if ((different = strcmp(rgroup[gp].name, prev_rgroup_name)) != 0) {
|
if ((different = strcmp(rgroup[gp].name, prev_rgroup_name)) != 0) {
|
||||||
// not the same as the previous group
|
// not the same as the previous group
|
||||||
if (gp > 0)
|
if (gp > 0)
|
||||||
@@ -1508,19 +1506,16 @@ static espeak_ng_STATUS compile_dictrules(CompileContext *ctx, FILE *f_in, FILE
|
|||||||
fputc(0, f_out);
|
fputc(0, f_out);
|
||||||
}
|
}
|
||||||
|
|
||||||
for (ix = rgroup[gp].length; ix > 0; ix--) {
|
fwrite(rgroup[gp].start, rgroup[gp].length, 1, f_out);
|
||||||
c = fgetc(f_temp);
|
|
||||||
fputc(c, f_out);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
fputc(RULE_GROUP_END, f_out);
|
fputc(RULE_GROUP_END, f_out);
|
||||||
fputc(0, f_out);
|
fputc(0, f_out);
|
||||||
|
|
||||||
fclose(f_temp);
|
|
||||||
remove(fname_temp);
|
|
||||||
|
|
||||||
fprintf(ctx->f_log, "\t%d rules, %d groups (%d)\n\n", count, n_rgroups, n_groups3);
|
fprintf(ctx->f_log, "\t%d rules, %d groups (%d)\n\n", count, n_rgroups, n_groups3);
|
||||||
free_rules(rules, n_rules);
|
free_rules(rules, n_rules);
|
||||||
|
for (gp = 0; gp < n_rgroups; gp++) {
|
||||||
|
free(rgroup[gp].start);
|
||||||
|
}
|
||||||
return ENS_OK;
|
return ENS_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1539,7 +1534,6 @@ ESPEAK_NG_API espeak_ng_STATUS espeak_ng_CompileDictionary(const char *dsource,
|
|||||||
int value;
|
int value;
|
||||||
char fname_in[sizeof(path_home)+45];
|
char fname_in[sizeof(path_home)+45];
|
||||||
char fname_out[sizeof(path_home)+15];
|
char fname_out[sizeof(path_home)+15];
|
||||||
char fname_temp[sizeof(path_home)+15];
|
|
||||||
char path[sizeof(path_home)+40]; // path_dsource+20
|
char path[sizeof(path_home)+40]; // path_dsource+20
|
||||||
|
|
||||||
CompileContext *ctx = calloc(1, sizeof(CompileContext));
|
CompileContext *ctx = calloc(1, sizeof(CompileContext));
|
||||||
@@ -1575,9 +1569,6 @@ ESPEAK_NG_API espeak_ng_STATUS espeak_ng_CompileDictionary(const char *dsource,
|
|||||||
clean_context(ctx);
|
clean_context(ctx);
|
||||||
return create_file_error_context(context, error, fname_out);
|
return create_file_error_context(context, error, fname_out);
|
||||||
}
|
}
|
||||||
/* Use dictionary-specific temp names to allow parallel compilation
|
|
||||||
* of multiple ductionaries. */
|
|
||||||
sprintf(fname_temp, "%s%c%stemp", path_home, PATHSEP, dict_name);
|
|
||||||
|
|
||||||
value = N_HASH_DICT;
|
value = N_HASH_DICT;
|
||||||
Write4Bytes(f_out, value);
|
Write4Bytes(f_out, value);
|
||||||
@@ -1602,7 +1593,7 @@ ESPEAK_NG_API espeak_ng_STATUS espeak_ng_CompileDictionary(const char *dsource,
|
|||||||
|
|
||||||
fprintf(ctx->f_log, "Compiling: '%s'\n", fname_in);
|
fprintf(ctx->f_log, "Compiling: '%s'\n", fname_in);
|
||||||
|
|
||||||
espeak_ng_STATUS status = compile_dictrules(ctx, f_in, f_out, fname_temp, context);
|
espeak_ng_STATUS status = compile_dictrules(ctx, f_in, f_out);
|
||||||
fclose(f_in);
|
fclose(f_in);
|
||||||
|
|
||||||
fseek(f_out, 4, SEEK_SET);
|
fseek(f_out, 4, SEEK_SET);
|
||||||
|
|||||||
Reference in New Issue
Block a user