Code Cleanup
- Integrated Context.config. - Eliminated Config& as a function argument. - Added extern references to Context where needed.
This commit is contained in:
107
src/command.cpp
107
src/command.cpp
@@ -44,8 +44,10 @@
|
|||||||
#include <ncurses.h>
|
#include <ncurses.h>
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
extern Context context;
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
std::string handleAdd (TDB& tdb, T& task, Config& conf)
|
std::string handleAdd (TDB& tdb, T& task)
|
||||||
{
|
{
|
||||||
std::stringstream out;
|
std::stringstream out;
|
||||||
|
|
||||||
@@ -69,12 +71,12 @@ std::string handleAdd (TDB& tdb, T& task, Config& conf)
|
|||||||
|
|
||||||
// Override with default.project, if not specified.
|
// Override with default.project, if not specified.
|
||||||
if (task.getAttribute ("project") == "")
|
if (task.getAttribute ("project") == "")
|
||||||
task.setAttribute ("project", conf.get ("default.project", ""));
|
task.setAttribute ("project", context.config.get ("default.project", ""));
|
||||||
|
|
||||||
// Override with default.priority, if not specified.
|
// Override with default.priority, if not specified.
|
||||||
if (task.getAttribute ("priority") == "")
|
if (task.getAttribute ("priority") == "")
|
||||||
{
|
{
|
||||||
std::string defaultPriority = conf.get ("default.priority", "");
|
std::string defaultPriority = context.config.get ("default.priority", "");
|
||||||
if (validPriority (defaultPriority))
|
if (validPriority (defaultPriority))
|
||||||
task.setAttribute ("priority", defaultPriority);
|
task.setAttribute ("priority", defaultPriority);
|
||||||
}
|
}
|
||||||
@@ -90,7 +92,7 @@ std::string handleAdd (TDB& tdb, T& task, Config& conf)
|
|||||||
}
|
}
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
std::string handleProjects (TDB& tdb, T& task, Config& conf)
|
std::string handleProjects (TDB& tdb, T& task)
|
||||||
{
|
{
|
||||||
std::stringstream out;
|
std::stringstream out;
|
||||||
|
|
||||||
@@ -114,14 +116,15 @@ std::string handleProjects (TDB& tdb, T& task, Config& conf)
|
|||||||
table.addColumn ("Project");
|
table.addColumn ("Project");
|
||||||
table.addColumn ("Tasks");
|
table.addColumn ("Tasks");
|
||||||
|
|
||||||
if (conf.get ("color", true) || conf.get (std::string ("_forcecolor"), false))
|
if (context.config.get ("color", true) ||
|
||||||
|
context.config.get (std::string ("_forcecolor"), false))
|
||||||
{
|
{
|
||||||
table.setColumnUnderline (0);
|
table.setColumnUnderline (0);
|
||||||
table.setColumnUnderline (1);
|
table.setColumnUnderline (1);
|
||||||
}
|
}
|
||||||
|
|
||||||
table.setColumnJustification (1, Table::right);
|
table.setColumnJustification (1, Table::right);
|
||||||
table.setDateFormat (conf.get ("dateformat", "m/d/Y"));
|
table.setDateFormat (context.config.get ("dateformat", "m/d/Y"));
|
||||||
|
|
||||||
foreach (i, unique)
|
foreach (i, unique)
|
||||||
{
|
{
|
||||||
@@ -130,9 +133,9 @@ std::string handleProjects (TDB& tdb, T& task, Config& conf)
|
|||||||
table.addCell (row, 1, i->second);
|
table.addCell (row, 1, i->second);
|
||||||
}
|
}
|
||||||
|
|
||||||
out << optionalBlankLine (conf)
|
out << optionalBlankLine ()
|
||||||
<< table.render ()
|
<< table.render ()
|
||||||
<< optionalBlankLine (conf)
|
<< optionalBlankLine ()
|
||||||
<< unique.size ()
|
<< unique.size ()
|
||||||
<< (unique.size () == 1 ? " project" : " projects")
|
<< (unique.size () == 1 ? " project" : " projects")
|
||||||
<< std::endl;
|
<< std::endl;
|
||||||
@@ -145,7 +148,7 @@ std::string handleProjects (TDB& tdb, T& task, Config& conf)
|
|||||||
}
|
}
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
std::string handleTags (TDB& tdb, T& task, Config& conf)
|
std::string handleTags (TDB& tdb, T& task)
|
||||||
{
|
{
|
||||||
std::stringstream out;
|
std::stringstream out;
|
||||||
|
|
||||||
@@ -168,12 +171,12 @@ std::string handleTags (TDB& tdb, T& task, Config& conf)
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Render a list of tag names from the map.
|
// Render a list of tag names from the map.
|
||||||
std::cout << optionalBlankLine (conf);
|
std::cout << optionalBlankLine ();
|
||||||
foreach (i, unique)
|
foreach (i, unique)
|
||||||
std::cout << i->first << std::endl;
|
std::cout << i->first << std::endl;
|
||||||
|
|
||||||
if (unique.size ())
|
if (unique.size ())
|
||||||
out << optionalBlankLine (conf)
|
out << optionalBlankLine ()
|
||||||
<< unique.size ()
|
<< unique.size ()
|
||||||
<< (unique.size () == 1 ? " tag" : " tags")
|
<< (unique.size () == 1 ? " tag" : " tags")
|
||||||
<< std::endl;
|
<< std::endl;
|
||||||
@@ -187,7 +190,7 @@ std::string handleTags (TDB& tdb, T& task, Config& conf)
|
|||||||
////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
// If a task is deleted, but is still in the pending file, then it may be
|
// If a task is deleted, but is still in the pending file, then it may be
|
||||||
// undeleted simply by changing it's status.
|
// undeleted simply by changing it's status.
|
||||||
std::string handleUndelete (TDB& tdb, T& task, Config& conf)
|
std::string handleUndelete (TDB& tdb, T& task)
|
||||||
{
|
{
|
||||||
std::stringstream out;
|
std::stringstream out;
|
||||||
|
|
||||||
@@ -225,7 +228,7 @@ std::string handleUndelete (TDB& tdb, T& task, Config& conf)
|
|||||||
////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
// If a task is done, but is still in the pending file, then it may be undone
|
// If a task is done, but is still in the pending file, then it may be undone
|
||||||
// simply by changing it's status.
|
// simply by changing it's status.
|
||||||
std::string handleUndo (TDB& tdb, T& task, Config& conf)
|
std::string handleUndo (TDB& tdb, T& task)
|
||||||
{
|
{
|
||||||
std::stringstream out;
|
std::stringstream out;
|
||||||
|
|
||||||
@@ -261,14 +264,14 @@ std::string handleUndo (TDB& tdb, T& task, Config& conf)
|
|||||||
}
|
}
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
std::string handleVersion (Config& conf)
|
std::string handleVersion ()
|
||||||
{
|
{
|
||||||
std::stringstream out;
|
std::stringstream out;
|
||||||
|
|
||||||
// Determine window size, and set table accordingly.
|
// Determine window size, and set table accordingly.
|
||||||
int width = conf.get ("defaultwidth", (int) 80);
|
int width = context.config.get ("defaultwidth", (int) 80);
|
||||||
#ifdef HAVE_LIBNCURSES
|
#ifdef HAVE_LIBNCURSES
|
||||||
if (conf.get ("curses", true))
|
if (context.config.get ("curses", true))
|
||||||
{
|
{
|
||||||
WINDOW* w = initscr ();
|
WINDOW* w = initscr ();
|
||||||
width = w->_maxx + 1;
|
width = w->_maxx + 1;
|
||||||
@@ -301,11 +304,11 @@ std::string handleVersion (Config& conf)
|
|||||||
// Create a table for output.
|
// Create a table for output.
|
||||||
Table table;
|
Table table;
|
||||||
table.setTableWidth (width);
|
table.setTableWidth (width);
|
||||||
table.setDateFormat (conf.get ("dateformat", "m/d/Y"));
|
table.setDateFormat (context.config.get ("dateformat", "m/d/Y"));
|
||||||
table.addColumn ("Config variable");
|
table.addColumn ("Config variable");
|
||||||
table.addColumn ("Value");
|
table.addColumn ("Value");
|
||||||
|
|
||||||
if (conf.get ("color", true) || conf.get (std::string ("_forcecolor"), false))
|
if (context.config.get ("color", true) || context.config.get (std::string ("_forcecolor"), false))
|
||||||
{
|
{
|
||||||
table.setColumnUnderline (0);
|
table.setColumnUnderline (0);
|
||||||
table.setColumnUnderline (1);
|
table.setColumnUnderline (1);
|
||||||
@@ -320,10 +323,10 @@ std::string handleVersion (Config& conf)
|
|||||||
table.sortOn (0, Table::ascendingCharacter);
|
table.sortOn (0, Table::ascendingCharacter);
|
||||||
|
|
||||||
std::vector <std::string> all;
|
std::vector <std::string> all;
|
||||||
conf.all (all);
|
context.config.all (all);
|
||||||
foreach (i, all)
|
foreach (i, all)
|
||||||
{
|
{
|
||||||
std::string value = conf.get (*i);
|
std::string value = context.config.get (*i);
|
||||||
if (value != "")
|
if (value != "")
|
||||||
{
|
{
|
||||||
int row = table.addRow ();
|
int row = table.addRow ();
|
||||||
@@ -334,11 +337,11 @@ std::string handleVersion (Config& conf)
|
|||||||
|
|
||||||
out << "Copyright (C) 2006 - 2009, P. Beckingham."
|
out << "Copyright (C) 2006 - 2009, P. Beckingham."
|
||||||
<< std::endl
|
<< std::endl
|
||||||
<< ((conf.get ("color", true) || conf.get (std::string ("_forcecolor"), false))
|
<< ((context.config.get ("color", true) || context.config.get (std::string ("_forcecolor"), false))
|
||||||
? Text::colorize (Text::bold, Text::nocolor, PACKAGE)
|
? Text::colorize (Text::bold, Text::nocolor, PACKAGE)
|
||||||
: PACKAGE)
|
: PACKAGE)
|
||||||
<< " "
|
<< " "
|
||||||
<< ((conf.get ("color", true) || conf.get (std::string ("_forcecolor"), false))
|
<< ((context.config.get ("color", true) || context.config.get (std::string ("_forcecolor"), false))
|
||||||
? Text::colorize (Text::bold, Text::nocolor, VERSION)
|
? Text::colorize (Text::bold, Text::nocolor, VERSION)
|
||||||
: VERSION)
|
: VERSION)
|
||||||
<< std::endl
|
<< std::endl
|
||||||
@@ -407,12 +410,12 @@ std::string handleVersion (Config& conf)
|
|||||||
<< std::endl;
|
<< std::endl;
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
if (conf.get ("data.location") == "")
|
if (context.config.get ("data.location") == "")
|
||||||
out << "Configuration error: data.location not specified in .taskrc "
|
out << "Configuration error: data.location not specified in .taskrc "
|
||||||
"file."
|
"file."
|
||||||
<< std::endl;
|
<< std::endl;
|
||||||
|
|
||||||
if (access (expandPath (conf.get ("data.location")).c_str (), X_OK))
|
if (access (expandPath (context.config.get ("data.location")).c_str (), X_OK))
|
||||||
out << "Configuration error: data.location contains a directory name"
|
out << "Configuration error: data.location contains a directory name"
|
||||||
" that doesn't exist, or is unreadable."
|
" that doesn't exist, or is unreadable."
|
||||||
<< std::endl;
|
<< std::endl;
|
||||||
@@ -422,7 +425,7 @@ std::string handleVersion (Config& conf)
|
|||||||
}
|
}
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
std::string handleDelete (TDB& tdb, T& task, Config& conf)
|
std::string handleDelete (TDB& tdb, T& task)
|
||||||
{
|
{
|
||||||
std::stringstream out;
|
std::stringstream out;
|
||||||
|
|
||||||
@@ -443,7 +446,7 @@ std::string handleDelete (TDB& tdb, T& task, Config& conf)
|
|||||||
<< t->getDescription ()
|
<< t->getDescription ()
|
||||||
<< "'?";
|
<< "'?";
|
||||||
|
|
||||||
if (!conf.get (std::string ("confirmation"), false) || confirm (question.str ()))
|
if (!context.config.get (std::string ("confirmation"), false) || confirm (question.str ()))
|
||||||
{
|
{
|
||||||
// Check for the more complex case of a recurring task. If this is a
|
// Check for the more complex case of a recurring task. If this is a
|
||||||
// recurring task, get confirmation to delete them all.
|
// recurring task, get confirmation to delete them all.
|
||||||
@@ -463,7 +466,7 @@ std::string handleDelete (TDB& tdb, T& task, Config& conf)
|
|||||||
sibling->setAttribute ("end", endTime);
|
sibling->setAttribute ("end", endTime);
|
||||||
tdb.modifyT (*sibling);
|
tdb.modifyT (*sibling);
|
||||||
|
|
||||||
if (conf.get ("echo.command", true))
|
if (context.config.get ("echo.command", true))
|
||||||
out << "Deleting recurring task "
|
out << "Deleting recurring task "
|
||||||
<< sibling->getId ()
|
<< sibling->getId ()
|
||||||
<< " '"
|
<< " '"
|
||||||
@@ -496,7 +499,7 @@ std::string handleDelete (TDB& tdb, T& task, Config& conf)
|
|||||||
t->setAttribute ("end", endTime);
|
t->setAttribute ("end", endTime);
|
||||||
tdb.modifyT (*t);
|
tdb.modifyT (*t);
|
||||||
|
|
||||||
if (conf.get ("echo.command", true))
|
if (context.config.get ("echo.command", true))
|
||||||
out << "Deleting task "
|
out << "Deleting task "
|
||||||
<< t->getId ()
|
<< t->getId ()
|
||||||
<< " '"
|
<< " '"
|
||||||
@@ -513,7 +516,7 @@ std::string handleDelete (TDB& tdb, T& task, Config& conf)
|
|||||||
}
|
}
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
std::string handleStart (TDB& tdb, T& task, Config& conf)
|
std::string handleStart (TDB& tdb, T& task)
|
||||||
{
|
{
|
||||||
std::stringstream out;
|
std::stringstream out;
|
||||||
|
|
||||||
@@ -531,14 +534,14 @@ std::string handleStart (TDB& tdb, T& task, Config& conf)
|
|||||||
|
|
||||||
tdb.modifyT (*t);
|
tdb.modifyT (*t);
|
||||||
|
|
||||||
if (conf.get ("echo.command", true))
|
if (context.config.get ("echo.command", true))
|
||||||
out << "Started "
|
out << "Started "
|
||||||
<< t->getId ()
|
<< t->getId ()
|
||||||
<< " '"
|
<< " '"
|
||||||
<< t->getDescription ()
|
<< t->getDescription ()
|
||||||
<< "'"
|
<< "'"
|
||||||
<< std::endl;
|
<< std::endl;
|
||||||
nag (tdb, task, conf);
|
nag (tdb, task);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
@@ -550,7 +553,7 @@ std::string handleStart (TDB& tdb, T& task, Config& conf)
|
|||||||
}
|
}
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
std::string handleStop (TDB& tdb, T& task, Config& conf)
|
std::string handleStop (TDB& tdb, T& task)
|
||||||
{
|
{
|
||||||
std::stringstream out;
|
std::stringstream out;
|
||||||
|
|
||||||
@@ -565,7 +568,7 @@ std::string handleStop (TDB& tdb, T& task, Config& conf)
|
|||||||
t->removeAttribute ("start");
|
t->removeAttribute ("start");
|
||||||
tdb.modifyT (*t);
|
tdb.modifyT (*t);
|
||||||
|
|
||||||
if (conf.get ("echo.command", true))
|
if (context.config.get ("echo.command", true))
|
||||||
out << "Stopped " << t->getId () << " '" << t->getDescription () << "'" << std::endl;
|
out << "Stopped " << t->getId () << " '" << t->getDescription () << "'" << std::endl;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
@@ -578,7 +581,7 @@ std::string handleStop (TDB& tdb, T& task, Config& conf)
|
|||||||
}
|
}
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
std::string handleDone (TDB& tdb, T& task, Config& conf)
|
std::string handleDone (TDB& tdb, T& task)
|
||||||
{
|
{
|
||||||
int count = 0;
|
int count = 0;
|
||||||
std::stringstream out;
|
std::stringstream out;
|
||||||
@@ -608,7 +611,7 @@ std::string handleDone (TDB& tdb, T& task, Config& conf)
|
|||||||
if (!tdb.modifyT (*seq))
|
if (!tdb.modifyT (*seq))
|
||||||
throw std::string ("Could not mark task as completed.");
|
throw std::string ("Could not mark task as completed.");
|
||||||
|
|
||||||
if (conf.get ("echo.command", true))
|
if (context.config.get ("echo.command", true))
|
||||||
out << "Completed "
|
out << "Completed "
|
||||||
<< seq->getId ()
|
<< seq->getId ()
|
||||||
<< " '"
|
<< " '"
|
||||||
@@ -617,7 +620,7 @@ std::string handleDone (TDB& tdb, T& task, Config& conf)
|
|||||||
<< std::endl;
|
<< std::endl;
|
||||||
|
|
||||||
updateRecurrenceMask (tdb, all, *seq);
|
updateRecurrenceMask (tdb, all, *seq);
|
||||||
nag (tdb, *seq, conf);
|
nag (tdb, *seq);
|
||||||
|
|
||||||
++count;
|
++count;
|
||||||
}
|
}
|
||||||
@@ -630,7 +633,7 @@ std::string handleDone (TDB& tdb, T& task, Config& conf)
|
|||||||
<< std::endl;
|
<< std::endl;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (conf.get ("echo.command", true))
|
if (context.config.get ("echo.command", true))
|
||||||
out << "Marked "
|
out << "Marked "
|
||||||
<< count
|
<< count
|
||||||
<< " task"
|
<< " task"
|
||||||
@@ -642,7 +645,7 @@ std::string handleDone (TDB& tdb, T& task, Config& conf)
|
|||||||
}
|
}
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
std::string handleExport (TDB& tdb, T& task, Config& conf)
|
std::string handleExport (TDB& tdb, T& task)
|
||||||
{
|
{
|
||||||
std::stringstream output;
|
std::stringstream output;
|
||||||
|
|
||||||
@@ -699,7 +702,7 @@ std::string handleExport (TDB& tdb, T& task, Config& conf)
|
|||||||
}
|
}
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
std::string handleModify (TDB& tdb, T& task, Config& conf)
|
std::string handleModify (TDB& tdb, T& task)
|
||||||
{
|
{
|
||||||
int count = 0;
|
int count = 0;
|
||||||
std::stringstream out;
|
std::stringstream out;
|
||||||
@@ -746,14 +749,14 @@ std::string handleModify (TDB& tdb, T& task, Config& conf)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (conf.get ("echo.command", true))
|
if (context.config.get ("echo.command", true))
|
||||||
out << "Modified " << count << " task" << (count == 1 ? "" : "s") << std::endl;
|
out << "Modified " << count << " task" << (count == 1 ? "" : "s") << std::endl;
|
||||||
|
|
||||||
return out.str ();
|
return out.str ();
|
||||||
}
|
}
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
std::string handleAppend (TDB& tdb, T& task, Config& conf)
|
std::string handleAppend (TDB& tdb, T& task)
|
||||||
{
|
{
|
||||||
int count = 0;
|
int count = 0;
|
||||||
std::stringstream out;
|
std::stringstream out;
|
||||||
@@ -783,7 +786,7 @@ std::string handleAppend (TDB& tdb, T& task, Config& conf)
|
|||||||
{
|
{
|
||||||
tdb.modifyT (*other);
|
tdb.modifyT (*other);
|
||||||
|
|
||||||
if (conf.get ("echo.command", true))
|
if (context.config.get ("echo.command", true))
|
||||||
out << "Appended '"
|
out << "Appended '"
|
||||||
<< task.getDescription ()
|
<< task.getDescription ()
|
||||||
<< "' to task "
|
<< "' to task "
|
||||||
@@ -796,14 +799,14 @@ std::string handleAppend (TDB& tdb, T& task, Config& conf)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (conf.get ("echo.command", true))
|
if (context.config.get ("echo.command", true))
|
||||||
out << "Appended " << count << " task" << (count == 1 ? "" : "s") << std::endl;
|
out << "Appended " << count << " task" << (count == 1 ? "" : "s") << std::endl;
|
||||||
|
|
||||||
return out.str ();
|
return out.str ();
|
||||||
}
|
}
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
std::string handleDuplicate (TDB& tdb, T& task, Config& conf)
|
std::string handleDuplicate (TDB& tdb, T& task)
|
||||||
{
|
{
|
||||||
int count = 0;
|
int count = 0;
|
||||||
std::stringstream out;
|
std::stringstream out;
|
||||||
@@ -833,7 +836,7 @@ std::string handleDuplicate (TDB& tdb, T& task, Config& conf)
|
|||||||
if (!tdb.addT (dup))
|
if (!tdb.addT (dup))
|
||||||
throw std::string ("Could not create new task.");
|
throw std::string ("Could not create new task.");
|
||||||
|
|
||||||
if (conf.get ("echo.command", true))
|
if (context.config.get ("echo.command", true))
|
||||||
out << "Duplicated "
|
out << "Duplicated "
|
||||||
<< seq->getId ()
|
<< seq->getId ()
|
||||||
<< " '"
|
<< " '"
|
||||||
@@ -851,20 +854,20 @@ std::string handleDuplicate (TDB& tdb, T& task, Config& conf)
|
|||||||
<< std::endl;
|
<< std::endl;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (conf.get ("echo.command", true))
|
if (context.config.get ("echo.command", true))
|
||||||
out << "Duplicated " << count << " task" << (count == 1 ? "" : "s") << std::endl;
|
out << "Duplicated " << count << " task" << (count == 1 ? "" : "s") << std::endl;
|
||||||
|
|
||||||
return out.str ();
|
return out.str ();
|
||||||
}
|
}
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
std::string handleColor (Config& conf)
|
std::string handleColor ()
|
||||||
{
|
{
|
||||||
std::stringstream out;
|
std::stringstream out;
|
||||||
|
|
||||||
if (conf.get ("color", true) || conf.get (std::string ("_forcecolor"), false))
|
if (context.config.get ("color", true) || context.config.get (std::string ("_forcecolor"), false))
|
||||||
{
|
{
|
||||||
out << optionalBlankLine (conf) << "Foreground" << std::endl
|
out << optionalBlankLine () << "Foreground" << std::endl
|
||||||
<< " "
|
<< " "
|
||||||
<< Text::colorize (Text::bold, Text::nocolor, "bold") << " "
|
<< Text::colorize (Text::bold, Text::nocolor, "bold") << " "
|
||||||
<< Text::colorize (Text::underline, Text::nocolor, "underline") << " "
|
<< Text::colorize (Text::underline, Text::nocolor, "underline") << " "
|
||||||
@@ -935,7 +938,7 @@ std::string handleColor (Config& conf)
|
|||||||
<< " " << Text::colorize (Text::nocolor, Text::on_white, "on_white") << " "
|
<< " " << Text::colorize (Text::nocolor, Text::on_white, "on_white") << " "
|
||||||
<< Text::colorize (Text::nocolor, Text::on_bright_white, "on_bright_white") << std::endl
|
<< Text::colorize (Text::nocolor, Text::on_bright_white, "on_bright_white") << std::endl
|
||||||
|
|
||||||
<< optionalBlankLine (conf);
|
<< optionalBlankLine ();
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
@@ -946,7 +949,7 @@ std::string handleColor (Config& conf)
|
|||||||
}
|
}
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
std::string handleAnnotate (TDB& tdb, T& task, Config& conf)
|
std::string handleAnnotate (TDB& tdb, T& task)
|
||||||
{
|
{
|
||||||
if (task.getDescription () == "")
|
if (task.getDescription () == "")
|
||||||
throw std::string ("Cannot apply a blank annotation.");
|
throw std::string ("Cannot apply a blank annotation.");
|
||||||
@@ -961,7 +964,7 @@ std::string handleAnnotate (TDB& tdb, T& task, Config& conf)
|
|||||||
t->addAnnotation (task.getDescription ());
|
t->addAnnotation (task.getDescription ());
|
||||||
tdb.modifyT (*t);
|
tdb.modifyT (*t);
|
||||||
|
|
||||||
if (conf.get ("echo.command", true))
|
if (context.config.get ("echo.command", true))
|
||||||
out << "Annotated "
|
out << "Annotated "
|
||||||
<< t->getId ()
|
<< t->getId ()
|
||||||
<< " with '"
|
<< " with '"
|
||||||
|
|||||||
44
src/edit.cpp
44
src/edit.cpp
@@ -40,6 +40,8 @@
|
|||||||
#include "util.h"
|
#include "util.h"
|
||||||
#include "task.h"
|
#include "task.h"
|
||||||
|
|
||||||
|
extern Context context;
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
static std::string findValue (
|
static std::string findValue (
|
||||||
const std::string& text,
|
const std::string& text,
|
||||||
@@ -64,7 +66,6 @@ static std::string findValue (
|
|||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
static std::string findDate (
|
static std::string findDate (
|
||||||
Config& conf,
|
|
||||||
const std::string& text,
|
const std::string& text,
|
||||||
const std::string& name)
|
const std::string& name)
|
||||||
{
|
{
|
||||||
@@ -80,7 +81,7 @@ static std::string findDate (
|
|||||||
|
|
||||||
if (value != "")
|
if (value != "")
|
||||||
{
|
{
|
||||||
Date dt (value, conf.get ("dateformat", "m/d/Y"));
|
Date dt (value, context.config.get ("dateformat", "m/d/Y"));
|
||||||
char epoch [16];
|
char epoch [16];
|
||||||
sprintf (epoch, "%d", (int)dt.toEpoch ());
|
sprintf (epoch, "%d", (int)dt.toEpoch ());
|
||||||
return std::string (epoch);
|
return std::string (epoch);
|
||||||
@@ -107,7 +108,6 @@ static std::string formatStatus (T& task)
|
|||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
static std::string formatDate (
|
static std::string formatDate (
|
||||||
Config& conf,
|
|
||||||
T& task,
|
T& task,
|
||||||
const std::string& attribute)
|
const std::string& attribute)
|
||||||
{
|
{
|
||||||
@@ -115,14 +115,14 @@ static std::string formatDate (
|
|||||||
if (value.length ())
|
if (value.length ())
|
||||||
{
|
{
|
||||||
Date dt (::atoi (value.c_str ()));
|
Date dt (::atoi (value.c_str ()));
|
||||||
value = dt.toString (conf.get ("dateformat", "m/d/Y"));
|
value = dt.toString (context.config.get ("dateformat", "m/d/Y"));
|
||||||
}
|
}
|
||||||
|
|
||||||
return value;
|
return value;
|
||||||
}
|
}
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
static std::string formatTask (Config& conf, T task)
|
static std::string formatTask (T task)
|
||||||
{
|
{
|
||||||
std::stringstream before;
|
std::stringstream before;
|
||||||
before << "# The 'task edit <id>' command allows you to modify all aspects of a task" << std::endl
|
before << "# The 'task edit <id>' command allows you to modify all aspects of a task" << std::endl
|
||||||
@@ -159,11 +159,11 @@ static std::string formatTask (Config& conf, T task)
|
|||||||
<< "# The description field is allowed to wrap and use multiple lines. Task" << std::endl
|
<< "# The description field is allowed to wrap and use multiple lines. Task" << std::endl
|
||||||
<< "# will combine them." << std::endl
|
<< "# will combine them." << std::endl
|
||||||
<< " Description: " << task.getDescription () << std::endl
|
<< " Description: " << task.getDescription () << std::endl
|
||||||
<< " Created: " << formatDate (conf, task, "entry") << std::endl
|
<< " Created: " << formatDate (task, "entry") << std::endl
|
||||||
<< " Started: " << formatDate (conf, task, "start") << std::endl
|
<< " Started: " << formatDate (task, "start") << std::endl
|
||||||
<< " Ended: " << formatDate (conf, task, "end") << std::endl
|
<< " Ended: " << formatDate (task, "end") << std::endl
|
||||||
<< " Due: " << formatDate (conf, task, "due") << std::endl
|
<< " Due: " << formatDate (task, "due") << std::endl
|
||||||
<< " Until: " << formatDate (conf, task, "until") << std::endl
|
<< " Until: " << formatDate (task, "until") << std::endl
|
||||||
<< " Recur: " << task.getAttribute ("recur") << std::endl
|
<< " Recur: " << task.getAttribute ("recur") << std::endl
|
||||||
<< " Parent: " << task.getAttribute ("parent") << std::endl
|
<< " Parent: " << task.getAttribute ("parent") << std::endl
|
||||||
<< " Foreground color: " << task.getAttribute ("fg") << std::endl
|
<< " Foreground color: " << task.getAttribute ("fg") << std::endl
|
||||||
@@ -176,7 +176,7 @@ static std::string formatTask (Config& conf, T task)
|
|||||||
foreach (anno, annotations)
|
foreach (anno, annotations)
|
||||||
{
|
{
|
||||||
Date dt (anno->first);
|
Date dt (anno->first);
|
||||||
before << " Annotation: " << dt.toString (conf.get ("dateformat", "m/d/Y"))
|
before << " Annotation: " << dt.toString (context.config.get ("dateformat", "m/d/Y"))
|
||||||
<< " " << anno->second << std::endl;
|
<< " " << anno->second << std::endl;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -187,7 +187,7 @@ static std::string formatTask (Config& conf, T task)
|
|||||||
}
|
}
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
static void parseTask (Config& conf, T& task, const std::string& after)
|
static void parseTask (T& task, const std::string& after)
|
||||||
{
|
{
|
||||||
// project
|
// project
|
||||||
std::string value = findValue (after, "Project:");
|
std::string value = findValue (after, "Project:");
|
||||||
@@ -245,7 +245,7 @@ static void parseTask (Config& conf, T& task, const std::string& after)
|
|||||||
}
|
}
|
||||||
|
|
||||||
// entry
|
// entry
|
||||||
value = findDate (conf, after, "Created:");
|
value = findDate (after, "Created:");
|
||||||
if (value != "")
|
if (value != "")
|
||||||
{
|
{
|
||||||
Date edited (::atoi (value.c_str ()));
|
Date edited (::atoi (value.c_str ()));
|
||||||
@@ -261,7 +261,7 @@ static void parseTask (Config& conf, T& task, const std::string& after)
|
|||||||
throw std::string ("Cannot remove creation date");
|
throw std::string ("Cannot remove creation date");
|
||||||
|
|
||||||
// start
|
// start
|
||||||
value = findDate (conf, after, "Started:");
|
value = findDate (after, "Started:");
|
||||||
if (value != "")
|
if (value != "")
|
||||||
{
|
{
|
||||||
Date edited (::atoi (value.c_str ()));
|
Date edited (::atoi (value.c_str ()));
|
||||||
@@ -291,7 +291,7 @@ static void parseTask (Config& conf, T& task, const std::string& after)
|
|||||||
}
|
}
|
||||||
|
|
||||||
// end
|
// end
|
||||||
value = findDate (conf, after, "Ended:");
|
value = findDate (after, "Ended:");
|
||||||
if (value != "")
|
if (value != "")
|
||||||
{
|
{
|
||||||
Date edited (::atoi (value.c_str ()));
|
Date edited (::atoi (value.c_str ()));
|
||||||
@@ -319,7 +319,7 @@ static void parseTask (Config& conf, T& task, const std::string& after)
|
|||||||
}
|
}
|
||||||
|
|
||||||
// due
|
// due
|
||||||
value = findDate (conf, after, "Due:");
|
value = findDate (after, "Due:");
|
||||||
if (value != "")
|
if (value != "")
|
||||||
{
|
{
|
||||||
Date edited (::atoi (value.c_str ()));
|
Date edited (::atoi (value.c_str ()));
|
||||||
@@ -357,7 +357,7 @@ static void parseTask (Config& conf, T& task, const std::string& after)
|
|||||||
}
|
}
|
||||||
|
|
||||||
// until
|
// until
|
||||||
value = findDate (conf, after, "Until:");
|
value = findDate (after, "Until:");
|
||||||
if (value != "")
|
if (value != "")
|
||||||
{
|
{
|
||||||
Date edited (::atoi (value.c_str ()));
|
Date edited (::atoi (value.c_str ()));
|
||||||
@@ -496,7 +496,7 @@ static void parseTask (Config& conf, T& task, const std::string& after)
|
|||||||
// Introducing the Silver Bullet. This feature is the catch-all fixative for
|
// Introducing the Silver Bullet. This feature is the catch-all fixative for
|
||||||
// various other ills. This is like opening up the hood and going in with a
|
// various other ills. This is like opening up the hood and going in with a
|
||||||
// wrench. To be used sparingly.
|
// wrench. To be used sparingly.
|
||||||
std::string handleEdit (TDB& tdb, T& task, Config& conf)
|
std::string handleEdit (TDB& tdb, T& task)
|
||||||
{
|
{
|
||||||
std::stringstream out;
|
std::stringstream out;
|
||||||
std::vector <T> all;
|
std::vector <T> all;
|
||||||
@@ -506,7 +506,7 @@ std::string handleEdit (TDB& tdb, T& task, Config& conf)
|
|||||||
foreach (seq, all)
|
foreach (seq, all)
|
||||||
{
|
{
|
||||||
// Check for file permissions.
|
// Check for file permissions.
|
||||||
std::string dataLocation = expandPath (conf.get ("data.location"));
|
std::string dataLocation = expandPath (context.config.get ("data.location"));
|
||||||
if (access (dataLocation.c_str (), X_OK))
|
if (access (dataLocation.c_str (), X_OK))
|
||||||
throw std::string ("Your data.location directory is not writable.");
|
throw std::string ("Your data.location directory is not writable.");
|
||||||
|
|
||||||
@@ -519,11 +519,11 @@ std::string handleEdit (TDB& tdb, T& task, Config& conf)
|
|||||||
char* file = cpattern;
|
char* file = cpattern;
|
||||||
|
|
||||||
// Format the contents, T -> text, write to a file.
|
// Format the contents, T -> text, write to a file.
|
||||||
std::string before = formatTask (conf, *seq);
|
std::string before = formatTask (*seq);
|
||||||
spit (file, before);
|
spit (file, before);
|
||||||
|
|
||||||
// Determine correct editor: .taskrc:editor > $VISUAL > $EDITOR > vi
|
// Determine correct editor: .taskrc:editor > $VISUAL > $EDITOR > vi
|
||||||
std::string editor = conf.get ("editor", "");
|
std::string editor = context.config.get ("editor", "");
|
||||||
char* peditor = getenv ("VISUAL");
|
char* peditor = getenv ("VISUAL");
|
||||||
if (editor == "" && peditor) editor = std::string (peditor);
|
if (editor == "" && peditor) editor = std::string (peditor);
|
||||||
peditor = getenv ("EDITOR");
|
peditor = getenv ("EDITOR");
|
||||||
@@ -558,7 +558,7 @@ ARE_THESE_REALLY_HARMFUL:
|
|||||||
|
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
parseTask (conf, *seq, after);
|
parseTask (*seq, after);
|
||||||
tdb.modifyT (*seq);
|
tdb.modifyT (*seq);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -35,6 +35,8 @@
|
|||||||
#include "util.h"
|
#include "util.h"
|
||||||
#include "task.h"
|
#include "task.h"
|
||||||
|
|
||||||
|
extern Context context;
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
enum fileType
|
enum fileType
|
||||||
{
|
{
|
||||||
@@ -159,19 +161,19 @@ static fileType determineFileType (const std::vector <std::string>& lines)
|
|||||||
}
|
}
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
static void decorateTask (T& task, Config& conf)
|
static void decorateTask (T& task)
|
||||||
{
|
{
|
||||||
char entryTime[16];
|
char entryTime[16];
|
||||||
sprintf (entryTime, "%u", (unsigned int) time (NULL));
|
sprintf (entryTime, "%u", (unsigned int) time (NULL));
|
||||||
task.setAttribute ("entry", entryTime);
|
task.setAttribute ("entry", entryTime);
|
||||||
|
|
||||||
// Override with default.project, if not specified.
|
// Override with default.project, if not specified.
|
||||||
std::string defaultProject = conf.get ("default.project", "");
|
std::string defaultProject = context.config.get ("default.project", "");
|
||||||
if (task.getAttribute ("project") == "" && defaultProject != "")
|
if (task.getAttribute ("project") == "" && defaultProject != "")
|
||||||
task.setAttribute ("project", defaultProject);
|
task.setAttribute ("project", defaultProject);
|
||||||
|
|
||||||
// Override with default.priority, if not specified.
|
// Override with default.priority, if not specified.
|
||||||
std::string defaultPriority = conf.get ("default.priority", "");
|
std::string defaultPriority = context.config.get ("default.priority", "");
|
||||||
if (task.getAttribute ("priority") == "" &&
|
if (task.getAttribute ("priority") == "" &&
|
||||||
defaultPriority != "" &&
|
defaultPriority != "" &&
|
||||||
validPriority (defaultPriority))
|
validPriority (defaultPriority))
|
||||||
@@ -181,7 +183,6 @@ static void decorateTask (T& task, Config& conf)
|
|||||||
////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
static std::string importTask_1_4_3 (
|
static std::string importTask_1_4_3 (
|
||||||
TDB& tdb,
|
TDB& tdb,
|
||||||
Config& conf,
|
|
||||||
const std::vector <std::string>& lines)
|
const std::vector <std::string>& lines)
|
||||||
{
|
{
|
||||||
std::vector <std::string> failed;
|
std::vector <std::string> failed;
|
||||||
@@ -337,7 +338,6 @@ static std::string importTask_1_4_3 (
|
|||||||
////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
static std::string importTask_1_5_0 (
|
static std::string importTask_1_5_0 (
|
||||||
TDB& tdb,
|
TDB& tdb,
|
||||||
Config& conf,
|
|
||||||
const std::vector <std::string>& lines)
|
const std::vector <std::string>& lines)
|
||||||
{
|
{
|
||||||
std::vector <std::string> failed;
|
std::vector <std::string> failed;
|
||||||
@@ -498,7 +498,6 @@ static std::string importTask_1_5_0 (
|
|||||||
////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
static std::string importTask_1_6_0 (
|
static std::string importTask_1_6_0 (
|
||||||
TDB& tdb,
|
TDB& tdb,
|
||||||
Config& conf,
|
|
||||||
const std::vector <std::string>& lines)
|
const std::vector <std::string>& lines)
|
||||||
{
|
{
|
||||||
std::vector <std::string> failed;
|
std::vector <std::string> failed;
|
||||||
@@ -659,7 +658,6 @@ static std::string importTask_1_6_0 (
|
|||||||
////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
static std::string importTaskCmdLine (
|
static std::string importTaskCmdLine (
|
||||||
TDB& tdb,
|
TDB& tdb,
|
||||||
Config& conf,
|
|
||||||
const std::vector <std::string>& lines)
|
const std::vector <std::string>& lines)
|
||||||
{
|
{
|
||||||
std::vector <std::string> failed;
|
std::vector <std::string> failed;
|
||||||
@@ -676,8 +674,8 @@ static std::string importTaskCmdLine (
|
|||||||
|
|
||||||
T task;
|
T task;
|
||||||
std::string command;
|
std::string command;
|
||||||
parse (args, command, task, conf);
|
parse (args, command, task);
|
||||||
handleAdd (tdb, task, conf);
|
handleAdd (tdb, task);
|
||||||
}
|
}
|
||||||
|
|
||||||
catch (...)
|
catch (...)
|
||||||
@@ -707,7 +705,6 @@ static std::string importTaskCmdLine (
|
|||||||
////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
static std::string importTodoSh_2_0 (
|
static std::string importTodoSh_2_0 (
|
||||||
TDB& tdb,
|
TDB& tdb,
|
||||||
Config& conf,
|
|
||||||
const std::vector <std::string>& lines)
|
const std::vector <std::string>& lines)
|
||||||
{
|
{
|
||||||
std::vector <std::string> failed;
|
std::vector <std::string> failed;
|
||||||
@@ -782,8 +779,8 @@ static std::string importTodoSh_2_0 (
|
|||||||
|
|
||||||
T task;
|
T task;
|
||||||
std::string command;
|
std::string command;
|
||||||
parse (args, command, task, conf);
|
parse (args, command, task);
|
||||||
decorateTask (task, conf);
|
decorateTask (task);
|
||||||
|
|
||||||
if (isPending)
|
if (isPending)
|
||||||
{
|
{
|
||||||
@@ -829,7 +826,6 @@ static std::string importTodoSh_2_0 (
|
|||||||
////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
static std::string importText (
|
static std::string importText (
|
||||||
TDB& tdb,
|
TDB& tdb,
|
||||||
Config& conf,
|
|
||||||
const std::vector <std::string>& lines)
|
const std::vector <std::string>& lines)
|
||||||
{
|
{
|
||||||
std::vector <std::string> failed;
|
std::vector <std::string> failed;
|
||||||
@@ -856,8 +852,8 @@ static std::string importText (
|
|||||||
|
|
||||||
T task;
|
T task;
|
||||||
std::string command;
|
std::string command;
|
||||||
parse (args, command, task, conf);
|
parse (args, command, task);
|
||||||
decorateTask (task, conf);
|
decorateTask (task);
|
||||||
|
|
||||||
if (! tdb.addT (task))
|
if (! tdb.addT (task))
|
||||||
failed.push_back (*it);
|
failed.push_back (*it);
|
||||||
@@ -891,7 +887,6 @@ static std::string importText (
|
|||||||
////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
static std::string importCSV (
|
static std::string importCSV (
|
||||||
TDB& tdb,
|
TDB& tdb,
|
||||||
Config& conf,
|
|
||||||
const std::vector <std::string>& lines)
|
const std::vector <std::string>& lines)
|
||||||
{
|
{
|
||||||
std::vector <std::string> failed;
|
std::vector <std::string> failed;
|
||||||
@@ -921,7 +916,7 @@ static std::string importCSV (
|
|||||||
std::string name = lowerCase (trim (unquoteText (trim (headings[h]))));
|
std::string name = lowerCase (trim (unquoteText (trim (headings[h]))));
|
||||||
|
|
||||||
// If there is a mapping for the field, use the value.
|
// If there is a mapping for the field, use the value.
|
||||||
if (name == conf.get ("import.synonym.id") ||
|
if (name == context.config.get ("import.synonym.id") ||
|
||||||
name == "id" ||
|
name == "id" ||
|
||||||
name == "#" ||
|
name == "#" ||
|
||||||
name == "sequence" ||
|
name == "sequence" ||
|
||||||
@@ -930,7 +925,7 @@ static std::string importCSV (
|
|||||||
mapping["id"] = (int)h;
|
mapping["id"] = (int)h;
|
||||||
}
|
}
|
||||||
|
|
||||||
else if (name == conf.get ("import.synonym.uuid") ||
|
else if (name == context.config.get ("import.synonym.uuid") ||
|
||||||
name == "uuid" ||
|
name == "uuid" ||
|
||||||
name == "guid" ||
|
name == "guid" ||
|
||||||
name.find ("unique") != std::string::npos)
|
name.find ("unique") != std::string::npos)
|
||||||
@@ -938,7 +933,7 @@ static std::string importCSV (
|
|||||||
mapping["uuid"] = (int)h;
|
mapping["uuid"] = (int)h;
|
||||||
}
|
}
|
||||||
|
|
||||||
else if (name == conf.get ("import.synonym.status") ||
|
else if (name == context.config.get ("import.synonym.status") ||
|
||||||
name == "status" ||
|
name == "status" ||
|
||||||
name == "condition" ||
|
name == "condition" ||
|
||||||
name == "state")
|
name == "state")
|
||||||
@@ -946,7 +941,7 @@ static std::string importCSV (
|
|||||||
mapping["status"] = (int)h;
|
mapping["status"] = (int)h;
|
||||||
}
|
}
|
||||||
|
|
||||||
else if (name == conf.get ("import.synonym.tags") ||
|
else if (name == context.config.get ("import.synonym.tags") ||
|
||||||
name == "tags" ||
|
name == "tags" ||
|
||||||
name.find ("categor") != std::string::npos ||
|
name.find ("categor") != std::string::npos ||
|
||||||
name.find ("tag") != std::string::npos)
|
name.find ("tag") != std::string::npos)
|
||||||
@@ -954,7 +949,7 @@ static std::string importCSV (
|
|||||||
mapping["tags"] = (int)h;
|
mapping["tags"] = (int)h;
|
||||||
}
|
}
|
||||||
|
|
||||||
else if (name == conf.get ("import.synonym.entry") ||
|
else if (name == context.config.get ("import.synonym.entry") ||
|
||||||
name == "entry" ||
|
name == "entry" ||
|
||||||
name.find ("added") != std::string::npos ||
|
name.find ("added") != std::string::npos ||
|
||||||
name.find ("created") != std::string::npos ||
|
name.find ("created") != std::string::npos ||
|
||||||
@@ -963,7 +958,7 @@ static std::string importCSV (
|
|||||||
mapping["entry"] = (int)h;
|
mapping["entry"] = (int)h;
|
||||||
}
|
}
|
||||||
|
|
||||||
else if (name == conf.get ("import.synonym.start") ||
|
else if (name == context.config.get ("import.synonym.start") ||
|
||||||
name == "start" ||
|
name == "start" ||
|
||||||
name.find ("began") != std::string::npos ||
|
name.find ("began") != std::string::npos ||
|
||||||
name.find ("begun") != std::string::npos ||
|
name.find ("begun") != std::string::npos ||
|
||||||
@@ -972,21 +967,21 @@ static std::string importCSV (
|
|||||||
mapping["start"] = (int)h;
|
mapping["start"] = (int)h;
|
||||||
}
|
}
|
||||||
|
|
||||||
else if (name == conf.get ("import.synonym.due") ||
|
else if (name == context.config.get ("import.synonym.due") ||
|
||||||
name == "due" ||
|
name == "due" ||
|
||||||
name.find ("expected") != std::string::npos)
|
name.find ("expected") != std::string::npos)
|
||||||
{
|
{
|
||||||
mapping["due"] = (int)h;
|
mapping["due"] = (int)h;
|
||||||
}
|
}
|
||||||
|
|
||||||
else if (name == conf.get ("import.synonym.recur") ||
|
else if (name == context.config.get ("import.synonym.recur") ||
|
||||||
name == "recur" ||
|
name == "recur" ||
|
||||||
name == "frequency")
|
name == "frequency")
|
||||||
{
|
{
|
||||||
mapping["recur"] = (int)h;
|
mapping["recur"] = (int)h;
|
||||||
}
|
}
|
||||||
|
|
||||||
else if (name == conf.get ("import.synonym.end") ||
|
else if (name == context.config.get ("import.synonym.end") ||
|
||||||
name == "end" ||
|
name == "end" ||
|
||||||
name == "done" ||
|
name == "done" ||
|
||||||
name.find ("complete") != std::string::npos)
|
name.find ("complete") != std::string::npos)
|
||||||
@@ -994,14 +989,14 @@ static std::string importCSV (
|
|||||||
mapping["end"] = (int)h;
|
mapping["end"] = (int)h;
|
||||||
}
|
}
|
||||||
|
|
||||||
else if (name == conf.get ("import.synonym.project") ||
|
else if (name == context.config.get ("import.synonym.project") ||
|
||||||
name == "project" ||
|
name == "project" ||
|
||||||
name.find ("proj") != std::string::npos)
|
name.find ("proj") != std::string::npos)
|
||||||
{
|
{
|
||||||
mapping["project"] = (int)h;
|
mapping["project"] = (int)h;
|
||||||
}
|
}
|
||||||
|
|
||||||
else if (name == conf.get ("import.synonym.priority") ||
|
else if (name == context.config.get ("import.synonym.priority") ||
|
||||||
name == "priority" ||
|
name == "priority" ||
|
||||||
name == "pri" ||
|
name == "pri" ||
|
||||||
name.find ("importan") != std::string::npos)
|
name.find ("importan") != std::string::npos)
|
||||||
@@ -1009,7 +1004,7 @@ static std::string importCSV (
|
|||||||
mapping["priority"] = (int)h;
|
mapping["priority"] = (int)h;
|
||||||
}
|
}
|
||||||
|
|
||||||
else if (name == conf.get ("import.synonym.fg") ||
|
else if (name == context.config.get ("import.synonym.fg") ||
|
||||||
name.find ("fg") != std::string::npos ||
|
name.find ("fg") != std::string::npos ||
|
||||||
name.find ("foreground") != std::string::npos ||
|
name.find ("foreground") != std::string::npos ||
|
||||||
name.find ("color") != std::string::npos)
|
name.find ("color") != std::string::npos)
|
||||||
@@ -1017,14 +1012,14 @@ static std::string importCSV (
|
|||||||
mapping["fg"] = (int)h;
|
mapping["fg"] = (int)h;
|
||||||
}
|
}
|
||||||
|
|
||||||
else if (name == conf.get ("import.synonym.bg") ||
|
else if (name == context.config.get ("import.synonym.bg") ||
|
||||||
name == "bg" ||
|
name == "bg" ||
|
||||||
name.find ("background") != std::string::npos)
|
name.find ("background") != std::string::npos)
|
||||||
{
|
{
|
||||||
mapping["bg"] = (int)h;
|
mapping["bg"] = (int)h;
|
||||||
}
|
}
|
||||||
|
|
||||||
else if (name == conf.get ("import.synonym.description") ||
|
else if (name == context.config.get ("import.synonym.description") ||
|
||||||
name.find ("desc") != std::string::npos ||
|
name.find ("desc") != std::string::npos ||
|
||||||
name.find ("detail") != std::string::npos ||
|
name.find ("detail") != std::string::npos ||
|
||||||
name.find ("task") != std::string::npos ||
|
name.find ("task") != std::string::npos ||
|
||||||
@@ -1132,7 +1127,7 @@ static std::string importCSV (
|
|||||||
}
|
}
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
std::string handleImport (TDB& tdb, T& task, Config& conf)
|
std::string handleImport (TDB& tdb, T& task)
|
||||||
{
|
{
|
||||||
std::stringstream out;
|
std::stringstream out;
|
||||||
|
|
||||||
@@ -1187,13 +1182,13 @@ std::string handleImport (TDB& tdb, T& task, Config& conf)
|
|||||||
// Determine which type it might be, then attempt an import.
|
// Determine which type it might be, then attempt an import.
|
||||||
switch (type)
|
switch (type)
|
||||||
{
|
{
|
||||||
case task_1_4_3: out << importTask_1_4_3 (tdb, conf, lines); break;
|
case task_1_4_3: out << importTask_1_4_3 (tdb, lines); break;
|
||||||
case task_1_5_0: out << importTask_1_5_0 (tdb, conf, lines); break;
|
case task_1_5_0: out << importTask_1_5_0 (tdb, lines); break;
|
||||||
case task_1_6_0: out << importTask_1_6_0 (tdb, conf, lines); break;
|
case task_1_6_0: out << importTask_1_6_0 (tdb, lines); break;
|
||||||
case task_cmd_line: out << importTaskCmdLine (tdb, conf, lines); break;
|
case task_cmd_line: out << importTaskCmdLine (tdb, lines); break;
|
||||||
case todo_sh_2_0: out << importTodoSh_2_0 (tdb, conf, lines); break;
|
case todo_sh_2_0: out << importTodoSh_2_0 (tdb, lines); break;
|
||||||
case csv: out << importCSV (tdb, conf, lines); break;
|
case csv: out << importCSV (tdb, lines); break;
|
||||||
case text: out << importText (tdb, conf, lines); break;
|
case text: out << importText (tdb, lines); break;
|
||||||
case not_a_clue: /* to stop the compiler from complaining. */ break;
|
case not_a_clue: /* to stop the compiler from complaining. */ break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -30,12 +30,15 @@
|
|||||||
#include <vector>
|
#include <vector>
|
||||||
#include <map>
|
#include <map>
|
||||||
|
|
||||||
|
#include "Context.h"
|
||||||
#include "Date.h"
|
#include "Date.h"
|
||||||
#include "Duration.h"
|
#include "Duration.h"
|
||||||
#include "T.h"
|
#include "T.h"
|
||||||
#include "text.h"
|
#include "text.h"
|
||||||
#include "util.h"
|
#include "util.h"
|
||||||
|
|
||||||
|
extern Context context;
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
// NOTE: These are static arrays only because there is no initializer list for
|
// NOTE: These are static arrays only because there is no initializer list for
|
||||||
// std::vector.
|
// std::vector.
|
||||||
@@ -220,9 +223,9 @@ static bool isCommand (const std::string& candidate)
|
|||||||
}
|
}
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
bool validDate (std::string& date, Config& conf)
|
bool validDate (std::string& date)
|
||||||
{
|
{
|
||||||
Date test (date, conf.get ("dateformat", "m/d/Y"));
|
Date test (date, context.config.get ("dateformat", "m/d/Y"));
|
||||||
|
|
||||||
char epoch[16];
|
char epoch[16];
|
||||||
sprintf (epoch, "%d", (int) test.toEpoch ());
|
sprintf (epoch, "%d", (int) test.toEpoch ());
|
||||||
@@ -248,8 +251,7 @@ bool validPriority (const std::string& input)
|
|||||||
////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
static bool validAttribute (
|
static bool validAttribute (
|
||||||
std::string& name,
|
std::string& name,
|
||||||
std::string& value,
|
std::string& value)
|
||||||
Config& conf)
|
|
||||||
{
|
{
|
||||||
guess ("attribute", attributes, name);
|
guess ("attribute", attributes, name);
|
||||||
if (name != "")
|
if (name != "")
|
||||||
@@ -258,10 +260,10 @@ static bool validAttribute (
|
|||||||
guess ("color", colors, value);
|
guess ("color", colors, value);
|
||||||
|
|
||||||
else if (name == "due" && value != "")
|
else if (name == "due" && value != "")
|
||||||
validDate (value, conf);
|
validDate (value);
|
||||||
|
|
||||||
else if (name == "until" && value != "")
|
else if (name == "until" && value != "")
|
||||||
validDate (value, conf);
|
validDate (value);
|
||||||
|
|
||||||
else if (name == "priority")
|
else if (name == "priority")
|
||||||
{
|
{
|
||||||
@@ -456,8 +458,7 @@ bool validDuration (std::string& input)
|
|||||||
void parse (
|
void parse (
|
||||||
std::vector <std::string>& args,
|
std::vector <std::string>& args,
|
||||||
std::string& command,
|
std::string& command,
|
||||||
T& task,
|
T& task)
|
||||||
Config& conf)
|
|
||||||
{
|
{
|
||||||
command = "";
|
command = "";
|
||||||
|
|
||||||
@@ -518,7 +519,7 @@ void parse (
|
|||||||
std::string name = lowerCase (arg.substr (0, colon));
|
std::string name = lowerCase (arg.substr (0, colon));
|
||||||
std::string value = arg.substr (colon + 1, std::string::npos);
|
std::string value = arg.substr (colon + 1, std::string::npos);
|
||||||
|
|
||||||
if (validAttribute (name, value, conf))
|
if (validAttribute (name, value))
|
||||||
{
|
{
|
||||||
if (name != "recur" || validDuration (value))
|
if (name != "recur" || validDuration (value))
|
||||||
task.setAttribute (name, value);
|
task.setAttribute (name, value);
|
||||||
@@ -589,10 +590,10 @@ void parse (
|
|||||||
}
|
}
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
void loadCustomReports (Config& conf)
|
void loadCustomReports ()
|
||||||
{
|
{
|
||||||
std::vector <std::string> all;
|
std::vector <std::string> all;
|
||||||
conf.all (all);
|
context.config.all (all);
|
||||||
|
|
||||||
foreach (i, all)
|
foreach (i, all)
|
||||||
{
|
{
|
||||||
|
|||||||
323
src/report.cpp
323
src/report.cpp
File diff suppressed because it is too large
Load Diff
@@ -26,13 +26,15 @@
|
|||||||
////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
#include <iostream>
|
#include <iostream>
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include "Config.h"
|
#include "Context.h"
|
||||||
#include "Table.h"
|
#include "Table.h"
|
||||||
#include "Date.h"
|
#include "Date.h"
|
||||||
#include "T.h"
|
#include "T.h"
|
||||||
#include "text.h"
|
#include "text.h"
|
||||||
#include "util.h"
|
#include "util.h"
|
||||||
|
|
||||||
|
extern Context context;
|
||||||
|
|
||||||
static std::map <std::string, Text::color> gsFg;
|
static std::map <std::string, Text::color> gsFg;
|
||||||
static std::map <std::string, Text::color> gsBg;
|
static std::map <std::string, Text::color> gsBg;
|
||||||
|
|
||||||
@@ -63,17 +65,17 @@ static void parseColorRule (
|
|||||||
}
|
}
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
void initializeColorRules (Config& conf)
|
void initializeColorRules ()
|
||||||
{
|
{
|
||||||
std::vector <std::string> ruleNames;
|
std::vector <std::string> ruleNames;
|
||||||
conf.all (ruleNames);
|
context.config.all (ruleNames);
|
||||||
foreach (it, ruleNames)
|
foreach (it, ruleNames)
|
||||||
{
|
{
|
||||||
if (it->substr (0, 6) == "color.")
|
if (it->substr (0, 6) == "color.")
|
||||||
{
|
{
|
||||||
Text::color fg;
|
Text::color fg;
|
||||||
Text::color bg;
|
Text::color bg;
|
||||||
parseColorRule (conf.get (*it), fg, bg);
|
parseColorRule (context.config.get (*it), fg, bg);
|
||||||
gsFg[*it] = fg;
|
gsFg[*it] = fg;
|
||||||
gsBg[*it] = bg;
|
gsBg[*it] = bg;
|
||||||
}
|
}
|
||||||
@@ -84,8 +86,7 @@ void initializeColorRules (Config& conf)
|
|||||||
void autoColorize (
|
void autoColorize (
|
||||||
T& task,
|
T& task,
|
||||||
Text::color& fg,
|
Text::color& fg,
|
||||||
Text::color& bg,
|
Text::color& bg)
|
||||||
Config& conf)
|
|
||||||
{
|
{
|
||||||
// Note: fg, bg already contain colors specifically assigned via command.
|
// Note: fg, bg already contain colors specifically assigned via command.
|
||||||
// Note: These rules form a hierarchy - the last rule is King.
|
// Note: These rules form a hierarchy - the last rule is King.
|
||||||
@@ -208,7 +209,7 @@ void autoColorize (
|
|||||||
{
|
{
|
||||||
Date dueDate (::atoi (due.c_str ()));
|
Date dueDate (::atoi (due.c_str ()));
|
||||||
Date now;
|
Date now;
|
||||||
Date then (now + conf.get ("due", 7) * 86400);
|
Date then (now + context.config.get ("due", 7) * 86400);
|
||||||
|
|
||||||
// Overdue
|
// Overdue
|
||||||
if (dueDate < now)
|
if (dueDate < now)
|
||||||
|
|||||||
@@ -3,25 +3,26 @@
|
|||||||
#include <string>
|
#include <string>
|
||||||
#include "Context.h"
|
#include "Context.h"
|
||||||
|
|
||||||
|
Context context;
|
||||||
|
|
||||||
int main (int argc, char** argv)
|
int main (int argc, char** argv)
|
||||||
{
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
Context c;
|
context.initialize (argc, argv);
|
||||||
c.initialize (argc, argv);
|
// context.run ();
|
||||||
// c.run ();
|
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
c.tdb.lock (c.config.get ("locking", true));
|
context.tdb.lock (context.config.get ("locking", true));
|
||||||
|
|
||||||
c.filter.push_back (Att ("priority", "L"));
|
context.filter.push_back (Att ("priority", "L"));
|
||||||
|
|
||||||
std::vector <T2> tasks;
|
std::vector <T2> tasks;
|
||||||
int quantity = c.tdb.load (tasks, c.filter);
|
int quantity = context.tdb.load (tasks, context.filter);
|
||||||
std::cout << "# " << quantity << " <-- c.tdb.load" << std::endl;
|
std::cout << "# " << quantity << " <-- context.tdb.load" << std::endl;
|
||||||
|
|
||||||
c.tdb.unlock ();
|
context.tdb.unlock ();
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
|||||||
164
src/task.cpp
164
src/task.cpp
@@ -50,16 +50,17 @@
|
|||||||
#include <ncurses.h>
|
#include <ncurses.h>
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
// Global context for use by all.
|
||||||
Context context;
|
Context context;
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
static std::string shortUsage (Config& conf)
|
static std::string shortUsage ()
|
||||||
{
|
{
|
||||||
std::stringstream out;
|
std::stringstream out;
|
||||||
Table table;
|
Table table;
|
||||||
int width = conf.get ("defaultwidth", (int) 80);
|
int width = context.config.get ("defaultwidth", (int) 80);
|
||||||
#ifdef HAVE_LIBNCURSES
|
#ifdef HAVE_LIBNCURSES
|
||||||
if (conf.get ("curses", true))
|
if (context.config.get ("curses", true))
|
||||||
{
|
{
|
||||||
WINDOW* w = initscr ();
|
WINDOW* w = initscr ();
|
||||||
width = w->_maxx + 1;
|
width = w->_maxx + 1;
|
||||||
@@ -79,7 +80,7 @@ static std::string shortUsage (Config& conf)
|
|||||||
table.setColumnWidth (1, Table::minimum);
|
table.setColumnWidth (1, Table::minimum);
|
||||||
table.setColumnWidth (2, Table::flexible);
|
table.setColumnWidth (2, Table::flexible);
|
||||||
table.setTableWidth (width);
|
table.setTableWidth (width);
|
||||||
table.setDateFormat (conf.get ("dateformat", "m/d/Y"));
|
table.setDateFormat (context.config.get ("dateformat", "m/d/Y"));
|
||||||
|
|
||||||
int row = table.addRow ();
|
int row = table.addRow ();
|
||||||
table.addCell (row, 0, "Usage:");
|
table.addCell (row, 0, "Usage:");
|
||||||
@@ -219,7 +220,7 @@ static std::string shortUsage (Config& conf)
|
|||||||
foreach (report, all)
|
foreach (report, all)
|
||||||
{
|
{
|
||||||
std::string command = std::string ("task ") + *report + std::string (" [tags] [attrs] desc...");
|
std::string command = std::string ("task ") + *report + std::string (" [tags] [attrs] desc...");
|
||||||
std::string description = conf.get (
|
std::string description = context.config.get (
|
||||||
std::string ("report.") + *report + ".description", std::string ("(missing description)"));
|
std::string ("report.") + *report + ".description", std::string ("(missing description)"));
|
||||||
|
|
||||||
row = table.addRow ();
|
row = table.addRow ();
|
||||||
@@ -240,10 +241,10 @@ static std::string shortUsage (Config& conf)
|
|||||||
}
|
}
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
static std::string longUsage (Config& conf)
|
static std::string longUsage ()
|
||||||
{
|
{
|
||||||
std::stringstream out;
|
std::stringstream out;
|
||||||
out << shortUsage (conf)
|
out << shortUsage ()
|
||||||
<< "ID is the numeric identifier displayed by the 'task list' command. "
|
<< "ID is the numeric identifier displayed by the 'task list' command. "
|
||||||
<< "You can specify multiple IDs for task commands, and multiple tasks "
|
<< "You can specify multiple IDs for task commands, and multiple tasks "
|
||||||
<< "will be affected. To specify multiple IDs make sure you use one "
|
<< "will be affected. To specify multiple IDs make sure you use one "
|
||||||
@@ -283,32 +284,6 @@ static std::string longUsage (Config& conf)
|
|||||||
return out.str ();
|
return out.str ();
|
||||||
}
|
}
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
|
||||||
void loadConfFile (int argc, char** argv, Config& conf)
|
|
||||||
{
|
|
||||||
for (int i = 1; i < argc; ++i)
|
|
||||||
{
|
|
||||||
if (! strncmp (argv[i], "rc:", 3))
|
|
||||||
{
|
|
||||||
if (! access (&(argv[i][3]), F_OK))
|
|
||||||
{
|
|
||||||
std::string file = &(argv[i][3]);
|
|
||||||
conf.load (file);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
throw std::string ("Could not read configuration file '") + &(argv[i][3]) + "'";
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
struct passwd* pw = getpwuid (getuid ());
|
|
||||||
if (!pw)
|
|
||||||
throw std::string ("Could not read home directory from passwd file.");
|
|
||||||
|
|
||||||
std::string file = pw->pw_dir;
|
|
||||||
conf.createDefault (file);
|
|
||||||
}
|
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
int main (int argc, char** argv)
|
int main (int argc, char** argv)
|
||||||
{
|
{
|
||||||
@@ -323,30 +298,25 @@ int main (int argc, char** argv)
|
|||||||
{
|
{
|
||||||
context.initialize (argc, argv);
|
context.initialize (argc, argv);
|
||||||
|
|
||||||
// Load the config file from the home directory. If the file cannot be
|
|
||||||
// found, offer to create a sample one.
|
|
||||||
Config conf;
|
|
||||||
loadConfFile (argc, argv, conf);
|
|
||||||
|
|
||||||
// When redirecting output to a file, do not use color, curses.
|
// When redirecting output to a file, do not use color, curses.
|
||||||
if (!isatty (fileno (stdout)))
|
if (!isatty (fileno (stdout)))
|
||||||
{
|
{
|
||||||
conf.set ("curses", "off");
|
context.config.set ("curses", "off");
|
||||||
|
|
||||||
if (! conf.get (std::string ("_forcecolor"), false))
|
if (! context.config.get (std::string ("_forcecolor"), false))
|
||||||
conf.set ("color", "off");
|
context.config.set ("color", "off");
|
||||||
}
|
}
|
||||||
|
|
||||||
TDB tdb;
|
TDB tdb;
|
||||||
std::string dataLocation = expandPath (conf.get ("data.location"));
|
std::string dataLocation = expandPath (context.config.get ("data.location"));
|
||||||
tdb.dataDirectory (dataLocation);
|
tdb.dataDirectory (dataLocation);
|
||||||
|
|
||||||
// Allow user override of file locking. Solaris/NFS machines may want this.
|
// Allow user override of file locking. Solaris/NFS machines may want this.
|
||||||
if (! conf.get ("locking", true))
|
if (! context.config.get ("locking", true))
|
||||||
tdb.noLock ();
|
tdb.noLock ();
|
||||||
|
|
||||||
// Check for silly shadow file settings.
|
// Check for silly shadow file settings.
|
||||||
std::string shadowFile = expandPath (conf.get ("shadow.file"));
|
std::string shadowFile = expandPath (context.config.get ("shadow.file"));
|
||||||
if (shadowFile != "")
|
if (shadowFile != "")
|
||||||
{
|
{
|
||||||
if (shadowFile == dataLocation + "/pending.data")
|
if (shadowFile == dataLocation + "/pending.data")
|
||||||
@@ -358,7 +328,7 @@ int main (int argc, char** argv)
|
|||||||
"overwrite your completed tasks. Please change it.");
|
"overwrite your completed tasks. Please change it.");
|
||||||
}
|
}
|
||||||
|
|
||||||
std::cout << runTaskCommand (argc, argv, tdb, conf);
|
std::cout << runTaskCommand (argc, argv, tdb);
|
||||||
}
|
}
|
||||||
|
|
||||||
catch (std::string& error)
|
catch (std::string& error)
|
||||||
@@ -377,9 +347,9 @@ int main (int argc, char** argv)
|
|||||||
}
|
}
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
void nag (TDB& tdb, T& task, Config& conf)
|
void nag (TDB& tdb, T& task)
|
||||||
{
|
{
|
||||||
std::string nagMessage = conf.get ("nag", std::string (""));
|
std::string nagMessage = context.config.get ("nag", std::string (""));
|
||||||
if (nagMessage != "")
|
if (nagMessage != "")
|
||||||
{
|
{
|
||||||
// Load all pending tasks.
|
// Load all pending tasks.
|
||||||
@@ -780,26 +750,26 @@ void updateRecurrenceMask (
|
|||||||
}
|
}
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
void updateShadowFile (TDB& tdb, Config& conf)
|
void updateShadowFile (TDB& tdb)
|
||||||
{
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
// Determine if shadow file is enabled.
|
// Determine if shadow file is enabled.
|
||||||
std::string shadowFile = expandPath (conf.get ("shadow.file"));
|
std::string shadowFile = expandPath (context.config.get ("shadow.file"));
|
||||||
if (shadowFile != "")
|
if (shadowFile != "")
|
||||||
{
|
{
|
||||||
std::string oldCurses = conf.get ("curses");
|
std::string oldCurses = context.config.get ("curses");
|
||||||
std::string oldColor = conf.get ("color");
|
std::string oldColor = context.config.get ("color");
|
||||||
conf.set ("curses", "off");
|
context.config.set ("curses", "off");
|
||||||
conf.set ("color", "off");
|
context.config.set ("color", "off");
|
||||||
|
|
||||||
// Run report. Use shadow.command, using default.command as a fallback
|
// Run report. Use shadow.command, using default.command as a fallback
|
||||||
// with "list" as a default.
|
// with "list" as a default.
|
||||||
std::string command = conf.get ("shadow.command",
|
std::string command = context.config.get ("shadow.command",
|
||||||
conf.get ("default.command", "list"));
|
context.config.get ("default.command", "list"));
|
||||||
std::vector <std::string> args;
|
std::vector <std::string> args;
|
||||||
split (args, command, ' ');
|
split (args, command, ' ');
|
||||||
std::string result = runTaskCommand (args, tdb, conf);
|
std::string result = runTaskCommand (args, tdb);
|
||||||
|
|
||||||
std::ofstream out (shadowFile.c_str ());
|
std::ofstream out (shadowFile.c_str ());
|
||||||
if (out.good ())
|
if (out.good ())
|
||||||
@@ -810,12 +780,12 @@ void updateShadowFile (TDB& tdb, Config& conf)
|
|||||||
else
|
else
|
||||||
throw std::string ("Could not write file '") + shadowFile + "'";
|
throw std::string ("Could not write file '") + shadowFile + "'";
|
||||||
|
|
||||||
conf.set ("curses", oldCurses);
|
context.config.set ("curses", oldCurses);
|
||||||
conf.set ("color", oldColor);
|
context.config.set ("color", oldColor);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Optionally display a notification that the shadow file was updated.
|
// Optionally display a notification that the shadow file was updated.
|
||||||
if (conf.get (std::string ("shadow.notify"), false))
|
if (context.config.get (std::string ("shadow.notify"), false))
|
||||||
std::cout << "[Shadow file '" << shadowFile << "' updated]" << std::endl;
|
std::cout << "[Shadow file '" << shadowFile << "' updated]" << std::endl;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -835,7 +805,6 @@ std::string runTaskCommand (
|
|||||||
int argc,
|
int argc,
|
||||||
char** argv,
|
char** argv,
|
||||||
TDB& tdb,
|
TDB& tdb,
|
||||||
Config& conf,
|
|
||||||
bool gc /* = true */,
|
bool gc /* = true */,
|
||||||
bool shadow /* = true */)
|
bool shadow /* = true */)
|
||||||
{
|
{
|
||||||
@@ -843,20 +812,19 @@ std::string runTaskCommand (
|
|||||||
for (int i = 1; i < argc; ++i)
|
for (int i = 1; i < argc; ++i)
|
||||||
args.push_back (argv[i]);
|
args.push_back (argv[i]);
|
||||||
|
|
||||||
return runTaskCommand (args, tdb, conf, gc, shadow);
|
return runTaskCommand (args, tdb, gc, shadow);
|
||||||
}
|
}
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
std::string runTaskCommand (
|
std::string runTaskCommand (
|
||||||
std::vector <std::string>& args,
|
std::vector <std::string>& args,
|
||||||
TDB& tdb,
|
TDB& tdb,
|
||||||
Config& conf,
|
|
||||||
bool gc /* = false */,
|
bool gc /* = false */,
|
||||||
bool shadow /* = false */)
|
bool shadow /* = false */)
|
||||||
{
|
{
|
||||||
// If argc == 1 and the default.command configuration variable is set,
|
// If argc == 1 and the default.command configuration variable is set,
|
||||||
// then use that, otherwise stick with argc/argv.
|
// then use that, otherwise stick with argc/argv.
|
||||||
std::string defaultCommand = conf.get ("default.command");
|
std::string defaultCommand = context.config.get ("default.command");
|
||||||
if ((args.size () == 0 ||
|
if ((args.size () == 0 ||
|
||||||
(args.size () == 1 && args[0].substr (0, 3) == "rc:")) &&
|
(args.size () == 1 && args[0].substr (0, 3) == "rc:")) &&
|
||||||
defaultCommand != "")
|
defaultCommand != "")
|
||||||
@@ -867,60 +835,60 @@ std::string runTaskCommand (
|
|||||||
std::cout << "[task " << defaultCommand << "]" << std::endl;
|
std::cout << "[task " << defaultCommand << "]" << std::endl;
|
||||||
}
|
}
|
||||||
|
|
||||||
loadCustomReports (conf);
|
loadCustomReports ();
|
||||||
|
|
||||||
std::string command;
|
std::string command;
|
||||||
T task;
|
T task;
|
||||||
parse (args, command, task, conf);
|
parse (args, command, task);
|
||||||
|
|
||||||
bool gcMod = false; // Change occurred by way of gc.
|
bool gcMod = false; // Change occurred by way of gc.
|
||||||
bool cmdMod = false; // Change occurred by way of command type.
|
bool cmdMod = false; // Change occurred by way of command type.
|
||||||
std::string out;
|
std::string out;
|
||||||
|
|
||||||
// Read-only commands with no side effects.
|
// Read-only commands with no side effects.
|
||||||
if (command == "export") { out = handleExport (tdb, task, conf); }
|
if (command == "export") { out = handleExport (tdb, task); }
|
||||||
else if (command == "projects") { out = handleProjects (tdb, task, conf); }
|
else if (command == "projects") { out = handleProjects (tdb, task); }
|
||||||
else if (command == "tags") { out = handleTags (tdb, task, conf); }
|
else if (command == "tags") { out = handleTags (tdb, task); }
|
||||||
else if (command == "info") { out = handleInfo (tdb, task, conf); }
|
else if (command == "info") { out = handleInfo (tdb, task); }
|
||||||
else if (command == "stats") { out = handleReportStats (tdb, task, conf); }
|
else if (command == "stats") { out = handleReportStats (tdb, task); }
|
||||||
else if (command == "history") { out = handleReportHistory (tdb, task, conf); }
|
else if (command == "history") { out = handleReportHistory (tdb, task); }
|
||||||
else if (command == "ghistory") { out = handleReportGHistory (tdb, task, conf); }
|
else if (command == "ghistory") { out = handleReportGHistory (tdb, task); }
|
||||||
else if (command == "calendar") { out = handleReportCalendar (tdb, task, conf); }
|
else if (command == "calendar") { out = handleReportCalendar (tdb, task); }
|
||||||
else if (command == "summary") { out = handleReportSummary (tdb, task, conf); }
|
else if (command == "summary") { out = handleReportSummary (tdb, task); }
|
||||||
else if (command == "timesheet") { out = handleReportTimesheet (tdb, task, conf); }
|
else if (command == "timesheet") { out = handleReportTimesheet (tdb, task); }
|
||||||
else if (command == "colors") { out = handleColor ( conf); }
|
else if (command == "colors") { out = handleColor ( ); }
|
||||||
else if (command == "version") { out = handleVersion ( conf); }
|
else if (command == "version") { out = handleVersion ( ); }
|
||||||
else if (command == "help") { out = longUsage ( conf); }
|
else if (command == "help") { out = longUsage ( ); }
|
||||||
|
|
||||||
// Commands that cause updates.
|
// Commands that cause updates.
|
||||||
else if (command == "" && task.getId ()) { cmdMod = true; out = handleModify (tdb, task, conf); }
|
else if (command == "" && task.getId ()) { cmdMod = true; out = handleModify (tdb, task); }
|
||||||
else if (command == "add") { cmdMod = true; out = handleAdd (tdb, task, conf); }
|
else if (command == "add") { cmdMod = true; out = handleAdd (tdb, task); }
|
||||||
else if (command == "append") { cmdMod = true; out = handleAppend (tdb, task, conf); }
|
else if (command == "append") { cmdMod = true; out = handleAppend (tdb, task); }
|
||||||
else if (command == "annotate") { cmdMod = true; out = handleAnnotate (tdb, task, conf); }
|
else if (command == "annotate") { cmdMod = true; out = handleAnnotate (tdb, task); }
|
||||||
else if (command == "done") { cmdMod = true; out = handleDone (tdb, task, conf); }
|
else if (command == "done") { cmdMod = true; out = handleDone (tdb, task); }
|
||||||
else if (command == "undelete") { cmdMod = true; out = handleUndelete (tdb, task, conf); }
|
else if (command == "undelete") { cmdMod = true; out = handleUndelete (tdb, task); }
|
||||||
else if (command == "delete") { cmdMod = true; out = handleDelete (tdb, task, conf); }
|
else if (command == "delete") { cmdMod = true; out = handleDelete (tdb, task); }
|
||||||
else if (command == "start") { cmdMod = true; out = handleStart (tdb, task, conf); }
|
else if (command == "start") { cmdMod = true; out = handleStart (tdb, task); }
|
||||||
else if (command == "stop") { cmdMod = true; out = handleStop (tdb, task, conf); }
|
else if (command == "stop") { cmdMod = true; out = handleStop (tdb, task); }
|
||||||
else if (command == "undo") { cmdMod = true; out = handleUndo (tdb, task, conf); }
|
else if (command == "undo") { cmdMod = true; out = handleUndo (tdb, task); }
|
||||||
else if (command == "import") { cmdMod = true; out = handleImport (tdb, task, conf); }
|
else if (command == "import") { cmdMod = true; out = handleImport (tdb, task); }
|
||||||
else if (command == "duplicate") { cmdMod = true; out = handleDuplicate (tdb, task, conf); }
|
else if (command == "duplicate") { cmdMod = true; out = handleDuplicate (tdb, task); }
|
||||||
else if (command == "edit") { cmdMod = true; out = handleEdit (tdb, task, conf); }
|
else if (command == "edit") { cmdMod = true; out = handleEdit (tdb, task); }
|
||||||
|
|
||||||
// Command that display IDs and therefore need TDB::gc first.
|
// Command that display IDs and therefore need TDB::gc first.
|
||||||
else if (command == "completed") { if (gc) gcMod = tdb.gc (); out = handleCompleted (tdb, task, conf); }
|
else if (command == "completed") { if (gc) gcMod = tdb.gc (); out = handleCompleted (tdb, task); }
|
||||||
else if (command == "next") { if (gc) gcMod = tdb.gc (); out = handleReportNext (tdb, task, conf); }
|
else if (command == "next") { if (gc) gcMod = tdb.gc (); out = handleReportNext (tdb, task); }
|
||||||
else if (command == "active") { if (gc) gcMod = tdb.gc (); out = handleReportActive (tdb, task, conf); }
|
else if (command == "active") { if (gc) gcMod = tdb.gc (); out = handleReportActive (tdb, task); }
|
||||||
else if (command == "overdue") { if (gc) gcMod = tdb.gc (); out = handleReportOverdue (tdb, task, conf); }
|
else if (command == "overdue") { if (gc) gcMod = tdb.gc (); out = handleReportOverdue (tdb, task); }
|
||||||
else if (isCustomReport (command)) { if (gc) gcMod = tdb.gc (); out = handleCustomReport (tdb, task, conf, command); }
|
else if (isCustomReport (command)) { if (gc) gcMod = tdb.gc (); out = handleCustomReport (tdb, task, command); }
|
||||||
|
|
||||||
// If the command is not recognized, display usage.
|
// If the command is not recognized, display usage.
|
||||||
else { out = shortUsage (conf); }
|
else { out = shortUsage (); }
|
||||||
|
|
||||||
// Only update the shadow file if such an update was not suppressed (shadow),
|
// Only update the shadow file if such an update was not suppressed (shadow),
|
||||||
// and if an actual change occurred (gcMod || cmdMod).
|
// and if an actual change occurred (gcMod || cmdMod).
|
||||||
if (shadow && (gcMod || cmdMod))
|
if (shadow && (gcMod || cmdMod))
|
||||||
updateShadowFile (tdb, conf);
|
updateShadowFile (tdb);
|
||||||
|
|
||||||
return out;
|
return out;
|
||||||
}
|
}
|
||||||
|
|||||||
79
src/task.h
79
src/task.h
@@ -32,50 +32,49 @@
|
|||||||
#include "Context.h"
|
#include "Context.h"
|
||||||
#include "T.h"
|
#include "T.h"
|
||||||
#include "TDB.h"
|
#include "TDB.h"
|
||||||
#include "Config.h"
|
|
||||||
#include "Table.h"
|
#include "Table.h"
|
||||||
#include "Date.h"
|
#include "Date.h"
|
||||||
#include "color.h"
|
#include "color.h"
|
||||||
#include "../auto.h"
|
#include "../auto.h"
|
||||||
|
|
||||||
// parse.cpp
|
// parse.cpp
|
||||||
void parse (std::vector <std::string>&, std::string&, T&, Config&);
|
void parse (std::vector <std::string>&, std::string&, T&);
|
||||||
bool validPriority (const std::string&);
|
bool validPriority (const std::string&);
|
||||||
bool validDate (std::string&, Config&);
|
bool validDate (std::string&);
|
||||||
bool validDuration (std::string&);
|
bool validDuration (std::string&);
|
||||||
void loadCustomReports (Config&);
|
void loadCustomReports ();
|
||||||
bool isCustomReport (const std::string&);
|
bool isCustomReport (const std::string&);
|
||||||
void allCustomReports (std::vector <std::string>&);
|
void allCustomReports (std::vector <std::string>&);
|
||||||
|
|
||||||
// task.cpp
|
// task.cpp
|
||||||
void gatherNextTasks (const TDB&, T&, Config&, std::vector <T>&, std::vector <int>&);
|
void gatherNextTasks (const TDB&, T&, std::vector <T>&, std::vector <int>&);
|
||||||
void nag (TDB&, T&, Config&);
|
void nag (TDB&, T&);
|
||||||
int getDueState (const std::string&);
|
int getDueState (const std::string&);
|
||||||
void handleRecurrence (TDB&, std::vector <T>&);
|
void handleRecurrence (TDB&, std::vector <T>&);
|
||||||
bool generateDueDates (T&, std::vector <Date>&);
|
bool generateDueDates (T&, std::vector <Date>&);
|
||||||
Date getNextRecurrence (Date&, std::string&);
|
Date getNextRecurrence (Date&, std::string&);
|
||||||
void updateRecurrenceMask (TDB&, std::vector <T>&, T&);
|
void updateRecurrenceMask (TDB&, std::vector <T>&, T&);
|
||||||
void onChangeCallback ();
|
void onChangeCallback ();
|
||||||
std::string runTaskCommand (int, char**, TDB&, Config&, bool gc = true, bool shadow = true);
|
std::string runTaskCommand (int, char**, TDB&, bool gc = true, bool shadow = true);
|
||||||
std::string runTaskCommand (std::vector <std::string>&, TDB&, Config&, bool gc = false, bool shadow = false);
|
std::string runTaskCommand (std::vector <std::string>&, TDB&, bool gc = false, bool shadow = false);
|
||||||
|
|
||||||
// command.cpp
|
// command.cpp
|
||||||
std::string handleAdd (TDB&, T&, Config&);
|
std::string handleAdd (TDB&, T&);
|
||||||
std::string handleAppend (TDB&, T&, Config&);
|
std::string handleAppend (TDB&, T&);
|
||||||
std::string handleExport (TDB&, T&, Config&);
|
std::string handleExport (TDB&, T&);
|
||||||
std::string handleDone (TDB&, T&, Config&);
|
std::string handleDone (TDB&, T&);
|
||||||
std::string handleModify (TDB&, T&, Config&);
|
std::string handleModify (TDB&, T&);
|
||||||
std::string handleProjects (TDB&, T&, Config&);
|
std::string handleProjects (TDB&, T&);
|
||||||
std::string handleTags (TDB&, T&, Config&);
|
std::string handleTags (TDB&, T&);
|
||||||
std::string handleUndelete (TDB&, T&, Config&);
|
std::string handleUndelete (TDB&, T&);
|
||||||
std::string handleVersion (Config&);
|
std::string handleVersion ();
|
||||||
std::string handleDelete (TDB&, T&, Config&);
|
std::string handleDelete (TDB&, T&);
|
||||||
std::string handleStart (TDB&, T&, Config&);
|
std::string handleStart (TDB&, T&);
|
||||||
std::string handleStop (TDB&, T&, Config&);
|
std::string handleStop (TDB&, T&);
|
||||||
std::string handleUndo (TDB&, T&, Config&);
|
std::string handleUndo (TDB&, T&);
|
||||||
std::string handleColor (Config&);
|
std::string handleColor ();
|
||||||
std::string handleAnnotate (TDB&, T&, Config&);
|
std::string handleAnnotate (TDB&, T&);
|
||||||
std::string handleDuplicate (TDB&, T&, Config&);
|
std::string handleDuplicate (TDB&, T&);
|
||||||
T findT (int, const std::vector <T>&);
|
T findT (int, const std::vector <T>&);
|
||||||
int deltaAppend (T&, T&);
|
int deltaAppend (T&, T&);
|
||||||
int deltaDescription (T&, T&);
|
int deltaDescription (T&, T&);
|
||||||
@@ -84,33 +83,33 @@ int deltaAttributes (T&, T&);
|
|||||||
int deltaSubstitutions (T&, T&);
|
int deltaSubstitutions (T&, T&);
|
||||||
|
|
||||||
// edit.cpp
|
// edit.cpp
|
||||||
std::string handleEdit (TDB&, T&, Config&);
|
std::string handleEdit (TDB&, T&);
|
||||||
|
|
||||||
// report.cpp
|
// report.cpp
|
||||||
void filterSequence (std::vector<T>&, T&);
|
void filterSequence (std::vector<T>&, T&);
|
||||||
void filter (std::vector<T>&, T&);
|
void filter (std::vector<T>&, T&);
|
||||||
std::string handleInfo (TDB&, T&, Config&);
|
std::string handleInfo (TDB&, T&);
|
||||||
std::string handleCompleted (TDB&, T&, Config&);
|
std::string handleCompleted (TDB&, T&);
|
||||||
std::string handleReportSummary (TDB&, T&, Config&);
|
std::string handleReportSummary (TDB&, T&);
|
||||||
std::string handleReportNext (TDB&, T&, Config&);
|
std::string handleReportNext (TDB&, T&);
|
||||||
std::string handleReportHistory (TDB&, T&, Config&);
|
std::string handleReportHistory (TDB&, T&);
|
||||||
std::string handleReportGHistory (TDB&, T&, Config&);
|
std::string handleReportGHistory (TDB&, T&);
|
||||||
std::string handleReportCalendar (TDB&, T&, Config&);
|
std::string handleReportCalendar (TDB&, T&);
|
||||||
std::string handleReportActive (TDB&, T&, Config&);
|
std::string handleReportActive (TDB&, T&);
|
||||||
std::string handleReportOverdue (TDB&, T&, Config&);
|
std::string handleReportOverdue (TDB&, T&);
|
||||||
std::string handleReportStats (TDB&, T&, Config&);
|
std::string handleReportStats (TDB&, T&);
|
||||||
std::string handleReportTimesheet (TDB&, T&, Config&);
|
std::string handleReportTimesheet (TDB&, T&);
|
||||||
|
|
||||||
std::string handleCustomReport (TDB&, T&, Config&, const std::string&);
|
std::string handleCustomReport (TDB&, T&, const std::string&);
|
||||||
void validReportColumns (const std::vector <std::string>&);
|
void validReportColumns (const std::vector <std::string>&);
|
||||||
void validSortColumns (const std::vector <std::string>&, const std::vector <std::string>&);
|
void validSortColumns (const std::vector <std::string>&, const std::vector <std::string>&);
|
||||||
|
|
||||||
// rules.cpp
|
// rules.cpp
|
||||||
void initializeColorRules (Config&);
|
void initializeColorRules ();
|
||||||
void autoColorize (T&, Text::color&, Text::color&, Config&);
|
void autoColorize (T&, Text::color&, Text::color&);
|
||||||
|
|
||||||
// import.cpp
|
// import.cpp
|
||||||
std::string handleImport (TDB&, T&, Config&);
|
std::string handleImport (TDB&, T&);
|
||||||
|
|
||||||
// list template
|
// list template
|
||||||
///////////////////////////////////////////////////////////////////////////////
|
///////////////////////////////////////////////////////////////////////////////
|
||||||
|
|||||||
@@ -5,7 +5,7 @@ LFLAGS = -L/usr/local/lib
|
|||||||
OBJECTS = ../TDB.o ../TDB2.o ../T.o ../T2.o ../parse.o ../text.o ../Date.o \
|
OBJECTS = ../TDB.o ../TDB2.o ../T.o ../T2.o ../parse.o ../text.o ../Date.o \
|
||||||
../Duration.o ../util.o ../Config.o ../Sequence.o ../Att.o \
|
../Duration.o ../util.o ../Config.o ../Sequence.o ../Att.o \
|
||||||
../Record.o ../Mod.o ../StringTable.o ../Subst.o ../Nibbler.o \
|
../Record.o ../Mod.o ../StringTable.o ../Subst.o ../Nibbler.o \
|
||||||
../Filter.o ../Location.o
|
../Filter.o ../Location.o ../Context.o ../Keymap.o
|
||||||
|
|
||||||
all: $(PROJECT)
|
all: $(PROJECT)
|
||||||
|
|
||||||
|
|||||||
@@ -24,9 +24,12 @@
|
|||||||
// USA
|
// USA
|
||||||
//
|
//
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
#include <Context.h>
|
||||||
#include <Att.h>
|
#include <Att.h>
|
||||||
#include <test.h>
|
#include <test.h>
|
||||||
|
|
||||||
|
Context context;
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
int main (int argc, char** argv)
|
int main (int argc, char** argv)
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -29,6 +29,8 @@
|
|||||||
#include <util.h>
|
#include <util.h>
|
||||||
#include <task.h>
|
#include <task.h>
|
||||||
|
|
||||||
|
Context context;
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
int main (int argc, char** argv)
|
int main (int argc, char** argv)
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -25,9 +25,12 @@
|
|||||||
//
|
//
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
#include <iostream>
|
#include <iostream>
|
||||||
|
#include <Context.h>
|
||||||
#include <Date.h>
|
#include <Date.h>
|
||||||
#include <test.h>
|
#include <test.h>
|
||||||
|
|
||||||
|
Context context;
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
int main (int argc, char** argv)
|
int main (int argc, char** argv)
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -25,9 +25,12 @@
|
|||||||
//
|
//
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
#include <iostream>
|
#include <iostream>
|
||||||
|
#include <Context.h>
|
||||||
#include <Duration.h>
|
#include <Duration.h>
|
||||||
#include <test.h>
|
#include <test.h>
|
||||||
|
|
||||||
|
Context context;
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
// daily, day, Nd
|
// daily, day, Nd
|
||||||
// weekly, 1w, sennight, biweekly, fortnight
|
// weekly, 1w, sennight, biweekly, fortnight
|
||||||
|
|||||||
@@ -24,9 +24,12 @@
|
|||||||
// USA
|
// USA
|
||||||
//
|
//
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
#include <Context.h>
|
||||||
#include <Mod.h>
|
#include <Mod.h>
|
||||||
#include <test.h>
|
#include <test.h>
|
||||||
|
|
||||||
|
Context context;
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
int main (int argc, char** argv)
|
int main (int argc, char** argv)
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -24,9 +24,12 @@
|
|||||||
// USA
|
// USA
|
||||||
//
|
//
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
#include <Context.h>
|
||||||
#include <Nibbler.h>
|
#include <Nibbler.h>
|
||||||
#include <test.h>
|
#include <test.h>
|
||||||
|
|
||||||
|
Context context;
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
int main (int argc, char** argv)
|
int main (int argc, char** argv)
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -29,6 +29,8 @@
|
|||||||
#include "text.h"
|
#include "text.h"
|
||||||
#include "test.h"
|
#include "test.h"
|
||||||
|
|
||||||
|
Context context;
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
int main (int argc, char** argv)
|
int main (int argc, char** argv)
|
||||||
{
|
{
|
||||||
@@ -37,13 +39,12 @@ int main (int argc, char** argv)
|
|||||||
std::vector <std::string> args;
|
std::vector <std::string> args;
|
||||||
std::string command;
|
std::string command;
|
||||||
|
|
||||||
Config conf;
|
context.config.set ("dateformat", "m/d/Y");
|
||||||
conf.set ("dateformat", "m/d/Y");
|
|
||||||
|
|
||||||
{
|
{
|
||||||
T task;
|
T task;
|
||||||
split (args, "add foo", ' ');
|
split (args, "add foo", ' ');
|
||||||
parse (args, command, task, conf);
|
parse (args, command, task);
|
||||||
t.is (command, "add", "(1) command found");
|
t.is (command, "add", "(1) command found");
|
||||||
t.is (task.getId (), 0, "(1) zero id on add");
|
t.is (task.getId (), 0, "(1) zero id on add");
|
||||||
t.is (task.getDescription (), "foo", "(1) correct description");
|
t.is (task.getDescription (), "foo", "(1) correct description");
|
||||||
@@ -52,7 +53,7 @@ int main (int argc, char** argv)
|
|||||||
{
|
{
|
||||||
T task;
|
T task;
|
||||||
split (args, "delete 1,3-5,7", ' ');
|
split (args, "delete 1,3-5,7", ' ');
|
||||||
parse (args, command, task, conf);
|
parse (args, command, task);
|
||||||
std::vector <int> sequence = task.getAllIds ();
|
std::vector <int> sequence = task.getAllIds ();
|
||||||
t.is (sequence.size (), (size_t)5, "(2) sequence length");
|
t.is (sequence.size (), (size_t)5, "(2) sequence length");
|
||||||
if (sequence.size () == 5)
|
if (sequence.size () == 5)
|
||||||
@@ -76,7 +77,7 @@ int main (int argc, char** argv)
|
|||||||
{
|
{
|
||||||
T task;
|
T task;
|
||||||
split (args, "delete 1,2 3,4", ' ');
|
split (args, "delete 1,2 3,4", ' ');
|
||||||
parse (args, command, task, conf);
|
parse (args, command, task);
|
||||||
std::vector <int> sequence = task.getAllIds ();
|
std::vector <int> sequence = task.getAllIds ();
|
||||||
t.is (sequence.size (), (size_t)4, "(3) sequence length");
|
t.is (sequence.size (), (size_t)4, "(3) sequence length");
|
||||||
if (sequence.size () == 4)
|
if (sequence.size () == 4)
|
||||||
@@ -98,7 +99,7 @@ int main (int argc, char** argv)
|
|||||||
{
|
{
|
||||||
T task;
|
T task;
|
||||||
split (args, "1 There are 7 days in a week", ' ');
|
split (args, "1 There are 7 days in a week", ' ');
|
||||||
parse (args, command, task, conf);
|
parse (args, command, task);
|
||||||
std::vector <int> sequence = task.getAllIds ();
|
std::vector <int> sequence = task.getAllIds ();
|
||||||
t.is (sequence.size (), (size_t)1, "(4) sequence length");
|
t.is (sequence.size (), (size_t)1, "(4) sequence length");
|
||||||
if (sequence.size () == 1)
|
if (sequence.size () == 1)
|
||||||
@@ -116,7 +117,7 @@ int main (int argc, char** argv)
|
|||||||
args.clear ();
|
args.clear ();
|
||||||
args.push_back ("1");
|
args.push_back ("1");
|
||||||
args.push_back ("4-123 is back-ordered");
|
args.push_back ("4-123 is back-ordered");
|
||||||
parse (args, command, task, conf);
|
parse (args, command, task);
|
||||||
std::vector <int> sequence = task.getAllIds ();
|
std::vector <int> sequence = task.getAllIds ();
|
||||||
t.is (sequence.size (), (size_t)1, "(5) sequence length");
|
t.is (sequence.size (), (size_t)1, "(5) sequence length");
|
||||||
if (sequence.size () == 1)
|
if (sequence.size () == 1)
|
||||||
|
|||||||
@@ -25,10 +25,13 @@
|
|||||||
//
|
//
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
#include <iostream>
|
#include <iostream>
|
||||||
|
#include <Context.h>
|
||||||
#include <Att.h>
|
#include <Att.h>
|
||||||
#include <Record.h>
|
#include <Record.h>
|
||||||
#include <test.h>
|
#include <test.h>
|
||||||
|
|
||||||
|
Context context;
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
int main (int argc, char** argv)
|
int main (int argc, char** argv)
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -25,9 +25,12 @@
|
|||||||
//
|
//
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
#include <iostream>
|
#include <iostream>
|
||||||
|
#include <Context.h>
|
||||||
#include <Sequence.h>
|
#include <Sequence.h>
|
||||||
#include <test.h>
|
#include <test.h>
|
||||||
|
|
||||||
|
Context context;
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
Sequence parseSequence (const std::string& input)
|
Sequence parseSequence (const std::string& input)
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -25,10 +25,13 @@
|
|||||||
//
|
//
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
|
#include <Context.h>
|
||||||
#include <StringTable.h>
|
#include <StringTable.h>
|
||||||
#include <util.h>
|
#include <util.h>
|
||||||
#include <test.h>
|
#include <test.h>
|
||||||
|
|
||||||
|
Context context;
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
int main (int argc, char** argv)
|
int main (int argc, char** argv)
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -24,10 +24,13 @@
|
|||||||
// USA
|
// USA
|
||||||
//
|
//
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
#include <Context.h>
|
||||||
#include <T2.h>
|
#include <T2.h>
|
||||||
#include <Subst.h>
|
#include <Subst.h>
|
||||||
#include <test.h>
|
#include <test.h>
|
||||||
|
|
||||||
|
Context context;
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
int main (int argc, char** argv)
|
int main (int argc, char** argv)
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -29,6 +29,8 @@
|
|||||||
#include "task.h"
|
#include "task.h"
|
||||||
#include "test.h"
|
#include "test.h"
|
||||||
|
|
||||||
|
Context context;
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
int main (int argc, char** argv)
|
int main (int argc, char** argv)
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -29,6 +29,8 @@
|
|||||||
#include "task.h"
|
#include "task.h"
|
||||||
#include "test.h"
|
#include "test.h"
|
||||||
|
|
||||||
|
Context context;
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
int main (int argc, char** argv)
|
int main (int argc, char** argv)
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -31,6 +31,8 @@
|
|||||||
#include "task.h"
|
#include "task.h"
|
||||||
#include "test.h"
|
#include "test.h"
|
||||||
|
|
||||||
|
Context context;
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
int main (int argc, char** argv)
|
int main (int argc, char** argv)
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -29,6 +29,8 @@
|
|||||||
#include "text.h"
|
#include "text.h"
|
||||||
#include "test.h"
|
#include "test.h"
|
||||||
|
|
||||||
|
Context context;
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
int main (int argc, char** argv)
|
int main (int argc, char** argv)
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -27,10 +27,12 @@
|
|||||||
#include <iostream>
|
#include <iostream>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
#include <string>
|
#include <string>
|
||||||
#include "Config.h"
|
#include "Context.h"
|
||||||
#include "util.h"
|
#include "util.h"
|
||||||
#include "text.h"
|
#include "text.h"
|
||||||
|
|
||||||
|
extern Context context;
|
||||||
|
|
||||||
static const char* newline = "\n";
|
static const char* newline = "\n";
|
||||||
static const char* noline = "";
|
static const char* noline = "";
|
||||||
|
|
||||||
@@ -294,9 +296,9 @@ std::string upperCase (const std::string& input)
|
|||||||
}
|
}
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
const char* optionalBlankLine (Config& conf)
|
const char* optionalBlankLine ()
|
||||||
{
|
{
|
||||||
if (conf.get ("blanklines", true) == true)
|
if (context.config.get ("blanklines", true) == true)
|
||||||
return newline;
|
return newline;
|
||||||
|
|
||||||
return noline;
|
return noline;
|
||||||
|
|||||||
@@ -29,7 +29,6 @@
|
|||||||
|
|
||||||
#include <string>
|
#include <string>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
#include "Config.h"
|
|
||||||
#include "../auto.h"
|
#include "../auto.h"
|
||||||
|
|
||||||
// text.cpp
|
// text.cpp
|
||||||
@@ -45,7 +44,7 @@ void join (std::string&, const std::string&, const std::vector<std::string>&);
|
|||||||
std::string commify (const std::string&);
|
std::string commify (const std::string&);
|
||||||
std::string lowerCase (const std::string&);
|
std::string lowerCase (const std::string&);
|
||||||
std::string upperCase (const std::string&);
|
std::string upperCase (const std::string&);
|
||||||
const char* optionalBlankLine (Config&);
|
const char* optionalBlankLine ();
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|||||||
545
src/utf8.cpp
Normal file
545
src/utf8.cpp
Normal file
@@ -0,0 +1,545 @@
|
|||||||
|
#ifdef NOPE
|
||||||
|
/*
|
||||||
|
Basic UTF-8 manipulation routines
|
||||||
|
by Jeff Bezanson
|
||||||
|
placed in the public domain Fall 2005
|
||||||
|
|
||||||
|
This code is designed to provide the utilities you need to manipulate
|
||||||
|
UTF-8 as an internal string encoding. These functions do not perform the
|
||||||
|
error checking normally needed when handling UTF-8 data, so if you happen
|
||||||
|
to be from the Unicode Consortium you will want to flay me alive.
|
||||||
|
I do this because error checking can be performed at the boundaries (I/O),
|
||||||
|
with these routines reserved for higher performance on data known to be
|
||||||
|
valid.
|
||||||
|
*/
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <string.h>
|
||||||
|
#include <stdarg.h>
|
||||||
|
#ifdef WIN32
|
||||||
|
#include <malloc.h>
|
||||||
|
#else
|
||||||
|
#include <alloca.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#include "utf8.h"
|
||||||
|
|
||||||
|
static const u_int32_t offsetsFromUTF8[6] = {
|
||||||
|
0x00000000UL, 0x00003080UL, 0x000E2080UL,
|
||||||
|
0x03C82080UL, 0xFA082080UL, 0x82082080UL
|
||||||
|
};
|
||||||
|
|
||||||
|
static const char trailingBytesForUTF8[256] = {
|
||||||
|
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
|
||||||
|
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
|
||||||
|
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
|
||||||
|
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
|
||||||
|
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
|
||||||
|
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
|
||||||
|
1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
|
||||||
|
2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2, 3,3,3,3,3,3,3,3,4,4,4,4,5,5,5,5
|
||||||
|
};
|
||||||
|
|
||||||
|
/* returns length of next utf-8 sequence */
|
||||||
|
int u8_seqlen(char *s)
|
||||||
|
{
|
||||||
|
return trailingBytesForUTF8[(unsigned int)(unsigned char)s[0]] + 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* conversions without error checking
|
||||||
|
only works for valid UTF-8, i.e. no 5- or 6-byte sequences
|
||||||
|
srcsz = source size in bytes, or -1 if 0-terminated
|
||||||
|
sz = dest size in # of wide characters
|
||||||
|
|
||||||
|
returns # characters converted
|
||||||
|
dest will always be L'\0'-terminated, even if there isn't enough room
|
||||||
|
for all the characters.
|
||||||
|
if sz = srcsz+1 (i.e. 4*srcsz+4 bytes), there will always be enough space.
|
||||||
|
*/
|
||||||
|
int u8_toucs(u_int32_t *dest, int sz, char *src, int srcsz)
|
||||||
|
{
|
||||||
|
u_int32_t ch;
|
||||||
|
char *src_end = src + srcsz;
|
||||||
|
int nb;
|
||||||
|
int i=0;
|
||||||
|
|
||||||
|
while (i < sz-1) {
|
||||||
|
nb = trailingBytesForUTF8[(unsigned char)*src];
|
||||||
|
if (srcsz == -1) {
|
||||||
|
if (*src == 0)
|
||||||
|
goto done_toucs;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
if (src + nb >= src_end)
|
||||||
|
goto done_toucs;
|
||||||
|
}
|
||||||
|
ch = 0;
|
||||||
|
switch (nb) {
|
||||||
|
/* these fall through deliberately */
|
||||||
|
case 3: ch += (unsigned char)*src++; ch <<= 6;
|
||||||
|
case 2: ch += (unsigned char)*src++; ch <<= 6;
|
||||||
|
case 1: ch += (unsigned char)*src++; ch <<= 6;
|
||||||
|
case 0: ch += (unsigned char)*src++;
|
||||||
|
}
|
||||||
|
ch -= offsetsFromUTF8[nb];
|
||||||
|
dest[i++] = ch;
|
||||||
|
}
|
||||||
|
done_toucs:
|
||||||
|
dest[i] = 0;
|
||||||
|
return i;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* srcsz = number of source characters, or -1 if 0-terminated
|
||||||
|
sz = size of dest buffer in bytes
|
||||||
|
|
||||||
|
returns # characters converted
|
||||||
|
dest will only be '\0'-terminated if there is enough space. this is
|
||||||
|
for consistency; imagine there are 2 bytes of space left, but the next
|
||||||
|
character requires 3 bytes. in this case we could NUL-terminate, but in
|
||||||
|
general we can't when there's insufficient space. therefore this function
|
||||||
|
only NUL-terminates if all the characters fit, and there's space for
|
||||||
|
the NUL as well.
|
||||||
|
the destination string will never be bigger than the source string.
|
||||||
|
*/
|
||||||
|
int u8_toutf8(char *dest, int sz, u_int32_t *src, int srcsz)
|
||||||
|
{
|
||||||
|
u_int32_t ch;
|
||||||
|
int i = 0;
|
||||||
|
char *dest_end = dest + sz;
|
||||||
|
|
||||||
|
while (srcsz<0 ? src[i]!=0 : i < srcsz) {
|
||||||
|
ch = src[i];
|
||||||
|
if (ch < 0x80) {
|
||||||
|
if (dest >= dest_end)
|
||||||
|
return i;
|
||||||
|
*dest++ = (char)ch;
|
||||||
|
}
|
||||||
|
else if (ch < 0x800) {
|
||||||
|
if (dest >= dest_end-1)
|
||||||
|
return i;
|
||||||
|
*dest++ = (ch>>6) | 0xC0;
|
||||||
|
*dest++ = (ch & 0x3F) | 0x80;
|
||||||
|
}
|
||||||
|
else if (ch < 0x10000) {
|
||||||
|
if (dest >= dest_end-2)
|
||||||
|
return i;
|
||||||
|
*dest++ = (ch>>12) | 0xE0;
|
||||||
|
*dest++ = ((ch>>6) & 0x3F) | 0x80;
|
||||||
|
*dest++ = (ch & 0x3F) | 0x80;
|
||||||
|
}
|
||||||
|
else if (ch < 0x110000) {
|
||||||
|
if (dest >= dest_end-3)
|
||||||
|
return i;
|
||||||
|
*dest++ = (ch>>18) | 0xF0;
|
||||||
|
*dest++ = ((ch>>12) & 0x3F) | 0x80;
|
||||||
|
*dest++ = ((ch>>6) & 0x3F) | 0x80;
|
||||||
|
*dest++ = (ch & 0x3F) | 0x80;
|
||||||
|
}
|
||||||
|
i++;
|
||||||
|
}
|
||||||
|
if (dest < dest_end)
|
||||||
|
*dest = '\0';
|
||||||
|
return i;
|
||||||
|
}
|
||||||
|
|
||||||
|
int u8_wc_toutf8(char *dest, u_int32_t ch)
|
||||||
|
{
|
||||||
|
if (ch < 0x80) {
|
||||||
|
dest[0] = (char)ch;
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
if (ch < 0x800) {
|
||||||
|
dest[0] = (ch>>6) | 0xC0;
|
||||||
|
dest[1] = (ch & 0x3F) | 0x80;
|
||||||
|
return 2;
|
||||||
|
}
|
||||||
|
if (ch < 0x10000) {
|
||||||
|
dest[0] = (ch>>12) | 0xE0;
|
||||||
|
dest[1] = ((ch>>6) & 0x3F) | 0x80;
|
||||||
|
dest[2] = (ch & 0x3F) | 0x80;
|
||||||
|
return 3;
|
||||||
|
}
|
||||||
|
if (ch < 0x110000) {
|
||||||
|
dest[0] = (ch>>18) | 0xF0;
|
||||||
|
dest[1] = ((ch>>12) & 0x3F) | 0x80;
|
||||||
|
dest[2] = ((ch>>6) & 0x3F) | 0x80;
|
||||||
|
dest[3] = (ch & 0x3F) | 0x80;
|
||||||
|
return 4;
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* charnum => byte offset */
|
||||||
|
int u8_offset(char *str, int charnum)
|
||||||
|
{
|
||||||
|
int offs=0;
|
||||||
|
|
||||||
|
while (charnum > 0 && str[offs]) {
|
||||||
|
(void)(isutf(str[++offs]) || isutf(str[++offs]) ||
|
||||||
|
isutf(str[++offs]) || ++offs);
|
||||||
|
charnum--;
|
||||||
|
}
|
||||||
|
return offs;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* byte offset => charnum */
|
||||||
|
int u8_charnum(char *s, int offset)
|
||||||
|
{
|
||||||
|
int charnum = 0, offs=0;
|
||||||
|
|
||||||
|
while (offs < offset && s[offs]) {
|
||||||
|
(void)(isutf(s[++offs]) || isutf(s[++offs]) ||
|
||||||
|
isutf(s[++offs]) || ++offs);
|
||||||
|
charnum++;
|
||||||
|
}
|
||||||
|
return charnum;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* number of characters */
|
||||||
|
int u8_strlen(char *s)
|
||||||
|
{
|
||||||
|
int count = 0;
|
||||||
|
int i = 0;
|
||||||
|
|
||||||
|
while (u8_nextchar(s, &i) != 0)
|
||||||
|
count++;
|
||||||
|
|
||||||
|
return count;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* reads the next utf-8 sequence out of a string, updating an index */
|
||||||
|
u_int32_t u8_nextchar(char *s, int *i)
|
||||||
|
{
|
||||||
|
u_int32_t ch = 0;
|
||||||
|
int sz = 0;
|
||||||
|
|
||||||
|
do {
|
||||||
|
ch <<= 6;
|
||||||
|
ch += (unsigned char)s[(*i)++];
|
||||||
|
sz++;
|
||||||
|
} while (s[*i] && !isutf(s[*i]));
|
||||||
|
ch -= offsetsFromUTF8[sz-1];
|
||||||
|
|
||||||
|
return ch;
|
||||||
|
}
|
||||||
|
|
||||||
|
void u8_inc(char *s, int *i)
|
||||||
|
{
|
||||||
|
(void)(isutf(s[++(*i)]) || isutf(s[++(*i)]) ||
|
||||||
|
isutf(s[++(*i)]) || ++(*i));
|
||||||
|
}
|
||||||
|
|
||||||
|
void u8_dec(char *s, int *i)
|
||||||
|
{
|
||||||
|
(void)(isutf(s[--(*i)]) || isutf(s[--(*i)]) ||
|
||||||
|
isutf(s[--(*i)]) || --(*i));
|
||||||
|
}
|
||||||
|
|
||||||
|
int octal_digit(char c)
|
||||||
|
{
|
||||||
|
return (c >= '0' && c <= '7');
|
||||||
|
}
|
||||||
|
|
||||||
|
int hex_digit(char c)
|
||||||
|
{
|
||||||
|
return ((c >= '0' && c <= '9') ||
|
||||||
|
(c >= 'A' && c <= 'F') ||
|
||||||
|
(c >= 'a' && c <= 'f'));
|
||||||
|
}
|
||||||
|
|
||||||
|
/* assumes that src points to the character after a backslash
|
||||||
|
returns number of input characters processed */
|
||||||
|
int u8_read_escape_sequence(char *str, u_int32_t *dest)
|
||||||
|
{
|
||||||
|
u_int32_t ch;
|
||||||
|
char digs[9]="\0\0\0\0\0\0\0\0";
|
||||||
|
int dno=0, i=1;
|
||||||
|
|
||||||
|
ch = (u_int32_t)str[0]; /* take literal character */
|
||||||
|
if (str[0] == 'n')
|
||||||
|
ch = L'\n';
|
||||||
|
else if (str[0] == 't')
|
||||||
|
ch = L'\t';
|
||||||
|
else if (str[0] == 'r')
|
||||||
|
ch = L'\r';
|
||||||
|
else if (str[0] == 'b')
|
||||||
|
ch = L'\b';
|
||||||
|
else if (str[0] == 'f')
|
||||||
|
ch = L'\f';
|
||||||
|
else if (str[0] == 'v')
|
||||||
|
ch = L'\v';
|
||||||
|
else if (str[0] == 'a')
|
||||||
|
ch = L'\a';
|
||||||
|
else if (octal_digit(str[0])) {
|
||||||
|
i = 0;
|
||||||
|
do {
|
||||||
|
digs[dno++] = str[i++];
|
||||||
|
} while (octal_digit(str[i]) && dno < 3);
|
||||||
|
ch = strtol(digs, NULL, 8);
|
||||||
|
}
|
||||||
|
else if (str[0] == 'x') {
|
||||||
|
while (hex_digit(str[i]) && dno < 2) {
|
||||||
|
digs[dno++] = str[i++];
|
||||||
|
}
|
||||||
|
if (dno > 0)
|
||||||
|
ch = strtol(digs, NULL, 16);
|
||||||
|
}
|
||||||
|
else if (str[0] == 'u') {
|
||||||
|
while (hex_digit(str[i]) && dno < 4) {
|
||||||
|
digs[dno++] = str[i++];
|
||||||
|
}
|
||||||
|
if (dno > 0)
|
||||||
|
ch = strtol(digs, NULL, 16);
|
||||||
|
}
|
||||||
|
else if (str[0] == 'U') {
|
||||||
|
while (hex_digit(str[i]) && dno < 8) {
|
||||||
|
digs[dno++] = str[i++];
|
||||||
|
}
|
||||||
|
if (dno > 0)
|
||||||
|
ch = strtol(digs, NULL, 16);
|
||||||
|
}
|
||||||
|
*dest = ch;
|
||||||
|
|
||||||
|
return i;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* convert a string with literal \uxxxx or \Uxxxxxxxx characters to UTF-8
|
||||||
|
example: u8_unescape(mybuf, 256, "hello\\u220e")
|
||||||
|
note the double backslash is needed if called on a C string literal */
|
||||||
|
int u8_unescape(char *buf, int sz, char *src)
|
||||||
|
{
|
||||||
|
int c=0, amt;
|
||||||
|
u_int32_t ch;
|
||||||
|
char temp[4];
|
||||||
|
|
||||||
|
while (*src && c < sz) {
|
||||||
|
if (*src == '\\') {
|
||||||
|
src++;
|
||||||
|
amt = u8_read_escape_sequence(src, &ch);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
ch = (u_int32_t)*src;
|
||||||
|
amt = 1;
|
||||||
|
}
|
||||||
|
src += amt;
|
||||||
|
amt = u8_wc_toutf8(temp, ch);
|
||||||
|
if (amt > sz-c)
|
||||||
|
break;
|
||||||
|
memcpy(&buf[c], temp, amt);
|
||||||
|
c += amt;
|
||||||
|
}
|
||||||
|
if (c < sz)
|
||||||
|
buf[c] = '\0';
|
||||||
|
return c;
|
||||||
|
}
|
||||||
|
|
||||||
|
int u8_escape_wchar(char *buf, int sz, u_int32_t ch)
|
||||||
|
{
|
||||||
|
if (ch == L'\n')
|
||||||
|
return snprintf(buf, sz, "\\n");
|
||||||
|
else if (ch == L'\t')
|
||||||
|
return snprintf(buf, sz, "\\t");
|
||||||
|
else if (ch == L'\r')
|
||||||
|
return snprintf(buf, sz, "\\r");
|
||||||
|
else if (ch == L'\b')
|
||||||
|
return snprintf(buf, sz, "\\b");
|
||||||
|
else if (ch == L'\f')
|
||||||
|
return snprintf(buf, sz, "\\f");
|
||||||
|
else if (ch == L'\v')
|
||||||
|
return snprintf(buf, sz, "\\v");
|
||||||
|
else if (ch == L'\a')
|
||||||
|
return snprintf(buf, sz, "\\a");
|
||||||
|
else if (ch == L'\\')
|
||||||
|
return snprintf(buf, sz, "\\\\");
|
||||||
|
else if (ch < 32 || ch == 0x7f)
|
||||||
|
return snprintf(buf, sz, "\\x%hhX", (unsigned char)ch);
|
||||||
|
else if (ch > 0xFFFF)
|
||||||
|
return snprintf(buf, sz, "\\U%.8X", (u_int32_t)ch);
|
||||||
|
else if (ch >= 0x80 && ch <= 0xFFFF)
|
||||||
|
return snprintf(buf, sz, "\\u%.4hX", (unsigned short)ch);
|
||||||
|
|
||||||
|
return snprintf(buf, sz, "%c", (char)ch);
|
||||||
|
}
|
||||||
|
|
||||||
|
int u8_escape(char *buf, int sz, char *src, int escape_quotes)
|
||||||
|
{
|
||||||
|
int c=0, i=0, amt;
|
||||||
|
|
||||||
|
while (src[i] && c < sz) {
|
||||||
|
if (escape_quotes && src[i] == '"') {
|
||||||
|
amt = snprintf(buf, sz - c, "\\\"");
|
||||||
|
i++;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
amt = u8_escape_wchar(buf, sz - c, u8_nextchar(src, &i));
|
||||||
|
}
|
||||||
|
c += amt;
|
||||||
|
buf += amt;
|
||||||
|
}
|
||||||
|
if (c < sz)
|
||||||
|
*buf = '\0';
|
||||||
|
return c;
|
||||||
|
}
|
||||||
|
|
||||||
|
char *u8_strchr(char *s, u_int32_t ch, int *charn)
|
||||||
|
{
|
||||||
|
int i = 0, lasti=0;
|
||||||
|
u_int32_t c;
|
||||||
|
|
||||||
|
*charn = 0;
|
||||||
|
while (s[i]) {
|
||||||
|
c = u8_nextchar(s, &i);
|
||||||
|
if (c == ch) {
|
||||||
|
return &s[lasti];
|
||||||
|
}
|
||||||
|
lasti = i;
|
||||||
|
(*charn)++;
|
||||||
|
}
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
char *u8_memchr(char *s, u_int32_t ch, size_t sz, int *charn)
|
||||||
|
{
|
||||||
|
int i = 0, lasti=0;
|
||||||
|
u_int32_t c;
|
||||||
|
int csz;
|
||||||
|
|
||||||
|
*charn = 0;
|
||||||
|
while (i < sz) {
|
||||||
|
c = csz = 0;
|
||||||
|
do {
|
||||||
|
c <<= 6;
|
||||||
|
c += (unsigned char)s[i++];
|
||||||
|
csz++;
|
||||||
|
} while (i < sz && !isutf(s[i]));
|
||||||
|
c -= offsetsFromUTF8[csz-1];
|
||||||
|
|
||||||
|
if (c == ch) {
|
||||||
|
return &s[lasti];
|
||||||
|
}
|
||||||
|
lasti = i;
|
||||||
|
(*charn)++;
|
||||||
|
}
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
int u8_is_locale_utf8(char *locale)
|
||||||
|
{
|
||||||
|
/* this code based on libutf8 */
|
||||||
|
const char* cp = locale;
|
||||||
|
|
||||||
|
for (; *cp != '\0' && *cp != '@' && *cp != '+' && *cp != ','; cp++) {
|
||||||
|
if (*cp == '.') {
|
||||||
|
const char* encoding = ++cp;
|
||||||
|
for (; *cp != '\0' && *cp != '@' && *cp != '+' && *cp != ','; cp++)
|
||||||
|
;
|
||||||
|
if ((cp-encoding == 5 && !strncmp(encoding, "UTF-8", 5))
|
||||||
|
|| (cp-encoding == 4 && !strncmp(encoding, "utf8", 4)))
|
||||||
|
return 1; /* it's UTF-8 */
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
int u8_vprintf(char *fmt, va_list ap)
|
||||||
|
{
|
||||||
|
int cnt, sz=0;
|
||||||
|
char *buf;
|
||||||
|
u_int32_t *wcs;
|
||||||
|
|
||||||
|
sz = 512;
|
||||||
|
buf = (char*)alloca(sz);
|
||||||
|
try_print:
|
||||||
|
cnt = vsnprintf(buf, sz, fmt, ap);
|
||||||
|
if (cnt >= sz) {
|
||||||
|
buf = (char*)alloca(cnt - sz + 1);
|
||||||
|
sz = cnt + 1;
|
||||||
|
goto try_print;
|
||||||
|
}
|
||||||
|
wcs = (u_int32_t*)alloca((cnt+1) * sizeof(u_int32_t));
|
||||||
|
cnt = u8_toucs(wcs, cnt+1, buf, cnt);
|
||||||
|
printf("%ls", (wchar_t*)wcs);
|
||||||
|
return cnt;
|
||||||
|
}
|
||||||
|
|
||||||
|
int u8_printf(char *fmt, ...)
|
||||||
|
{
|
||||||
|
int cnt;
|
||||||
|
va_list args;
|
||||||
|
|
||||||
|
va_start(args, fmt);
|
||||||
|
|
||||||
|
cnt = u8_vprintf(fmt, args);
|
||||||
|
|
||||||
|
va_end(args);
|
||||||
|
return cnt;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
// task - a command line task list manager.
|
||||||
|
//
|
||||||
|
// Copyright 2006 - 2009, Paul Beckingham.
|
||||||
|
// All rights reserved.
|
||||||
|
//
|
||||||
|
// This program is free software; you can redistribute it and/or modify it under
|
||||||
|
// the terms of the GNU General Public License as published by the Free Software
|
||||||
|
// Foundation; either version 2 of the License, or (at your option) any later
|
||||||
|
// version.
|
||||||
|
//
|
||||||
|
// This program is distributed in the hope that it will be useful, but WITHOUT
|
||||||
|
// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
|
||||||
|
// FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
|
||||||
|
// details.
|
||||||
|
//
|
||||||
|
// You should have received a copy of the GNU General Public License along with
|
||||||
|
// this program; if not, write to the
|
||||||
|
//
|
||||||
|
// Free Software Foundation, Inc.,
|
||||||
|
// 51 Franklin Street, Fifth Floor,
|
||||||
|
// Boston, MA
|
||||||
|
// 02110-1301
|
||||||
|
// USA
|
||||||
|
//
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
#include "utf8.h"
|
||||||
|
|
||||||
|
static const u_int32_t offsetsFromUTF8[6] =
|
||||||
|
{
|
||||||
|
0x00000000UL, 0x00003080UL, 0x000E2080UL,
|
||||||
|
0x03C82080UL, 0xFA082080UL, 0x82082080UL,
|
||||||
|
};
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
// number of characters in a string.
|
||||||
|
int utf8_length (const std::string& s)
|
||||||
|
{
|
||||||
|
int count = 0;
|
||||||
|
int i = 0;
|
||||||
|
|
||||||
|
while (utf8_nextchar (s.c_str (), &i) != 0)
|
||||||
|
count++;
|
||||||
|
|
||||||
|
return count;
|
||||||
|
}
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
// reads the next utf-8 sequence out of a string, updating an index.
|
||||||
|
u_int32_t utf8_nextchar (const char* s, int* i)
|
||||||
|
{
|
||||||
|
u_int32_t ch = 0;
|
||||||
|
int sz = 0;
|
||||||
|
|
||||||
|
do
|
||||||
|
{
|
||||||
|
ch <<= 6;
|
||||||
|
ch += (unsigned char) s[(*i)++];
|
||||||
|
sz++;
|
||||||
|
}
|
||||||
|
while (s[*i] && ! isutf (s[*i]));
|
||||||
|
|
||||||
|
return ch - offsetsFromUTF8[sz - 1];
|
||||||
|
}
|
||||||
|
|
||||||
113
src/utf8.h
Normal file
113
src/utf8.h
Normal file
@@ -0,0 +1,113 @@
|
|||||||
|
#ifdef NOPE
|
||||||
|
#include <stdarg.h>
|
||||||
|
|
||||||
|
/* is c the start of a utf8 sequence? */
|
||||||
|
#define isutf(c) (((c)&0xC0)!=0x80)
|
||||||
|
|
||||||
|
/* convert UTF-8 data to wide character */
|
||||||
|
int u8_toucs(u_int32_t *dest, int sz, char *src, int srcsz);
|
||||||
|
|
||||||
|
/* the opposite conversion */
|
||||||
|
int u8_toutf8(char *dest, int sz, u_int32_t *src, int srcsz);
|
||||||
|
|
||||||
|
/* single character to UTF-8 */
|
||||||
|
int u8_wc_toutf8(char *dest, u_int32_t ch);
|
||||||
|
|
||||||
|
/* character number to byte offset */
|
||||||
|
int u8_offset(char *str, int charnum);
|
||||||
|
|
||||||
|
/* byte offset to character number */
|
||||||
|
int u8_charnum(char *s, int offset);
|
||||||
|
|
||||||
|
/* return next character, updating an index variable */
|
||||||
|
u_int32_t u8_nextchar(char *s, int *i);
|
||||||
|
|
||||||
|
/* move to next character */
|
||||||
|
void u8_inc(char *s, int *i);
|
||||||
|
|
||||||
|
/* move to previous character */
|
||||||
|
void u8_dec(char *s, int *i);
|
||||||
|
|
||||||
|
/* returns length of next utf-8 sequence */
|
||||||
|
int u8_seqlen(char *s);
|
||||||
|
|
||||||
|
/* assuming src points to the character after a backslash, read an
|
||||||
|
escape sequence, storing the result in dest and returning the number of
|
||||||
|
input characters processed */
|
||||||
|
int u8_read_escape_sequence(char *src, u_int32_t *dest);
|
||||||
|
|
||||||
|
/* given a wide character, convert it to an ASCII escape sequence stored in
|
||||||
|
buf, where buf is "sz" bytes. returns the number of characters output. */
|
||||||
|
int u8_escape_wchar(char *buf, int sz, u_int32_t ch);
|
||||||
|
|
||||||
|
/* convert a string "src" containing escape sequences to UTF-8 */
|
||||||
|
int u8_unescape(char *buf, int sz, char *src);
|
||||||
|
|
||||||
|
/* convert UTF-8 "src" to ASCII with escape sequences.
|
||||||
|
if escape_quotes is nonzero, quote characters will be preceded by
|
||||||
|
backslashes as well. */
|
||||||
|
int u8_escape(char *buf, int sz, char *src, int escape_quotes);
|
||||||
|
|
||||||
|
/* utility predicates used by the above */
|
||||||
|
int octal_digit(char c);
|
||||||
|
int hex_digit(char c);
|
||||||
|
|
||||||
|
/* return a pointer to the first occurrence of ch in s, or NULL if not
|
||||||
|
found. character index of found character returned in *charn. */
|
||||||
|
char *u8_strchr(char *s, u_int32_t ch, int *charn);
|
||||||
|
|
||||||
|
/* same as the above, but searches a buffer of a given size instead of
|
||||||
|
a NUL-terminated string. */
|
||||||
|
char *u8_memchr(char *s, u_int32_t ch, size_t sz, int *charn);
|
||||||
|
|
||||||
|
/* count the number of characters in a UTF-8 string */
|
||||||
|
int u8_strlen(char *s);
|
||||||
|
|
||||||
|
int u8_is_locale_utf8(char *locale);
|
||||||
|
|
||||||
|
/* printf where the format string and arguments may be in UTF-8.
|
||||||
|
you can avoid this function and just use ordinary printf() if the current
|
||||||
|
locale is UTF-8. */
|
||||||
|
int u8_vprintf(char *fmt, va_list ap);
|
||||||
|
int u8_printf(char *fmt, ...);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
// task - a command line task list manager.
|
||||||
|
//
|
||||||
|
// Copyright 2006 - 2009, Paul Beckingham.
|
||||||
|
// All rights reserved.
|
||||||
|
//
|
||||||
|
// This program is free software; you can redistribute it and/or modify it under
|
||||||
|
// the terms of the GNU General Public License as published by the Free Software
|
||||||
|
// Foundation; either version 2 of the License, or (at your option) any later
|
||||||
|
// version.
|
||||||
|
//
|
||||||
|
// This program is distributed in the hope that it will be useful, but WITHOUT
|
||||||
|
// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
|
||||||
|
// FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
|
||||||
|
// details.
|
||||||
|
//
|
||||||
|
// You should have received a copy of the GNU General Public License along with
|
||||||
|
// this program; if not, write to the
|
||||||
|
//
|
||||||
|
// Free Software Foundation, Inc.,
|
||||||
|
// 51 Franklin Street, Fifth Floor,
|
||||||
|
// Boston, MA
|
||||||
|
// 02110-1301
|
||||||
|
// USA
|
||||||
|
//
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
#ifndef INCLUDED_UTF8
|
||||||
|
#define INCLUDED_UTF8
|
||||||
|
|
||||||
|
#include <string>
|
||||||
|
|
||||||
|
// is c the start of a utf8 sequence?
|
||||||
|
#define isutf(c) (((c)&0xC0)!=0x80)
|
||||||
|
|
||||||
|
int utf8_length (const std::string&);
|
||||||
|
u_int32_t utf8_nextchar (const char*, int*);
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
Reference in New Issue
Block a user