mirror of
https://github.com/GothenburgBitFactory/taskwarrior.git
synced 2025-06-26 10:54:26 +02:00
- 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:
parent
2a7c8c2aad
commit
e6b7445788
4 changed files with 124 additions and 22 deletions
|
@ -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)
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue