summaryrefslogtreecommitdiff
path: root/navit/speech/cmdline/speech_cmdline.c
diff options
context:
space:
mode:
Diffstat (limited to 'navit/speech/cmdline/speech_cmdline.c')
-rw-r--r--navit/speech/cmdline/speech_cmdline.c392
1 files changed, 187 insertions, 205 deletions
diff --git a/navit/speech/cmdline/speech_cmdline.c b/navit/speech/cmdline/speech_cmdline.c
index 490811ce5..11537e570 100644
--- a/navit/speech/cmdline/speech_cmdline.c
+++ b/navit/speech/cmdline/speech_cmdline.c
@@ -38,228 +38,210 @@
#endif
-static char *urldecode(char *str)
-{
- char *ret=g_strdup(str);
- char *src=ret;
- char *dst=ret;
- while (*src) {
- if (*src == '%') {
- int val;
- if (sscanf(src+1,"%02x",&val)) {
- src+=2;
- *dst++=val;
- }
- src++;
- } else
- *dst++=*src++;
- }
- *dst++='\0';
- return ret;
+static char *urldecode(char *str) {
+ char *ret=g_strdup(str);
+ char *src=ret;
+ char *dst=ret;
+ while (*src) {
+ if (*src == '%') {
+ int val;
+ if (sscanf(src+1,"%02x",&val)) {
+ src+=2;
+ *dst++=val;
+ }
+ src++;
+ } else
+ *dst++=*src++;
+ }
+ *dst++='\0';
+ return ret;
}
-static GList *
-speech_cmdline_search(GList *samples, int suffix_len, const char *text, int decode)
-{
- GList *loop_samples=samples,*result=NULL,*recursion_result;
- int shortest_result_length=INT_MAX;
- dbg(lvl_debug,"searching samples for text: '%s'\n",text);
- while (loop_samples) {
- char *sample_name=loop_samples->data;
- int sample_name_len;
- if (decode)
- sample_name=urldecode(sample_name);
- sample_name_len=strlen(sample_name)-suffix_len;
- // TODO: Here we compare UTF-8 text with a filename.
- // It's unclear how a case-insensitive comparison should work
- // in general, so for now we only do it for ASCII text.
- if (!g_ascii_strncasecmp(text, sample_name, sample_name_len)) {
- const char *remaining_text=text+sample_name_len;
- while (*remaining_text == ' ' || *remaining_text == ',')
- remaining_text++;
- dbg(lvl_debug,"sample '%s' matched; remaining text: '%s'\n",sample_name,remaining_text);
- if (*remaining_text) {
- recursion_result=speech_cmdline_search(samples, suffix_len, remaining_text, decode);
- if (recursion_result && g_list_length(recursion_result) < shortest_result_length) {
- g_list_free(result);
- result=recursion_result;
- result=g_list_prepend(result, loop_samples->data);
- shortest_result_length=g_list_length(result);
- } else {
- dbg(lvl_debug,"no (shorter) result found for remaining text '%s', "
- "trying next sample\n", remaining_text);
- g_list_free(recursion_result);
- }
- } else {
- g_list_free(result);
- result=g_list_prepend(NULL, loop_samples->data);
- break;
- }
- }
- if (decode)
- g_free(sample_name);
- loop_samples=g_list_next(loop_samples);
- }
- return result;
+static GList *speech_cmdline_search(GList *samples, int suffix_len, const char *text, int decode) {
+ GList *loop_samples=samples,*result=NULL,*recursion_result;
+ int shortest_result_length=INT_MAX;
+ dbg(lvl_debug,"searching samples for text: '%s'",text);
+ while (loop_samples) {
+ char *sample_name=loop_samples->data;
+ int sample_name_len;
+ if (decode)
+ sample_name=urldecode(sample_name);
+ sample_name_len=strlen(sample_name)-suffix_len;
+ // TODO: Here we compare UTF-8 text with a filename.
+ // It's unclear how a case-insensitive comparison should work
+ // in general, so for now we only do it for ASCII text.
+ if (!g_ascii_strncasecmp(text, sample_name, sample_name_len)) {
+ const char *remaining_text=text+sample_name_len;
+ while (*remaining_text == ' ' || *remaining_text == ',')
+ remaining_text++;
+ dbg(lvl_debug,"sample '%s' matched; remaining text: '%s'",sample_name,remaining_text);
+ if (*remaining_text) {
+ recursion_result=speech_cmdline_search(samples, suffix_len, remaining_text, decode);
+ if (recursion_result && g_list_length(recursion_result) < shortest_result_length) {
+ g_list_free(result);
+ result=recursion_result;
+ result=g_list_prepend(result, loop_samples->data);
+ shortest_result_length=g_list_length(result);
+ } else {
+ dbg(lvl_debug,"no (shorter) result found for remaining text '%s', "
+ "trying next sample\n", remaining_text);
+ g_list_free(recursion_result);
+ }
+ } else {
+ g_list_free(result);
+ result=g_list_prepend(NULL, loop_samples->data);
+ break;
+ }
+ }
+ if (decode)
+ g_free(sample_name);
+ loop_samples=g_list_next(loop_samples);
+ }
+ return result;
}
-#if 0
-
- r=search(l, strlen(path)+1, suffix_len, argv[1]);
- while (r) {
- printf("%s/%s\n",path,r->data);
- r=g_list_next(r);
- }
- return 0;
-#endif
struct speech_priv {
- char *cmdline;
- char *sample_dir;
- char *sample_suffix;
- int flags;
- GList *samples;
- struct spawn_process_info *spi;
+ char *cmdline;
+ char *sample_dir;
+ char *sample_suffix;
+ int flags;
+ GList *samples;
+ struct spawn_process_info *spi;
};
-static int
-speechd_say(struct speech_priv *this, const char *text)
-{
- char **cmdv=g_strsplit(this->cmdline," ", -1);
- int variable_arg_no=-1;
- GList *argl=NULL;
- guint listlen;
- int samplesmode=0;
- int i;
-
- for(i=0;cmdv[i];i++)
- if(strchr(cmdv[i],'%')) {
- variable_arg_no=i;
- break;
- }
-
- if (this->sample_dir && this->sample_suffix) {
- argl=speech_cmdline_search(this->samples, strlen(this->sample_suffix), text, !!(this->flags & 1));
- samplesmode=1;
- listlen=g_list_length(argl);
- dbg(lvl_debug,"For text: '%s', found %d samples.\n",text,listlen);
- if (!listlen){
- dbg(lvl_error,"No matching samples found. Cannot speak text: '%s'\n",text);
- }
- } else {
- listlen=1;
- }
- if(listlen>0) {
- dbg(lvl_debug,"Speaking text '%s'\n",text);
- int argc;
- char**argv;
- int j;
- int cmdvlen=g_strv_length(cmdv);
- argc=cmdvlen + listlen - (variable_arg_no>0?1:0);
- argv=g_new(char *,argc+1);
- if(variable_arg_no==-1) {
- argv[cmdvlen]=g_strdup("%s");
- variable_arg_no=cmdvlen;
- }
-
- for(i=0,j=0;j<argc;) {
- if( i==variable_arg_no ) {
- if (samplesmode) {
- GList *l=argl;
- while(l) {
- char *new_arg;
- new_arg=g_strdup_printf("%s/%s",this->sample_dir,(char *)l->data);
- dbg(lvl_debug,"new_arg %s\n",new_arg);
- argv[j++]=g_strdup_printf(cmdv[i],new_arg);
- g_free(new_arg);
- l=g_list_next(l);
- }
- } else {
- argv[j++]=g_strdup_printf(cmdv[i],text);
- }
- i++;
- } else {
- argv[j++]=g_strdup(cmdv[i++]);
- }
- }
- argv[j]=NULL;
- if (argl)
- // No need to free data elements here as they are
- // still referenced from this->samples
- g_list_free(argl);
+static int speechd_say(struct speech_priv *this, const char *text) {
+ char **cmdv=g_strsplit(this->cmdline," ", -1);
+ int variable_arg_no=-1;
+ GList *argl=NULL;
+ guint listlen;
+ int samplesmode=0;
+ int i;
+
+ for(i=0; cmdv[i]; i++)
+ if(strchr(cmdv[i],'%')) {
+ variable_arg_no=i;
+ break;
+ }
+
+ if (this->sample_dir && this->sample_suffix) {
+ argl=speech_cmdline_search(this->samples, strlen(this->sample_suffix), text, !!(this->flags & 1));
+ samplesmode=1;
+ listlen=g_list_length(argl);
+ dbg(lvl_debug,"For text: '%s', found %d samples.",text,listlen);
+ if (!listlen) {
+ dbg(lvl_error,"No matching samples found. Cannot speak text: '%s'",text);
+ }
+ } else {
+ listlen=1;
+ }
+ if(listlen>0) {
+ dbg(lvl_debug,"Speaking text '%s'",text);
+ int argc;
+ char**argv;
+ int j;
+ int cmdvlen=g_strv_length(cmdv);
+ argc=cmdvlen + listlen - (variable_arg_no>0?1:0);
+ argv=g_new(char *,argc+1);
+ if(variable_arg_no==-1) {
+ argv[cmdvlen]=g_strdup("%s");
+ variable_arg_no=cmdvlen;
+ }
+
+ for(i=0,j=0; j<argc;) {
+ if( i==variable_arg_no ) {
+ if (samplesmode) {
+ GList *l=argl;
+ while(l) {
+ char *new_arg;
+ new_arg=g_strdup_printf("%s/%s",this->sample_dir,(char *)l->data);
+ dbg(lvl_debug,"new_arg %s",new_arg);
+ argv[j++]=g_strdup_printf(cmdv[i],new_arg);
+ g_free(new_arg);
+ l=g_list_next(l);
+ }
+ } else {
+ argv[j++]=g_strdup_printf(cmdv[i],text);
+ }
+ i++;
+ } else {
+ argv[j++]=g_strdup(cmdv[i++]);
+ }
+ }
+ argv[j]=NULL;
+ if (argl)
+ // No need to free data elements here as they are
+ // still referenced from this->samples
+ g_list_free(argl);
- if(this->spi) {
- spawn_process_check_status(this->spi,1); // Block until previous spawned speech process is terminated.
- spawn_process_info_free(this->spi);
- }
- this->spi=spawn_process(argv);
- g_strfreev(argv);
- }
- g_strfreev(cmdv);
- return 0;
+ if(this->spi) {
+ spawn_process_check_status(this->spi,1); // Block until previous spawned speech process is terminated.
+ spawn_process_info_free(this->spi);
+ }
+ this->spi=spawn_process(argv);
+ g_strfreev(argv);
+ }
+ g_strfreev(cmdv);
+ return 0;
}
-static void
-speechd_destroy(struct speech_priv *this) {
- GList *l=this->samples;
- g_free(this->cmdline);
- g_free(this->sample_dir);
- g_free(this->sample_suffix);
- while(l) {
- g_free(l->data);
- }
- g_list_free(this->samples);
- if(this->spi)
- spawn_process_info_free(this->spi);
- g_free(this);
+static void speechd_destroy(struct speech_priv *this) {
+ GList *l=this->samples;
+ g_free(this->cmdline);
+ g_free(this->sample_dir);
+ g_free(this->sample_suffix);
+ while(l) {
+ g_free(l->data);
+ }
+ g_list_free(this->samples);
+ if(this->spi)
+ spawn_process_info_free(this->spi);
+ g_free(this);
}
static struct speech_methods speechd_meth = {
- speechd_destroy,
- speechd_say,
+ speechd_destroy,
+ speechd_say,
};
-static struct speech_priv *
-speechd_new(struct speech_methods *meth, struct attr **attrs, struct attr *parent) {
- struct speech_priv *this;
- struct attr *attr;
- attr=attr_search(attrs, NULL, attr_data);
- if (! attr)
- return NULL;
- this=g_new0(struct speech_priv,1);
- this->cmdline=g_strdup(attr->u.str);
- if ((attr=attr_search(attrs, NULL, attr_sample_dir)))
- this->sample_dir=g_strdup(attr->u.str);
- if ((attr=attr_search(attrs, NULL, attr_sample_suffix)))
- this->sample_suffix=g_strdup(attr->u.str);
- if ((attr=attr_search(attrs, NULL, attr_flags)))
- this->flags=attr->u.num;
- if (this->sample_dir && this->sample_suffix) {
- void *handle=file_opendir(this->sample_dir);
- if (!handle) {
- dbg(lvl_error,"Cannot read sample directory contents: %s", this->sample_dir);
- return NULL;
- }
- char *name;
- int suffix_len=strlen(this->sample_suffix);
- while((name=file_readdir(handle))) {
- int len=strlen(name);
- if (len > suffix_len) {
- if (!strcmp(name+len-suffix_len, this->sample_suffix)) {
- dbg(lvl_debug,"found %s\n",name);
- this->samples=g_list_prepend(this->samples, g_strdup(name));
- }
- }
- }
- file_closedir(handle);
- }
- *meth=speechd_meth;
- return this;
+static struct speech_priv *speechd_new(struct speech_methods *meth, struct attr **attrs, struct attr *parent) {
+ struct speech_priv *this;
+ struct attr *attr;
+ attr=attr_search(attrs, NULL, attr_data);
+ if (! attr)
+ return NULL;
+ this=g_new0(struct speech_priv,1);
+ this->cmdline=g_strdup(attr->u.str);
+ if ((attr=attr_search(attrs, NULL, attr_sample_dir)))
+ this->sample_dir=g_strdup(attr->u.str);
+ if ((attr=attr_search(attrs, NULL, attr_sample_suffix)))
+ this->sample_suffix=g_strdup(attr->u.str);
+ if ((attr=attr_search(attrs, NULL, attr_flags)))
+ this->flags=attr->u.num;
+ if (this->sample_dir && this->sample_suffix) {
+ void *handle=file_opendir(this->sample_dir);
+ if (!handle) {
+ dbg(lvl_error,"Cannot read sample directory contents: %s", this->sample_dir);
+ return NULL;
+ }
+ char *name;
+ int suffix_len=strlen(this->sample_suffix);
+ while((name=file_readdir(handle))) {
+ int len=strlen(name);
+ if (len > suffix_len) {
+ if (!strcmp(name+len-suffix_len, this->sample_suffix)) {
+ dbg(lvl_debug,"found %s",name);
+ this->samples=g_list_prepend(this->samples, g_strdup(name));
+ }
+ }
+ }
+ file_closedir(handle);
+ }
+ *meth=speechd_meth;
+ return this;
}
-void
-plugin_init(void)
-{
- plugin_register_category_speech("cmdline", speechd_new);
+void plugin_init(void) {
+ plugin_register_category_speech("cmdline", speechd_new);
}