/* * gnureadline.cc * * This file is part of NEST. * * Copyright (C) 2004 The NEST Initiative * * NEST is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 2 of the License, or * (at your option) any later version. * * NEST is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with NEST. If not, see <http://www.gnu.org/licenses/>. * */ #include "gnureadline.h" #include <cstdio> #include "stringdatum.h" #include <algorithm> #ifdef HAVE_READLINE extern "C" char* readline(const char *); extern "C" void add_history(const char *); extern "C" int read_history(const char *); extern "C" int write_history(const char *); extern "C" void using_history(); extern "C" void clear_history(); /*BeginDocumentation Name: GNUreadline - Read and edit a line from standard input Synopsis: (prompt) GNUreadline -> (string) true -> false Description: GNUreadline offers an interface to the GNU readline library. It offers - line editing - history browsing - filename completion (with TAB) Remarks: If GNUreadline is executed with a number, the Interpreter is exited (in contrast to readline). SeeAlso: readline, GNUaddhistory */ void GNUReadline::GNUReadlineFunction::execute(SLIInterpreter *i) const { //call: promptstring GNUreadline -> string true // false assert(i->OStack.load()>0); i->EStack.pop(); StringDatum *sd = dynamic_cast<StringDatum *>(i->OStack.top().datum()); assert(sd != NULL); char *line_read = readline(sd->c_str()); if(line_read == NULL) { // We have received EOF (Ctrl-D), so we quit. std::cout << std::endl; Token t("quit"); i->OStack.top().swap(t); i->OStack.push(i->baselookup(i->true_name)); } else { StringDatum *sr = new StringDatum(line_read); std::free(line_read); if(sr->empty()) { i->OStack.pop(); i->OStack.push(i->baselookup(i->false_name)); } else { Token t(sr); i->OStack.top().swap(t); i->OStack.push(i->baselookup(i->true_name)); } } } /*BeginDocumentation Name: GNUaddhistory - Add a string to the readline-history Synopsis: (string) GRNUaddhistory -> - Description: Adds a string to the readline history. SeeAlso: GNUreadline */ void GNUReadline::GNUAddhistoryFunction::execute(SLIInterpreter *i) const { //call: string GNUaddhistory assert(i->OStack.load()>0); i->EStack.pop(); StringDatum *sd = dynamic_cast<StringDatum *>(i->OStack.top().datum()); assert(sd != NULL); add_history(sd->c_str()); char *home = std::getenv("HOME"); std::string hist_file = std::string(home) + std::string("/.nest_history"); // We write the history after _each_ command. This comes in handy if you // experience a crash during a long interactive session. write_history(hist_file.c_str()); i->OStack.pop(); } GNUReadline::~GNUReadline() { clear_history(); } void GNUReadline::init(SLIInterpreter *i) { i->createcommand("GNUreadline", &gnureadlinefunction); i->createcommand("GNUaddhistory",&gnuaddhistoryfunction); using_history(); char *home = std::getenv("HOME"); std::string hist_file = std::string(home) + std::string("/.nest_history"); read_history(hist_file.c_str()); } #endif //HAVE_READLINE