summaryrefslogtreecommitdiff
path: root/Build/source/utils/asymptote/interact.cc
diff options
context:
space:
mode:
authorKarl Berry <karl@freefriends.org>2009-05-16 00:19:13 +0000
committerKarl Berry <karl@freefriends.org>2009-05-16 00:19:13 +0000
commitbab45528d65eaafe68a705dbb2a57075c7b7cbd8 (patch)
tree10b4ae2b5195c8dede153ab89359ec00f55f325f /Build/source/utils/asymptote/interact.cc
parent8643d90372e9c31e0f461c15c596b60a545bd7d3 (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.cc197
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