- 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 # - Find the readline library
if (READLINE_INCLUDE_DIR AND READLINE_LIBRARIES) # This module defines
set (READLINE_FOUND TRUE) # READLINE_INCLUDE_DIR, path to readline/readline.h, etc.
else (READLINE_INCLUDE_DIR AND READLINE_LIBRARIES) # READLINE_LIBRARIES, the libraries required to use READLINE.
find_path (READLINE_INCLUDE_DIR readline/readline.h) # READLINE_FOUND, If false, do not try to use READLINE.
find_library (READLINE_LIBRARIES readline) # also defined, but not for general use are
mark_as_advanced (READLINE_INCLUDE_DIR READLINE_LIBRARIES) # READLINE_readline_LIBRARY, where to find the READLINE library.
endif (READLINE_INCLUDE_DIR AND READLINE_LIBRARIES) # 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 #ifdef HAVE_READLINE
// Get a line from the user. // Get a line from the user.
char *line_read = readline (prompt.c_str ()); char *line_read = readline (prompt.c_str ());
if (!line_read) // Exit when CTRL-D is pressed
{
std::cout << "exit\n";
return "exit";
}
#else #else
std::string line_read; std::string line_read;
std::cout << prompt; std::cout << prompt;
@ -52,7 +57,7 @@ std::string Readline::gets (const std::string& prompt)
#ifdef HAVE_READLINE #ifdef HAVE_READLINE
// If the line has any text in it, save it on the history. // 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); add_history (line_read);
#endif #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); 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::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: public:
static std::string gets (const std::string& prompt); static std::string gets (const std::string& prompt);
static bool interactive_mode (const std::istream& in); static bool interactiveMode (const std::istream& in);
private: private:
// No construction or destruction. // No construction or destruction.
@ -57,6 +57,9 @@ public:
int argc (); int argc ();
char** argv (); char** argv ();
char* argv (int i);
void escapeSpecialChars(std::string& str);
private: private:
wordexp_t _p; wordexp_t _p;

View file

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