void fsg_arciter_free(fsg_arciter_t * itor) { if (itor == NULL) return; hash_table_iter_free(itor->null_itor); hash_table_iter_free(itor->itor); ckd_free(itor); }
int ps_load_dict(ps_decoder_t *ps, char const *dictfile, char const *fdictfile, char const *format) { cmd_ln_t *newconfig; dict2pid_t *d2p; dict_t *dict; hash_iter_t *search_it; /* Create a new scratch config to load this dict (so existing one * won't be affected if it fails) */ newconfig = cmd_ln_init(NULL, ps_args(), TRUE, NULL); cmd_ln_set_boolean_r(newconfig, "-dictcase", cmd_ln_boolean_r(ps->config, "-dictcase")); cmd_ln_set_str_r(newconfig, "-dict", dictfile); if (fdictfile) cmd_ln_set_str_r(newconfig, "-fdict", fdictfile); else cmd_ln_set_str_r(newconfig, "-fdict", cmd_ln_str_r(ps->config, "-fdict")); /* Try to load it. */ if ((dict = dict_init(newconfig, ps->acmod->mdef, ps->acmod->lmath)) == NULL) { cmd_ln_free_r(newconfig); return -1; } /* Reinit the dict2pid. */ if ((d2p = dict2pid_build(ps->acmod->mdef, dict)) == NULL) { cmd_ln_free_r(newconfig); return -1; } /* Success! Update the existing config to reflect new dicts and * drop everything into place. */ cmd_ln_free_r(newconfig); cmd_ln_set_str_r(ps->config, "-dict", dictfile); if (fdictfile) cmd_ln_set_str_r(ps->config, "-fdict", fdictfile); dict_free(ps->dict); ps->dict = dict; dict2pid_free(ps->d2p); ps->d2p = d2p; /* And tell all searches to reconfigure themselves. */ for (search_it = hash_table_iter(ps->searches); search_it; search_it = hash_table_iter_next(search_it)) { if (ps_search_reinit(hash_entry_val(search_it->ent), dict, d2p) < 0) { hash_table_iter_free(search_it); return -1; } } return 0; }
int ps_add_word(ps_decoder_t *ps, char const *word, char const *phones, int update) { int32 wid; s3cipid_t *pron; hash_iter_t *search_it; char **phonestr, *tmp; int np, i, rv; /* Parse phones into an array of phone IDs. */ tmp = ckd_salloc(phones); np = str2words(tmp, NULL, 0); phonestr = ckd_calloc(np, sizeof(*phonestr)); str2words(tmp, phonestr, np); pron = ckd_calloc(np, sizeof(*pron)); for (i = 0; i < np; ++i) { pron[i] = bin_mdef_ciphone_id(ps->acmod->mdef, phonestr[i]); if (pron[i] == -1) { E_ERROR("Unknown phone %s in phone string %s\n", phonestr[i], tmp); ckd_free(phonestr); ckd_free(tmp); ckd_free(pron); return -1; } } /* No longer needed. */ ckd_free(phonestr); ckd_free(tmp); /* Add it to the dictionary. */ if ((wid = dict_add_word(ps->dict, word, pron, np)) == -1) { ckd_free(pron); return -1; } /* No longer needed. */ ckd_free(pron); /* Now we also have to add it to dict2pid. */ dict2pid_add_word(ps->d2p, wid); /* TODO: we definitely need to refactor this */ for (search_it = hash_table_iter(ps->searches); search_it; search_it = hash_table_iter_next(search_it)) { ps_search_t *search = hash_entry_val(search_it->ent); if (!strcmp(PS_SEARCH_NGRAM, ps_search_name(search))) { ngram_model_t *lmset = ((ngram_search_t *) search)->lmset; if (ngram_model_add_word(lmset, word, 1.0) == NGRAM_INVALID_WID) { hash_table_iter_free(search_it); return -1; } } if (update) { if ((rv = ps_search_reinit(search, ps->dict, ps->d2p) < 0)) { hash_table_iter_free(search_it); return rv; } } } /* Rebuild the widmap and search tree if requested. */ return wid; }
void ps_search_iter_free(ps_search_iter_t *itor) { hash_table_iter_free((hash_iter_t *)itor); }
jsgf_rule_t * jsgf_import_rule(jsgf_t * jsgf, char *name) { char *c, *path, *newpath; size_t namelen, packlen; void *val; jsgf_t *imp; int import_all; /* Trim the leading and trailing <> */ namelen = strlen(name); path = ckd_malloc(namelen - 2 + 6); /* room for a trailing .gram */ strcpy(path, name + 1); /* Split off the first part of the name */ c = strrchr(path, '.'); if (c == NULL) { E_ERROR("Imported rule is not qualified: %s\n", name); ckd_free(path); return NULL; } packlen = c - path; *c = '\0'; /* Look for import foo.* */ import_all = (strlen(name) > 2 && 0 == strcmp(name + namelen - 3, ".*>")); /* Construct a filename. */ for (c = path; *c; ++c) if (*c == '.') *c = '/'; strcat(path, ".gram"); newpath = path_list_search(jsgf->searchpath, path); if (newpath == NULL) { E_ERROR("Failed to find grammar %s\n", path); ckd_free(path); return NULL; } ckd_free(path); path = newpath; E_INFO("Importing %s from %s to %s\n", name, path, jsgf->name); /* FIXME: Also, we need to make sure that path is fully qualified * here, by adding any prefixes from jsgf->name to it. */ /* See if we have parsed it already */ if (hash_table_lookup(jsgf->imports, path, &val) == 0) { E_INFO("Already imported %s\n", path); imp = val; ckd_free(path); } else { /* If not, parse it. */ imp = jsgf_parse_file(path, jsgf); val = hash_table_enter(jsgf->imports, path, imp); if (val != (void *) imp) { E_WARN("Multiply imported file: %s\n", path); } } if (imp != NULL) { hash_iter_t *itor; /* Look for public rules matching rulename. */ for (itor = hash_table_iter(imp->rules); itor; itor = hash_table_iter_next(itor)) { hash_entry_t *he = itor->ent; jsgf_rule_t *rule = hash_entry_val(he); int rule_matches; char *rule_name = importname2rulename(name); if (import_all) { /* Match package name (symbol table is shared) */ rule_matches = !strncmp(rule_name, rule->name, packlen + 1); } else { /* Exact match */ rule_matches = !strcmp(rule_name, rule->name); } ckd_free(rule_name); if (rule->is_public && rule_matches) { void *val; char *newname; /* Link this rule into the current namespace. */ c = strrchr(rule->name, '.'); assert(c != NULL); newname = jsgf_fullname(jsgf, c); E_INFO("Imported %s\n", newname); val = hash_table_enter(jsgf->rules, newname, jsgf_rule_retain(rule)); if (val != (void *) rule) { E_WARN("Multiply defined symbol: %s\n", newname); } if (!import_all) { hash_table_iter_free(itor); return rule; } } } } return NULL; }