speech-tools/siod/siodeditline.c
2015-09-19 10:52:26 +02:00

294 lines
8.9 KiB
C

/*************************************************************************/
/* */
/* Centre for Speech Technology Research */
/* University of Edinburgh, UK */
/* Copyright (c) 1996,1997 */
/* All Rights Reserved. */
/* */
/* Permission is hereby granted, free of charge, to use and distribute */
/* this software and its documentation without restriction, including */
/* without limitation the rights to use, copy, modify, merge, publish, */
/* distribute, sublicense, and/or sell copies of this work, and to */
/* permit persons to whom this work is furnished to do so, subject to */
/* the following conditions: */
/* 1. The code must retain the above copyright notice, this list of */
/* conditions and the following disclaimer. */
/* 2. Any modifications must be clearly marked as such. */
/* 3. Original authors' names are not deleted. */
/* 4. The authors' names are not used to endorse or promote products */
/* derived from this software without specific prior written */
/* permission. */
/* */
/* THE UNIVERSITY OF EDINBURGH AND THE CONTRIBUTORS TO THIS WORK */
/* DISCLAIM ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING */
/* ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT */
/* SHALL THE UNIVERSITY OF EDINBURGH NOR THE CONTRIBUTORS BE LIABLE */
/* FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES */
/* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN */
/* AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, */
/* ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF */
/* THIS SOFTWARE. */
/* */
/*************************************************************************/
/* Author : Alan W Black */
/* Date : December 1998 */
/*-----------------------------------------------------------------------*/
/* */
/* Due to incompatibility between the GPL for readline and Festival's */
/* current licence readline support was removed after 1.3.0 */
/* This uses a much simpler but much poorer command line editor called */
/* editline instead. */
/* */
/* Although this code is included in our distribution we still offer */
/* optional compilation as it may not work on all platforms */
/* */
/*=======================================================================*/
#include <stdio.h>
#include <stdlib.h>
#include "EST_unix.h"
#include <string.h>
#include "EST_cutils.h"
#include "siodeditline.h"
FILE *stddebug = NULL;
extern int el_pos;
extern char *repl_prompt;
#ifndef SUPPORT_EDITLINE
/* If for some reason you don't want editline the following */
/* functions are provided. They are functional but minimal. They are */
/* suitable when you are in an embedded environment and don't need */
/* command lin editing */
int el_no_echo;
int editline_histsize;
int siod_el_getc(FILE *f)
{
int c;
if (el_pos == -1)
{
fprintf(stdout,"%s",repl_prompt);
fflush(stdout);
el_pos = 0;
}
c = getc(f);
if (c == '\n')
el_pos = -1;
return c;
}
void siod_el_ungetc(int c, FILE *f)
{
ungetc(c,f);
}
void siod_el_init(void)
{
return;
}
#else
#include "editline.h"
static int possible_commandp(char *text, int start, int end);
static int possible_variablep(char *text, int start, int end);
static char **command_completion (char *text,int start,int end);
static char *el_line = NULL;
char *editline_history_file = ".editline_history";
static char *full_history_file = ".editline_history";
static STATUS siod_display_doc ()
{
/* Find the current symbol and check for a documentation string */
char *symbol;
const char *docstring;
int i;
symbol = el_current_sym();
putc('\n',stderr);
docstring = siod_docstring(symbol);
for (i=0; docstring[i] != '\0'; i++)
putc(docstring[i],stderr);
putc('\n',stderr);
fflush(stderr);
wfree(symbol);
el_redisplay();
return CSmove;
}
static STATUS siod_say_doc ()
{
/* Find the current symbol and check for a documentation string */
/* Now this is what you call wasting your time. Here we get the */
/* synthesizer to say the documentation string */
char *symbol;
symbol = el_current_sym();
fprintf(stderr,"\nsynthesizing doc string ...");
fflush(stderr);
siod_saydocstring(symbol);
putc('\n',stderr);
fflush(stderr);
wfree(symbol);
el_redisplay();
return CSmove;
}
static STATUS siod_manual()
{
/* Find the current symbol and check for a documentation string */
/* Look for a "see " reference in its documentation string, if so */
/* access that section of the manual by sending a call to netscape */
char *symbol;
const char *infostring;
symbol = el_current_sym();
infostring = siod_manual_sym(symbol);
putc('\n',stderr);
fprintf(stderr,"%s",infostring);
fflush(stderr);
putc('\n',stderr);
fflush(stderr);
el_redisplay();
wfree(symbol);
return CSmove;
}
void siod_el_init(void)
{
/* Various initialization completion, history etc */
char *home;
home = getenv("HOME");
if (home==NULL)
home="";
full_history_file =
walloc(char,strlen(home)+strlen(editline_history_file)+2);
sprintf(full_history_file,"%s/%s",home,editline_history_file);
read_history(full_history_file);
el_user_intr = TRUE; /* we want SIGINT to raise a signal */
el_user_completion_function = command_completion;
el_bind_key_in_metamap('h',siod_display_doc);
el_bind_key_in_metamap('s',siod_say_doc);
el_bind_key_in_metamap('m',siod_manual);
}
int siod_el_getc(FILE *f)
{
int c;
if (el_pos == -1)
{
el_line=readline(repl_prompt);
if (el_line != NULL)
{
add_history(el_line);
write_history(full_history_file);
}
el_pos = 0;
}
if ((el_line==NULL) ||
(strlen(el_line) <= el_pos))
el_pos = -1;
if (el_line==NULL)
c = EOF;
else if (el_pos == -1)
c = '\n'; /* whitespace representing end of line */
else
{
c = el_line[el_pos];
el_pos++;
}
return c;
}
void siod_el_ungetc(int c, FILE *f)
{
if (el_pos > 0)
el_pos--;
else
{
fprintf(stderr,"fix ungetc when nothing is there");
}
}
static int qsort_str_compare(const void *p1,const void *p2)
{
const char *s1;
const char *s2;
s1 = *(const char **)p1;
s2 = *(const char **)p2;
return strcmp(s1,s2);
}
static char **command_completion (char *text,int start,int end)
{
char **matches = NULL;
int i;
/* If preceding non-alphanum character is a left paren, */
/* look for a command else look for any variable */
if (possible_commandp(text,start,end))
matches = siod_command_generator(text+start,end-start);
else if (possible_variablep(text,start,end))
matches = siod_variable_generator(text+start,end-start);
if (matches && matches[0] && matches[1])
{
/* If there are at least two, Sort them */
for (i=0; matches[i] != NULL; i++);
qsort(matches,i,sizeof(char **),qsort_str_compare);
}
return matches;
}
static int possible_commandp(char *text, int start, int end)
{
/* If non-white space previous to this is a left paren */
/* signal we are looking for a function name */
int t;
for (t=start-1; t >= 0; t--)
if (strchr(" \t\n\r",text[t]) != NULL)
continue;
else if (text[t] == '(')
return TRUE;
else
return FALSE;
return FALSE;
}
static int possible_variablep(char *text, int start, int end)
{
/* Almost negative of above but if previous symbol is a quote */
/* let the file completion stuff do it */
int t;
for (t=start-1; t >= 0; t--)
if (strchr(" \t\n",text[t]) != NULL)
continue;
else if (text[t] == '(')
return FALSE;
else if ((text[t] == '"') &&
(t == start-1))
return FALSE;
else
return TRUE;
return TRUE;
}
#endif /* SUPPORT_EDITLINE */