- Changed FindReadline.cmake to search for Readline in macports paths before system paths. - Fixed CTRL-D. Now it exits tasksh. - Fixed a crash when a task description had any special characters.

This commit is contained in:
Haitham Gad 2013-03-17 14:10:17 -04:00 committed by Paul Beckingham
parent 2a7c8c2aad
commit e6b7445788
4 changed files with 124 additions and 22 deletions

View file

@ -1,8 +1,80 @@
# GNU Readline library finder
if (READLINE_INCLUDE_DIR AND READLINE_LIBRARIES)
set (READLINE_FOUND TRUE)
else (READLINE_INCLUDE_DIR AND READLINE_LIBRARIES)
find_path (READLINE_INCLUDE_DIR readline/readline.h)
find_library (READLINE_LIBRARIES readline)
mark_as_advanced (READLINE_INCLUDE_DIR READLINE_LIBRARIES)
endif (READLINE_INCLUDE_DIR AND READLINE_LIBRARIES)
# - Find the readline library
# This module defines
# READLINE_INCLUDE_DIR, path to readline/readline.h, etc.
# READLINE_LIBRARIES, the libraries required to use READLINE.
# READLINE_FOUND, If false, do not try to use READLINE.
# also defined, but not for general use are
# READLINE_readline_LIBRARY, where to find the READLINE library.
# READLINE_ncurses_LIBRARY, where to find the ncurses library [might not be defined]
# Apple readline does not support readline hooks
# So we look for another one by default
IF (APPLE)
FIND_PATH (READLINE_INCLUDE_DIR NAMES readline/readline.h PATHS
/sw/include
/opt/local/include
/opt/include
/usr/local/include
/usr/include/
NO_DEFAULT_PATH
)
ENDIF (APPLE)
FIND_PATH (READLINE_INCLUDE_DIR NAMES readline/readline.h)
# Apple readline does not support readline hooks
# So we look for another one by default
IF (APPLE)
FIND_LIBRARY (READLINE_readline_LIBRARY NAMES readline PATHS
/sw/lib
/opt/local/lib
/opt/lib
/usr/local/lib
/usr/lib
NO_DEFAULT_PATH
)
ENDIF (APPLE)
FIND_LIBRARY (READLINE_readline_LIBRARY NAMES readline)
# Sometimes readline really needs ncurses
IF (APPLE)
FIND_LIBRARY (READLINE_ncurses_LIBRARY NAMES ncurses PATHS
/sw/lib
/opt/local/lib
/opt/lib
/usr/local/lib
/usr/lib
NO_DEFAULT_PATH
)
ENDIF (APPLE)
FIND_LIBRARY (READLINE_ncurses_LIBRARY NAMES ncurses)
MARK_AS_ADVANCED (
READLINE_INCLUDE_DIR
READLINE_readline_LIBRARY
READLINE_ncurses_LIBRARY
)
SET (READLINE_FOUND "NO" )
IF (READLINE_INCLUDE_DIR)
IF (READLINE_readline_LIBRARY)
SET (READLINE_FOUND "YES" )
SET (READLINE_LIBRARIES
${READLINE_readline_LIBRARY}
)
# some readline libraries depend on ncurses
IF (READLINE_ncurses_LIBRARY)
SET (READLINE_LIBRARIES ${READLINE_LIBRARIES} ${READLINE_ncurses_LIBRARY})
ENDIF (READLINE_ncurses_LIBRARY)
ENDIF (READLINE_readline_LIBRARY)
ENDIF (READLINE_INCLUDE_DIR)
IF (READLINE_FOUND)
MESSAGE (STATUS "Found readline library")
ELSE (READLINE_FOUND)
IF (READLINE_FIND_REQUIRED)
MESSAGE (FATAL_ERROR "Could not find readline -- please give some paths to CMake")
ENDIF (READLINE_FIND_REQUIRED)
ENDIF (READLINE_FOUND)

View file

