- 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

@ -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,11 +57,11 @@ 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
std::string ret (line_read);
std::string ret(line_read);
#ifdef HAVE_READLINE
free (line_read);
@ -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.
@ -52,11 +52,14 @@ private:
class Wordexp
{
public:
Wordexp (const std::string &str);
Wordexp (const std::string& str);
~Wordexp ();
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;
}
}