diff options
author | Karl Berry <karl@freefriends.org> | 2009-05-16 00:19:13 +0000 |
---|---|---|
committer | Karl Berry <karl@freefriends.org> | 2009-05-16 00:19:13 +0000 |
commit | bab45528d65eaafe68a705dbb2a57075c7b7cbd8 (patch) | |
tree | 10b4ae2b5195c8dede153ab89359ec00f55f325f /Build/source/utils/asymptote/interact.cc | |
parent | 8643d90372e9c31e0f461c15c596b60a545bd7d3 (diff) |
asymptote 1.72 sources (not integrated into build yet)
git-svn-id: svn://tug.org/texlive/trunk@13110 c570f23f-e606-0410-a88d-b1316a301751
Diffstat (limited to 'Build/source/utils/asymptote/interact.cc')
-rw-r--r-- | Build/source/utils/asymptote/interact.cc | 197 |
1 files changed, 197 insertions, 0 deletions
diff --git a/Build/source/utils/asymptote/interact.cc b/Build/source/utils/asymptote/interact.cc new file mode 100644 index 00000000000..43c7184ffe2 --- /dev/null +++ b/Build/source/utils/asymptote/interact.cc @@ -0,0 +1,197 @@ +/***** + * interact.cc + * + * The glue between the lexical analyzer and the readline library. + *****/ + +#include <cstdlib> +#include <cassert> +#include <iostream> +#include <sstream> +#include <sys/wait.h> +#include <sys/types.h> +#include <unistd.h> +#include <csignal> + +#include "interact.h" + +#if defined(HAVE_LIBREADLINE) && defined(HAVE_LIBCURSES) +#include <readline/readline.h> +#include <readline/history.h> +#endif + +#include "util.h" +#include "errormsg.h" + +using namespace settings; + +namespace run { +void init_readline(bool); +} + +namespace interact { + +bool interactive=false; +bool uptodate=true; +int lines=0; +bool query=false; + +bool tty=isatty(STDIN_FILENO); +completer *currentCompleter=0; + +void setCompleter(completer *c) { + currentCompleter=c; +} + +char *call_completer(const char *text, int state) { + return currentCompleter ? (*currentCompleter)(text, state) : 0; +} + +#if defined(HAVE_LIBREADLINE) && defined(HAVE_LIBCURSES) +void init_completion() { + rl_completion_entry_function=call_completer; + + rl_completion_append_character='\0'; // Don't add a space after a match. + + // Build a string containing all characters that separate words to be + // completed. All characters that can't form part of an identifier are + // treated as break characters. + static char break_characters[128]; + Int j=0; + for (unsigned char c=9; c<128; ++c) + if (!isalnum(c) && c != '_') { + break_characters[j]=c; + ++j; + } + break_characters[j]='\0'; + rl_completer_word_break_characters=break_characters; +} +#endif + +char *(*Readline)(const char *prompt); + +char *verbatimreadline(const char *prompt) +{ + if(!cin.good()) {cin.clear(); return NULL;} + cout << prompt; + string s; + getline(cin,s); + return StrdupMalloc(s); +} + +void pre_readline() +{ +#if defined(HAVE_LIBREADLINE) && defined(HAVE_LIBCURSES) + if(tty) { + run::init_readline(getSetting<bool>("tabcompletion")); + Readline=readline; + } else +#endif + Readline=verbatimreadline; +} + +void init_interactive() +{ +#if defined(HAVE_LIBREADLINE) && defined(HAVE_LIBCURSES) + if(tty) { + init_completion(); + read_history(historyname.c_str()); + } +#endif +} + +string simpleline(string prompt) { + // Rebind tab key, as the setting tabcompletion may be changed at runtime. + pre_readline(); + + // Get a line from the user. + char *line=Readline(prompt.c_str()); + + // Reset scroll count. + interact::lines=0; + interact::query=tty; + + // Ignore keyboard interrupts while taking input. + errorstream::interrupt=false; + + if(line) { + string s=line; + free(line); + return s; + } else { + cout << endl; + if(!tty || getSetting<bool>("exitonEOF")) + throw eof(); + return "\n"; + } +} + +void addToHistory(string line) { +#if defined(HAVE_LIBREADLINE) && defined(HAVE_LIBCURSES) + // Only add it if it has something other than newlines. + if(tty && line.find_first_not_of('\n') != string::npos) { + add_history(line.c_str()); + } +#endif +} + +string getLastHistoryLine() { +#if defined(HAVE_LIBREADLINE) && defined(HAVE_LIBCURSES) + if(tty && history_length > 0) { + HIST_ENTRY *entry=history_list()[history_length-1]; + if(!entry) { + em.compiler(); + em << "cannot access last history line"; + return ""; + } else + return entry->line; + } else +#endif + return ""; +} + +void setLastHistoryLine(string line) { +#if defined(HAVE_LIBREADLINE) && defined(HAVE_LIBCURSES) + if(tty) { + if (history_length > 0) { + HIST_ENTRY *entry=remove_history(history_length-1); + + if(!entry) { + em.compiler(); + em << "cannot modify last history line"; + } else { + free(entry->line); + free(entry); + } + } + addToHistory(line); + } +#endif +} + +void deleteLastLine() { +#if defined(HAVE_LIBREADLINE) && defined(HAVE_LIBCURSES) + if(tty) { + HIST_ENTRY *entry=remove_history(history_length-1); + if(!entry) { + em.compiler(); + em << "cannot delete last history line"; + } else { + free(entry->line); + free(entry); + } + } +#endif +} + +void cleanup_interactive() { +#if defined(HAVE_LIBREADLINE) && defined(HAVE_LIBCURSES) + // Write the history file. + if(tty) { + stifle_history(intcast(getSetting<Int>("historylines"))); + write_history(historyname.c_str()); + } +#endif +} + +} // namespace interact |