Edinburgh Speech Tools 2.4-release
siodeditline.c
1/*************************************************************************/
2/* */
3/* Centre for Speech Technology Research */
4/* University of Edinburgh, UK */
5/* Copyright (c) 1996,1997 */
6/* All Rights Reserved. */
7/* */
8/* Permission is hereby granted, free of charge, to use and distribute */
9/* this software and its documentation without restriction, including */
10/* without limitation the rights to use, copy, modify, merge, publish, */
11/* distribute, sublicense, and/or sell copies of this work, and to */
12/* permit persons to whom this work is furnished to do so, subject to */
13/* the following conditions: */
14/* 1. The code must retain the above copyright notice, this list of */
15/* conditions and the following disclaimer. */
16/* 2. Any modifications must be clearly marked as such. */
17/* 3. Original authors' names are not deleted. */
18/* 4. The authors' names are not used to endorse or promote products */
19/* derived from this software without specific prior written */
20/* permission. */
21/* */
22/* THE UNIVERSITY OF EDINBURGH AND THE CONTRIBUTORS TO THIS WORK */
23/* DISCLAIM ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING */
24/* ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT */
25/* SHALL THE UNIVERSITY OF EDINBURGH NOR THE CONTRIBUTORS BE LIABLE */
26/* FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES */
27/* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN */
28/* AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, */
29/* ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF */
30/* THIS SOFTWARE. */
31/* */
32/*************************************************************************/
33/* Author : Alan W Black */
34/* Date : December 1998 */
35/*-----------------------------------------------------------------------*/
36/* */
37/* Due to incompatibility between the GPL for readline and Festival's */
38/* current licence readline support was removed after 1.3.0 */
39/* This uses a much simpler but much poorer command line editor called */
40/* editline instead. */
41/* */
42/* Although this code is included in our distribution we still offer */
43/* optional compilation as it may not work on all platforms */
44/* */
45/*=======================================================================*/
46#include <stdio.h>
47#include <stdlib.h>
48#include "EST_unix.h"
49#include <string.h>
50#include "EST_cutils.h"
51#include "siodeditline.h"
52
53FILE *stddebug = NULL;
54extern int el_pos;
55extern char *repl_prompt;
56
57#ifndef SUPPORT_EDITLINE
58
59/* If for some reason you don't want editline the following */
60/* functions are provided. They are functional but minimal. They are */
61/* suitable when you are in an embedded environment and don't need */
62/* command lin editing */
63int el_no_echo;
64int editline_histsize;
65
66int siod_el_getc(FILE *f)
67{
68 int c;
69
70 if (el_pos == -1)
71 {
72 fprintf(stdout,"%s",repl_prompt);
73 fflush(stdout);
74 el_pos = 0;
75 }
76
77 c = getc(f);
78
79 if (c == '\n')
80 el_pos = -1;
81
82 return c;
83}
84
85void siod_el_ungetc(int c, FILE *f)
86{
87 ungetc(c,f);
88}
89
90void siod_el_init(void)
91{
92 return;
93}
94#else
95#include "editline.h"
96
97static int possible_commandp(char *text, int start, int end);
98static int possible_variablep(char *text, int start, int end);
99static char **command_completion (char *text,int start,int end);
100
101static char *el_line = NULL;
102
103char *editline_history_file = ".editline_history";
104static char *full_history_file = ".editline_history";
105
106static STATUS siod_display_doc ()
107{
108 /* Find the current symbol and check for a documentation string */
109 char *symbol;
110 const char *docstring;
111 int i;
112
113 symbol = el_current_sym();
114 putc('\n',stderr);
115 docstring = siod_docstring(symbol);
116 for (i=0; docstring[i] != '\0'; i++)
117 putc(docstring[i],stderr);
118 putc('\n',stderr);
119 fflush(stderr);
120 wfree(symbol);
121 el_redisplay();
122 return CSmove;
123}
124
125static STATUS siod_say_doc ()
126{
127 /* Find the current symbol and check for a documentation string */
128 /* Now this is what you call wasting your time. Here we get the */
129 /* synthesizer to say the documentation string */
130 char *symbol;
131
132 symbol = el_current_sym();
133 fprintf(stderr,"\nsynthesizing doc string ...");
134 fflush(stderr);
135 siod_saydocstring(symbol);
136 putc('\n',stderr);
137 fflush(stderr);
138 wfree(symbol);
139 el_redisplay();
140 return CSmove;
141}
142
143static STATUS siod_manual()
144{
145 /* Find the current symbol and check for a documentation string */
146 /* Look for a "see " reference in its documentation string, if so */
147 /* access that section of the manual by sending a call to netscape */
148 char *symbol;
149 const char *infostring;
150
151 symbol = el_current_sym();
152 infostring = siod_manual_sym(symbol);
153 putc('\n',stderr);
154 fprintf(stderr,"%s",infostring);
155 fflush(stderr);
156 putc('\n',stderr);
157 fflush(stderr);
158 el_redisplay();
159 wfree(symbol);
160 return CSmove;
161}
162
163void siod_el_init(void)
164{
165 /* Various initialization completion, history etc */
166 char *home;
167
168 home = getenv("HOME");
169 if (home==NULL)
170 home="";
171 full_history_file =
172 walloc(char,strlen(home)+strlen(editline_history_file)+2);
173 sprintf(full_history_file,"%s/%s",home,editline_history_file);
174 read_history(full_history_file);
175 el_user_intr = TRUE; /* we want SIGINT to raise a signal */
176
177 el_user_completion_function = command_completion;
178 el_bind_key_in_metamap('h',siod_display_doc);
179 el_bind_key_in_metamap('s',siod_say_doc);
180 el_bind_key_in_metamap('m',siod_manual);
181}
182
183int siod_el_getc(FILE *f)
184{
185 int c;
186
187 if (el_pos == -1)
188 {
189 el_line=readline(repl_prompt);
190 if (el_line != NULL)
191 {
192 add_history(el_line);
193 write_history(full_history_file);
194 }
195 el_pos = 0;
196 }
197 if ((el_line==NULL) ||
198 (strlen(el_line) <= el_pos))
199 el_pos = -1;
200 if (el_line==NULL)
201 c = EOF;
202 else if (el_pos == -1)
203 c = '\n'; /* whitespace representing end of line */
204 else
205 {
206 c = el_line[el_pos];
207 el_pos++;
208 }
209
210 return c;
211}
212
213void siod_el_ungetc(int c, FILE *f)
214{
215 if (el_pos > 0)
216 el_pos--;
217 else
218 {
219 fprintf(stderr,"fix ungetc when nothing is there");
220 }
221}
222
223static int qsort_str_compare(const void *p1,const void *p2)
224{
225 const char *s1;
226 const char *s2;
227
228 s1 = *(const char **)p1;
229 s2 = *(const char **)p2;
230
231 return strcmp(s1,s2);
232}
233
234static char **command_completion (char *text,int start,int end)
235{
236 char **matches = NULL;
237 int i;
238
239 /* If preceding non-alphanum character is a left paren, */
240 /* look for a command else look for any variable */
241 if (possible_commandp(text,start,end))
242 matches = siod_command_generator(text+start,end-start);
243 else if (possible_variablep(text,start,end))
244 matches = siod_variable_generator(text+start,end-start);
245
246 if (matches && matches[0] && matches[1])
247 {
248 /* If there are at least two, Sort them */
249 for (i=0; matches[i] != NULL; i++);
250 qsort(matches,i,sizeof(char **),qsort_str_compare);
251 }
252
253 return matches;
254}
255
256static int possible_commandp(char *text, int start, int end)
257{
258 /* If non-white space previous to this is a left paren */
259 /* signal we are looking for a function name */
260 int t;
261
262 for (t=start-1; t >= 0; t--)
263 if (strchr(" \t\n\r",text[t]) != NULL)
264 continue;
265 else if (text[t] == '(')
266 return TRUE;
267 else
268 return FALSE;
269
270 return FALSE;
271}
272
273static int possible_variablep(char *text, int start, int end)
274{
275 /* Almost negative of above but if previous symbol is a quote */
276 /* let the file completion stuff do it */
277 int t;
278
279 for (t=start-1; t >= 0; t--)
280 if (strchr(" \t\n",text[t]) != NULL)
281 continue;
282 else if (text[t] == '(')
283 return FALSE;
284 else if ((text[t] == '"') &&
285 (t == start-1))
286 return FALSE;
287 else
288 return TRUE;
289
290 return TRUE;
291}
292
293#endif /* SUPPORT_EDITLINE */