- Coded around the absence of wordexp on some BSD systems.
This commit is contained in:
Paul Beckingham 2014-01-12 16:30:01 -05:00
parent 6018a174e0
commit 3e04ff5e44
5 changed files with 52 additions and 94 deletions

View file

@ -1,7 +1,6 @@
cmake_minimum_required (VERSION 2.8)
set(CMAKE_LEGACY_CYGWIN_WIN32 0) # Remove when CMake >= 2.8.4 is required
include (CheckIncludeFiles)
include (CheckFunctionExists)
include (CheckStructHasMember)
@ -90,10 +89,9 @@ if (READLINE_FOUND)
set (TASK_LIBRARIES ${TASK_LIBRARIES} ${READLINE_LIBRARIES})
endif (READLINE_FOUND)
check_include_files (wordexp.h HAVE_WORDEXP_H)
check_function_exists (timegm HAVE_TIMEGM)
check_function_exists (get_current_dir_name HAVE_GET_CURRENT_DIR_NAME)
check_function_exists (wordexp HAVE_WORDEXP)
check_struct_has_member ("struct tm" tm_gmtoff time.h HAVE_TM_GMTOFF)
check_struct_has_member ("struct stat" st_birthtime "sys/types.h;sys/stat.h" HAVE_ST_BIRTHTIME)

View file

@ -67,8 +67,8 @@
/* Found uuid_unparse_lower in the uuid library */
#cmakedefine HAVE_UUID_UNPARSE_LOWER
/* Found wordexp.h in the libreadline library */
#cmakedefine HAVE_WORDEXP_H
/* Found wordexp.h */
#cmakedefine HAVE_WORDEXP
/* Undefine this to eliminate the execute command */
#define HAVE_EXECUTE 1

View file

@ -75,65 +75,3 @@ bool Readline::interactiveMode (const std::istream& in)
}
////////////////////////////////////////////////////////////////////////////////
Wordexp::Wordexp (const std::string &str)
{
#ifdef HAVE_WORDEXP_H
std::string strCopy (str);
escapeSpecialChars(strCopy);
wordexp (strCopy.c_str (), &_p, 0);
#else
_input = str;
escapeSpecialChars(_input);
#endif
}
////////////////////////////////////////////////////////////////////////////////
Wordexp::~Wordexp ()
{
#ifdef HAVE_WORDEXP_H
wordfree (&_p);
#endif
}
////////////////////////////////////////////////////////////////////////////////
int Wordexp::argc ()
{
#ifdef HAVE_WORDEXP_H
return _p.we_wordc;
#else
return 1;
#endif
}
////////////////////////////////////////////////////////////////////////////////
char** Wordexp::argv ()
{
#ifdef HAVE_WORDEXP_H
return _p.we_wordv;
#else
return (char**)_input.c_str ();
#endif
}
////////////////////////////////////////////////////////////////////////////////
char* Wordexp::argv (int i)
{
#ifdef HAVE_WORDEXP_H
return _p.we_wordv[i];
#else
return (char*)_input.c_str ();
#endif
}
////////////////////////////////////////////////////////////////////////////////
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

@ -49,26 +49,5 @@ private:
Readline& operator= (const Readline&); // Don't implement.
};
// RAII for wordexp_t
class Wordexp
{
public:
Wordexp (const std::string& str);
~Wordexp ();
int argc ();
char** argv ();
char* argv (int i);
void escapeSpecialChars(std::string& str);
private:
#ifdef HAVE_WORDEXP_H
wordexp_t _p;
#else
std::string _input;
#endif
};
#endif
////////////////////////////////////////////////////////////////////////////////

View file

@ -30,6 +30,7 @@
#include <fstream>
#include <iostream>
#include <cstring>
#include <string.h>
#include <text.h>
#include <i18n.h>
@ -39,6 +40,8 @@
Context context;
#define MAX_ARGUMENTS 256
////////////////////////////////////////////////////////////////////////////////
int main (int argc, const char** argv)
{
@ -154,19 +157,59 @@ int main (int argc, const char** argv)
try
{
Wordexp w ("task " + trim (input + permanent_overrides));
#ifdef HAVE_WORDEXP
std::string command = "task " + trim (input + permanent_overrides);
for (int i = 0; i < w.argc (); ++i)
// Escape special chars.
size_t i = 0;
while ((i = command.find_first_of ("$*?!|&;<>(){}~#@", i)) != std::string::npos)
{
command.insert(i, 1, '\\');
i += 2;
}
// Perform expansion.
wordexp_t p;
wordexp (command.c_str (), &p, 0);
char** w = p.we_wordv;
for (int i = 0; i < p.we_wordc; ++i)
{
if (std::find (quit_commands.begin (), quit_commands.end (),
lowerCase (w.argv (i))) != quit_commands.end ())
lowerCase (w[i])) != quit_commands.end ())
{
context.clearMessages ();
return 0;
}
}
int status = context.initialize (w.argc (), (const char**)w.argv ());
int status = context.initialize (p.we_wordc, (const char**)p.we_wordv);
wordfree(&p);
#else
std::string command = "task " + trim (input + permanent_overrides);
int arg_count = 0;
char* arg_vector[MAX_ARGUMENTS];
char* arg = strtok ((char*)command.c_str (), " ");
while (arg && arg_count < MAX_ARGUMENTS)
{
arg_vector[arg_count++] = arg;
arg = strtok (0, " ");
}
for (int i = 1; i < arg_count; ++i)
{
if (std::find (quit_commands.begin (), quit_commands.end (),
lowerCase (arg_vector[i])) != quit_commands.end ())
{
context.clearMessages ();
return 0;
}
}
int status = context.initialize (arg_count, (const char**) arg_vector);
#endif
if (status == 0)
context.run ();
}