@ -44,6 +44,11 @@ std::string Readline::gets (const std::string& prompt)
#ifdef HAVE_READLINE
// Get a line from the user.
char *line_read = readline (prompt.c_str ());
if (!line_read) // Exit when CTRL-D is pressed
{
std::cout << "exit\n";
return "exit";
}
#else
std::string line_read;
std::cout << prompt;
@ -52,7 +57,7 @@ std::string Readline::gets (const std::string& prompt)
#ifdef HAVE_READLINE
// If the line has any text in it, save it on the history.
if (line_read && *line_read)
if (*line_read)
add_history (line_read);
#endif
@ -66,7 +71,7 @@ std::string Readline::gets (const std::string& prompt)
}
////////////////////////////////////////////////////////////////////////////////
bool Readline::interactive_mode (const std::istream& in)
bool Readline::interactiveMode (const std::istream& in)
{
return (&in == &std::cin && isatty (0) == 1);
}
@ -74,7 +79,9 @@ bool Readline::interactive_mode (const std::istream& in)
////////////////////////////////////////////////////////////////////////////////
Wordexp::Wordexp (const std::string &str)
{
wordexp (str.c_str (), &_p, 0);
std::string tmpStr(str);
escapeSpecialChars(tmpStr);
wordexp (tmpStr.c_str (), &_p, 0);
}
////////////////////////////////////////////////////////////////////////////////
@ -96,3 +103,20 @@ char** Wordexp::argv ()
}
////////////////////////////////////////////////////////////////////////////////
char* Wordexp::argv (int i)
{
return _p.we_wordv[i];
}
////////////////////////////////////////////////////////////////////////////////
void Wordexp::escapeSpecialChars(std::string& str)
{
size_t i = 0;
while ((i = str.find_first_of ("$*?!|&;<>(){}~#@", i)) != std::string::npos)
{
str.insert(i, 1, '\\');
i += 2;
}
}
////////////////////////////////////////////////////////////////////////////////

View file

@ -38,7 +38,7 @@ class Readline
{
public:
static std::string gets (const std::string& prompt);
static bool interactive_mode (const std::istream& in);
static bool interactiveMode (const std::istream& in);
private:
// No construction or destruction.
@ -57,6 +57,9 @@ public:
int argc ();
char** argv ();
char* argv (int i);
void escapeSpecialChars(std::string& str);
private:
wordexp_t _p;

View file

@ -31,7 +31,6 @@
#include <fstream>
#include <iostream>
#include <cstring>
#include <stdlib.h>
#ifdef CYGWIN
#include <time.h>
@ -115,8 +114,8 @@ int main (int argc, const char** argv)
std::cout << (context.color () ? bold.colorize (PACKAGE_STRING) : PACKAGE_STRING)
<< " shell\n\n"
<< STRING_CMD_SHELL_HELP1 << "\n"
<< STRING_CMD_SHELL_HELP2 << "\n"
<< STRING_CMD_SHELL_HELP1 << '\n'
<< STRING_CMD_SHELL_HELP2 << '\n'
<< STRING_CMD_SHELL_HELP3 << "\n\n";
// Make a copy because context.clear will delete them.
@ -147,9 +146,13 @@ int main (int argc, const char** argv)
std::string prompt (context.config.get ("shell.prompt") + " ");
context.clear ();
if (Readline::interactive_mode (in))
if (Readline::interactiveMode (in))
{
input = Readline::gets (prompt);
// if a string has nothing but whitespaces, ignore it
if (input.find_first_not_of (" \t") == std::string::npos)
continue;
}
else
{
@ -159,7 +162,7 @@ int main (int argc, const char** argv)
if (input.find_first_not_of (" \t") == std::string::npos)
continue;
std::cout << prompt << input << "\n";
std::cout << prompt << input << '\n';
}
try
@ -169,7 +172,7 @@ int main (int argc, const char** argv)
for (int i = 0; i < w.argc (); ++i)
{
if (std::find (quit_commands.begin (), quit_commands.end (),
lowerCase (w.argv ()[i])) != quit_commands.end ())
lowerCase (w.argv (i))) != quit_commands.end ())
{
context.clearMessages ();
return 0;
@ -183,13 +186,13 @@ int main (int argc, const char** argv)
catch (const std::string& error)
{
std::cerr << error << "\n";
std::cerr << error << '\n';
return -1;
}
catch (...)
{
std::cerr << STRING_UNKNOWN_ERROR << "\n";
std::cerr << STRING_UNKNOWN_ERROR << '\n';
return -2;
}
}