mirror of
https://github.com/GothenburgBitFactory/taskwarrior.git
synced 2025-06-26 10:54:26 +02:00
Code Cleanup
- Integrated Context.config. - Eliminated Config& as a function argument. - Added extern references to Context where needed.
This commit is contained in:
parent
98978c7c00
commit
66bd5fc3c0
29 changed files with 1115 additions and 451 deletions
107
src/command.cpp
107
src/command.cpp
|
@ -44,8 +44,10 @@
|
|||
#include <ncurses.h>
|
||||
#endif
|
||||
|
||||
extern Context context;
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
std::string handleAdd (TDB& tdb, T& task, Config& conf)
|
||||
std::string handleAdd (TDB& tdb, T& task)
|
||||
{
|
||||
std::stringstream out;
|
||||
|
||||
|
@ -69,12 +71,12 @@ std::string handleAdd (TDB& tdb, T& task, Config& conf)
|
|||
|
||||
// Override with default.project, if not specified.
|
||||
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.
|
||||
if (task.getAttribute ("priority") == "")
|
||||
{
|
||||
std::string defaultPriority = conf.get ("default.priority", "");
|
||||
std::string defaultPriority = context.config.get ("default.priority", "");
|
||||
if (validPriority (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;
|
||||
|
||||
|
@ -114,14 +116,15 @@ std::string handleProjects (TDB& tdb, T& task, Config& conf)
|
|||
table.addColumn ("Project");
|
||||
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 (1);
|
||||
}
|
||||
|
||||
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)
|
||||
{
|
||||
|
@ -130,9 +133,9 @@ std::string handleProjects (TDB& tdb, T& task, Config& conf)
|
|||
table.addCell (row, 1, i->second);
|
||||
}
|
||||
|
||||
out << optionalBlankLine (conf)
|
||||
out << optionalBlankLine ()
|
||||
<< table.render ()
|
||||
<< optionalBlankLine (conf)
|
||||
<< optionalBlankLine ()
|
||||
<< unique.size ()
|
||||
<< (unique.size () == 1 ? " project" : " projects")
|
||||
<< 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;
|
||||
|
||||
|
@ -168,12 +171,12 @@ std::string handleTags (TDB& tdb, T& task, Config& conf)
|
|||
}
|
||||
|
||||
// Render a list of tag names from the map.
|
||||
std::cout << optionalBlankLine (conf);
|
||||
std::cout << optionalBlankLine ();
|
||||
foreach (i, unique)
|
||||
std::cout << i->first << std::endl;
|
||||
|
||||
if (unique.size ())
|
||||
out << optionalBlankLine (conf)
|
||||
out << optionalBlankLine ()
|
||||
<< unique.size ()
|
||||
<< (unique.size () == 1 ? " tag" : " tags")
|
||||
<< 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
|
||||
// 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;
|
||||
|
||||
|
@ -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
|
||||
// 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;
|
||||
|
||||
|
@ -261,14 +264,14 @@ std::string handleUndo (TDB& tdb, T& task, Config& conf)
|
|||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
std::string handleVersion (Config& conf)
|
||||
std::string handleVersion ()
|
||||
{
|
||||
std::stringstream out;
|
||||
|
||||
// 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
|
||||
if (conf.get ("curses", true))
|
||||
if (context.config.get ("curses", true))
|
||||
{
|
||||
WINDOW* w = initscr ();
|
||||
width = w->_maxx + 1;
|
||||
|
@ -301,11 +304,11 @@ std::string handleVersion (Config& conf)
|
|||
// Create a table for output.
|
||||
Table table;
|
||||
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 ("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 (1);
|
||||
|
@ -320,10 +323,10 @@ std::string handleVersion (Config& conf)
|
|||
table.sortOn (0, Table::ascendingCharacter);
|
||||
|
||||
std::vector <std::string> all;
|
||||
conf.all (all);
|
||||
context.config.all (all);
|
||||
foreach (i, all)
|
||||
{
|
||||
std::string value = conf.get (*i);
|
||||
std::string value = context.config.get (*i);
|
||||
if (value != "")
|
||||
{
|
||||
int row = table.addRow ();
|
||||
|
@ -334,11 +337,11 @@ std::string handleVersion (Config& conf)
|
|||
|
||||
out << "Copyright (C) 2006 - 2009, P. Beckingham."
|
||||
<< 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)
|
||||
: 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)
|
||||
: VERSION)
|
||||
<< std::endl
|
||||
|
@ -407,12 +410,12 @@ std::string handleVersion (Config& conf)
|
|||
<< std::endl;
|
||||
else
|
||||
{
|
||||
if (conf.get ("data.location") == "")
|
||||
if (context.config.get ("data.location") == "")
|
||||
out << "Configuration error: data.location not specified in .taskrc "
|
||||
"file."
|
||||
<< 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"
|
||||
" that doesn't exist, or is unreadable."
|
||||
<< 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;
|
||||
|
||||
|
@ -443,7 +446,7 @@ std::string handleDelete (TDB& tdb, T& task, Config& conf)
|
|||
<< 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
|
||||
// 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);
|
||||
tdb.modifyT (*sibling);
|
||||
|
||||
if (conf.get ("echo.command", true))
|
||||
if (context.config.get ("echo.command", true))
|
||||
out << "Deleting recurring task "
|
||||
<< sibling->getId ()
|
||||
<< " '"
|
||||
|
@ -496,7 +499,7 @@ std::string handleDelete (TDB& tdb, T& task, Config& conf)
|
|||
t->setAttribute ("end", endTime);
|
||||
tdb.modifyT (*t);
|
||||
|
||||
if (conf.get ("echo.command", true))
|
||||
if (context.config.get ("echo.command", true))
|
||||
out << "Deleting task "
|
||||
<< 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;
|
||||
|
||||
|
@ -531,14 +534,14 @@ std::string handleStart (TDB& tdb, T& task, Config& conf)
|
|||
|
||||
tdb.modifyT (*t);
|
||||
|
||||
if (conf.get ("echo.command", true))
|
||||
if (context.config.get ("echo.command", true))
|
||||
out << "Started "
|
||||
<< t->getId ()
|
||||
<< " '"
|
||||
<< t->getDescription ()
|
||||
<< "'"
|
||||
<< std::endl;
|
||||
nag (tdb, task, conf);
|
||||
nag (tdb, task);
|
||||
}
|
||||
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;
|
||||
|
||||
|
@ -565,7 +568,7 @@ std::string handleStop (TDB& tdb, T& task, Config& conf)
|
|||
t->removeAttribute ("start");
|
||||
tdb.modifyT (*t);
|
||||
|
||||
if (conf.get ("echo.command", true))
|
||||
if (context.config.get ("echo.command", true))
|
||||
out << "Stopped " << t->getId () << " '" << t->getDescription () << "'" << std::endl;
|
||||
}
|
||||
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;
|
||||
std::stringstream out;
|
||||
|
@ -608,7 +611,7 @@ std::string handleDone (TDB& tdb, T& task, Config& conf)
|
|||
if (!tdb.modifyT (*seq))
|
||||
throw std::string ("Could not mark task as completed.");
|
||||
|
||||
if (conf.get ("echo.command", true))
|
||||
if (context.config.get ("echo.command", true))
|
||||
out << "Completed "
|
||||
<< seq->getId ()
|
||||
<< " '"
|
||||
|
@ -617,7 +620,7 @@ std::string handleDone (TDB& tdb, T& task, Config& conf)
|
|||
<< std::endl;
|
||||
|
||||
updateRecurrenceMask (tdb, all, *seq);
|
||||
nag (tdb, *seq, conf);
|
||||
nag (tdb, *seq);
|
||||
|
||||
++count;
|
||||
}
|
||||
|
@ -630,7 +633,7 @@ std::string handleDone (TDB& tdb, T& task, Config& conf)
|
|||
<< std::endl;
|
||||
}
|
||||
|
||||
if (conf.get ("echo.command", true))
|
||||
if (context.config.get ("echo.command", true))
|
||||
out << "Marked "
|
||||
<< count
|
||||
<< " 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;
|
||||
|
||||
|
@ -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;
|
||||
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;
|
||||
|
||||
return out.str ();
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
std::string handleAppend (TDB& tdb, T& task, Config& conf)
|
||||
std::string handleAppend (TDB& tdb, T& task)
|
||||
{
|
||||
int count = 0;
|
||||
std::stringstream out;
|
||||
|
@ -783,7 +786,7 @@ std::string handleAppend (TDB& tdb, T& task, Config& conf)
|
|||
{
|
||||
tdb.modifyT (*other);
|
||||
|
||||
if (conf.get ("echo.command", true))
|
||||
if (context.config.get ("echo.command", true))
|
||||
out << "Appended '"
|
||||
<< task.getDescription ()
|
||||
<< "' 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;
|
||||
|
||||
return out.str ();
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
std::string handleDuplicate (TDB& tdb, T& task, Config& conf)
|
||||
std::string handleDuplicate (TDB& tdb, T& task)
|
||||
{
|
||||
int count = 0;
|
||||
std::stringstream out;
|
||||
|
@ -833,7 +836,7 @@ std::string handleDuplicate (TDB& tdb, T& task, Config& conf)
|
|||
if (!tdb.addT (dup))
|
||||
throw std::string ("Could not create new task.");
|
||||
|
||||
if (conf.get ("echo.command", true))
|
||||
if (context.config.get ("echo.command", true))
|
||||
out << "Duplicated "
|
||||
<< seq->getId ()
|
||||
<< " '"
|
||||
|
@ -851,20 +854,20 @@ std::string handleDuplicate (TDB& tdb, T& task, Config& conf)
|
|||
<< std::endl;
|
||||
}
|
||||
|
||||
if (conf.get ("echo.command", true))
|
||||
if (context.config.get ("echo.command", true))
|
||||
out << "Duplicated " << count << " task" << (count == 1 ? "" : "s") << std::endl;
|
||||
|
||||
return out.str ();
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
std::string handleColor (Config& conf)
|
||||
std::string handleColor ()
|
||||
{
|
||||
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::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_bright_white, "on_bright_white") << std::endl
|
||||
|
||||
<< optionalBlankLine (conf);
|
||||
<< optionalBlankLine ();
|
||||
}
|
||||
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 () == "")
|
||||
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 ());
|
||||
tdb.modifyT (*t);
|
||||
|
||||
if (conf.get ("echo.command", true))
|
||||
if (context.config.get ("echo.command", true))
|
||||
out << "Annotated "
|
||||
<< t->getId ()
|
||||
<< " with '"
|
||||
|
|
44
src/edit.cpp
44
src/edit.cpp
|
@ -40,6 +40,8 @@
|
|||
#include "util.h"
|
||||
#include "task.h"
|
||||
|
||||
extern Context context;
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
static std::string findValue (
|
||||
const std::string& text,
|
||||
|
@ -64,7 +66,6 @@ static std::string findValue (
|
|||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
static std::string findDate (
|
||||
Config& conf,
|
||||
const std::string& text,
|
||||
const std::string& name)
|
||||
{
|
||||
|
@ -80,7 +81,7 @@ static std::string findDate (
|
|||
|
||||
if (value != "")
|
||||
{
|
||||
Date dt (value, conf.get ("dateformat", "m/d/Y"));
|
||||
Date dt (value, context.config.get ("dateformat", "m/d/Y"));
|
||||
char epoch [16];
|
||||
sprintf (epoch, "%d", (int)dt.toEpoch ());
|
||||
return std::string (epoch);
|
||||
|
@ -107,7 +108,6 @@ static std::string formatStatus (T& task)
|
|||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
static std::string formatDate (
|
||||
Config& conf,
|
||||
T& task,
|
||||
const std::string& attribute)
|
||||
{
|
||||
|
@ -115,14 +115,14 @@ static std::string formatDate (
|
|||
if (value.length ())
|
||||
{
|
||||
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;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
static std::string formatTask (Config& conf, T task)
|
||||
static std::string formatTask (T task)
|
||||
{
|
||||
std::stringstream before;
|
||||
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
|
||||
<< "# will combine them." << std::endl
|
||||
<< " Description: " << task.getDescription () << std::endl
|
||||
<< " Created: " << formatDate (conf, task, "entry") << std::endl
|
||||
<< " Started: " << formatDate (conf, task, "start") << std::endl
|
||||
<< " Ended: " << formatDate (conf, task, "end") << std::endl
|
||||
<< " Due: " << formatDate (conf, task, "due") << std::endl
|
||||
<< " Until: " << formatDate (conf, task, "until") << std::endl
|
||||
<< " Created: " << formatDate (task, "entry") << std::endl
|
||||
<< " Started: " << formatDate (task, "start") << std::endl
|
||||
<< " Ended: " << formatDate (task, "end") << std::endl
|
||||
<< " Due: " << formatDate (task, "due") << std::endl
|
||||
<< " Until: " << formatDate (task, "until") << std::endl
|
||||
<< " Recur: " << task.getAttribute ("recur") << std::endl
|
||||
<< " Parent: " << task.getAttribute ("parent") << std::endl
|
||||
<< " Foreground color: " << task.getAttribute ("fg") << std::endl
|
||||
|
@ -176,7 +176,7 @@ static std::string formatTask (Config& conf, T task)
|
|||
foreach (anno, annotations)
|
||||
{
|
||||
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;
|
||||
}
|
||||
|
||||
|
@ -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
|
||||
std::string value = findValue (after, "Project:");
|
||||
|
@ -245,7 +245,7 @@ static void parseTask (Config& conf, T& task, const std::string& after)
|
|||
}
|
||||
|
||||
// entry
|
||||
value = findDate (conf, after, "Created:");
|
||||
value = findDate (after, "Created:");
|
||||
if (value != "")
|
||||
{
|
||||
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");
|
||||
|
||||
// start
|
||||
value = findDate (conf, after, "Started:");
|
||||
value = findDate (after, "Started:");
|
||||
if (value != "")
|
||||
{
|
||||
Date edited (::atoi (value.c_str ()));
|
||||
|
@ -291,7 +291,7 @@ static void parseTask (Config& conf, T& task, const std::string& after)
|
|||
}
|
||||
|
||||
// end
|
||||
value = findDate (conf, after, "Ended:");
|
||||
value = findDate (after, "Ended:");
|
||||
if (value != "")
|
||||
{
|
||||
Date edited (::atoi (value.c_str ()));
|
||||
|
@ -319,7 +319,7 @@ static void parseTask (Config& conf, T& task, const std::string& after)
|
|||
}
|
||||
|
||||
// due
|
||||
value = findDate (conf, after, "Due:");
|
||||
value = findDate (after, "Due:");
|
||||
if (value != "")
|
||||
{
|
||||
Date edited (::atoi (value.c_str ()));
|
||||
|
@ -357,7 +357,7 @@ static void parseTask (Config& conf, T& task, const std::string& after)
|
|||
}
|
||||
|
||||
// until
|
||||
value = findDate (conf, after, "Until:");
|
||||
value = findDate (after, "Until:");
|
||||
if (value != "")
|
||||
{
|
||||
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
|
||||
// various other ills. This is like opening up the hood and going in with a
|
||||
// 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::vector <T> all;
|
||||
|
@ -506,7 +506,7 @@ std::string handleEdit (TDB& tdb, T& task, Config& conf)
|
|||
foreach (seq, all)
|
||||
{
|
||||
// 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))
|
||||
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;
|
||||
|
||||
// Format the contents, T -> text, write to a file.
|
||||
std::string before = formatTask (conf, *seq);
|
||||
std::string before = formatTask (*seq);
|
||||
spit (file, before);
|
||||
|
||||
// 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");
|
||||
if (editor == "" && peditor) editor = std::string (peditor);
|
||||
peditor = getenv ("EDITOR");
|
||||
|
@ -558,7 +558,7 @@ ARE_THESE_REALLY_HARMFUL:
|
|||
|
||||
try
|
||||
{
|
||||
parseTask (conf, *seq, after);
|
||||
parseTask (*seq, after);
|
||||
tdb.modifyT (*seq);
|
||||
}
|
||||
|
||||
|
|
|
@ -35,6 +35,8 @@
|
|||
#include "util.h"
|
||||
#include "task.h"
|
||||
|
||||
extern Context context;
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
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];
|
||||
sprintf (entryTime, "%u", (unsigned int) time (NULL));
|
||||
task.setAttribute ("entry", entryTime);
|
||||
|
||||
// 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 != "")
|
||||
task.setAttribute ("project", defaultProject);
|
||||
|
||||
// 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") == "" &&
|
||||
defaultPriority != "" &&
|
||||
validPriority (defaultPriority))
|
||||
|
@ -181,7 +183,6 @@ static void decorateTask (T& task, Config& conf)
|
|||
////////////////////////////////////////////////////////////////////////////////
|
||||
static std::string importTask_1_4_3 (
|
||||
TDB& tdb,
|
||||
Config& conf,
|
||||
const std::vector <std::string>& lines)
|
||||
{
|
||||
std::vector <std::string> failed;
|
||||
|
@ -337,7 +338,6 @@ static std::string importTask_1_4_3 (
|
|||
////////////////////////////////////////////////////////////////////////////////
|
||||
static std::string importTask_1_5_0 (
|
||||
TDB& tdb,
|
||||
Config& conf,
|
||||
const std::vector <std::string>& lines)
|
||||
{
|
||||
std::vector <std::string> failed;
|
||||
|
@ -498,7 +498,6 @@ static std::string importTask_1_5_0 (
|
|||
////////////////////////////////////////////////////////////////////////////////
|
||||
static std::string importTask_1_6_0 (
|
||||
TDB& tdb,
|
||||
Config& conf,
|
||||
const std::vector <std::string>& lines)
|
||||
{
|
||||
std::vector <std::string> failed;
|
||||
|
@ -659,7 +658,6 @@ static std::string importTask_1_6_0 (
|
|||
////////////////////////////////////////////////////////////////////////////////
|
||||
static std::string importTaskCmdLine (
|
||||
TDB& tdb,
|
||||
Config& conf,
|
||||
const std::vector <std::string>& lines)
|
||||
{
|
||||
std::vector <std::string> failed;
|
||||
|
@ -676,8 +674,8 @@ static std::string importTaskCmdLine (
|
|||
|
||||
T task;
|
||||
std::string command;
|
||||
parse (args, command, task, conf);
|
||||
handleAdd (tdb, task, conf);
|
||||
parse (args, command, task);
|
||||
handleAdd (tdb, task);
|
||||
}
|
||||
|
||||
catch (...)
|
||||
|
@ -707,7 +705,6 @@ static std::string importTaskCmdLine (
|
|||
////////////////////////////////////////////////////////////////////////////////
|
||||
static std::string importTodoSh_2_0 (
|
||||
TDB& tdb,
|
||||
Config& conf,
|
||||
const std::vector <std::string>& lines)
|
||||
{
|
||||
std::vector <std::string> failed;
|
||||
|
@ -782,8 +779,8 @@ static std::string importTodoSh_2_0 (
|
|||
|
||||
T task;
|
||||
std::string command;
|
||||
parse (args, command, task, conf);
|
||||
decorateTask (task, conf);
|
||||
parse (args, command, task);
|
||||
decorateTask (task);
|
||||
|
||||
if (isPending)
|
||||
{
|
||||
|
@ -829,7 +826,6 @@ static std::string importTodoSh_2_0 (
|
|||
////////////////////////////////////////////////////////////////////////////////
|
||||
static std::string importText (
|
||||
TDB& tdb,
|
||||
Config& conf,
|
||||
const std::vector <std::string>& lines)
|
||||
{
|
||||
std::vector <std::string> failed;
|
||||
|
@ -856,8 +852,8 @@ static std::string importText (
|
|||
|
||||
T task;
|
||||
std::string command;
|
||||
parse (args, command, task, conf);
|
||||
decorateTask (task, conf);
|
||||
parse (args, command, task);
|
||||
decorateTask (task);
|
||||
|
||||
if (! tdb.addT (task))
|
||||
failed.push_back (*it);
|
||||
|
@ -891,7 +887,6 @@ static std::string importText (
|
|||
////////////////////////////////////////////////////////////////////////////////
|
||||
static std::string importCSV (
|
||||
TDB& tdb,
|
||||
Config& conf,
|
||||
const std::vector <std::string>& lines)
|
||||
{
|
||||
std::vector <std::string> failed;
|
||||
|
@ -921,7 +916,7 @@ static std::string importCSV (
|
|||
std::string name = lowerCase (trim (unquoteText (trim (headings[h]))));
|
||||
|
||||
// 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 == "#" ||
|
||||
name == "sequence" ||
|
||||
|
@ -930,7 +925,7 @@ static std::string importCSV (
|
|||
mapping["id"] = (int)h;
|
||||
}
|
||||
|
||||
else if (name == conf.get ("import.synonym.uuid") ||
|
||||
else if (name == context.config.get ("import.synonym.uuid") ||
|
||||
name == "uuid" ||
|
||||
name == "guid" ||
|
||||
name.find ("unique") != std::string::npos)
|
||||
|
@ -938,7 +933,7 @@ static std::string importCSV (
|
|||
mapping["uuid"] = (int)h;
|
||||
}
|
||||
|
||||
else if (name == conf.get ("import.synonym.status") ||
|
||||
else if (name == context.config.get ("import.synonym.status") ||
|
||||
name == "status" ||
|
||||
name == "condition" ||
|
||||
name == "state")
|
||||
|
@ -946,7 +941,7 @@ static std::string importCSV (
|
|||
mapping["status"] = (int)h;
|
||||
}
|
||||
|
||||
else if (name == conf.get ("import.synonym.tags") ||
|
||||
else if (name == context.config.get ("import.synonym.tags") ||
|
||||
name == "tags" ||
|
||||
name.find ("categor") != std::string::npos ||
|
||||
name.find ("tag") != std::string::npos)
|
||||
|
@ -954,7 +949,7 @@ static std::string importCSV (
|
|||
mapping["tags"] = (int)h;
|
||||
}
|
||||
|
||||
else if (name == conf.get ("import.synonym.entry") ||
|
||||
else if (name == context.config.get ("import.synonym.entry") ||
|
||||
name == "entry" ||
|
||||
name.find ("added") != std::string::npos ||
|
||||
name.find ("created") != std::string::npos ||
|
||||
|
@ -963,7 +958,7 @@ static std::string importCSV (
|
|||
mapping["entry"] = (int)h;
|
||||
}
|
||||
|
||||
else if (name == conf.get ("import.synonym.start") ||
|
||||
else if (name == context.config.get ("import.synonym.start") ||
|
||||
name == "start" ||
|
||||
name.find ("began") != std::string::npos ||
|
||||
name.find ("begun") != std::string::npos ||
|
||||
|
@ -972,21 +967,21 @@ static std::string importCSV (
|
|||
mapping["start"] = (int)h;
|
||||
}
|
||||
|
||||
else if (name == conf.get ("import.synonym.due") ||
|
||||
else if (name == context.config.get ("import.synonym.due") ||
|
||||
name == "due" ||
|
||||
name.find ("expected") != std::string::npos)
|
||||
{
|
||||
mapping["due"] = (int)h;
|
||||
}
|
||||
|
||||
else if (name == conf.get ("import.synonym.recur") ||
|
||||
else if (name == context.config.get ("import.synonym.recur") ||
|
||||
name == "recur" ||
|
||||
name == "frequency")
|
||||
{
|
||||
mapping["recur"] = (int)h;
|
||||
}
|
||||
|
||||
else if (name == conf.get ("import.synonym.end") ||
|
||||
else if (name == context.config.get ("import.synonym.end") ||
|
||||
name == "end" ||
|
||||
name == "done" ||
|
||||
name.find ("complete") != std::string::npos)
|
||||
|
@ -994,14 +989,14 @@ static std::string importCSV (
|
|||
mapping["end"] = (int)h;
|
||||
}
|
||||
|
||||
else if (name == conf.get ("import.synonym.project") ||
|
||||
else if (name == context.config.get ("import.synonym.project") ||
|
||||
name == "project" ||
|
||||
name.find ("proj") != std::string::npos)
|
||||
{
|
||||
mapping["project"] = (int)h;
|
||||
}
|
||||
|
||||
else if (name == conf.get ("import.synonym.priority") ||
|
||||
else if (name == context.config.get ("import.synonym.priority") ||
|
||||
name == "priority" ||
|
||||
name == "pri" ||
|
||||
name.find ("importan") != std::string::npos)
|
||||
|
@ -1009,7 +1004,7 @@ static std::string importCSV (
|
|||
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 ("foreground") != std::string::npos ||
|
||||
name.find ("color") != std::string::npos)
|
||||
|
@ -1017,14 +1012,14 @@ static std::string importCSV (
|
|||
mapping["fg"] = (int)h;
|
||||
}
|
||||
|
||||
else if (name == conf.get ("import.synonym.bg") ||
|
||||
else if (name == context.config.get ("import.synonym.bg") ||
|
||||
name == "bg" ||
|
||||
name.find ("background") != std::string::npos)
|
||||
{
|
||||
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 ("detail") != 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;
|
||||
|
||||
|
@ -1187,13 +1182,13 @@ std::string handleImport (TDB& tdb, T& task, Config& conf)
|
|||
// Determine which type it might be, then attempt an import.
|
||||
switch (type)
|
||||
{
|
||||
case task_1_4_3: out << importTask_1_4_3 (tdb, conf, lines); break;
|
||||
case task_1_5_0: out << importTask_1_5_0 (tdb, conf, lines); break;
|
||||
case task_1_6_0: out << importTask_1_6_0 (tdb, conf, lines); break;
|
||||
case task_cmd_line: out << importTaskCmdLine (tdb, conf, lines); break;
|
||||
case todo_sh_2_0: out << importTodoSh_2_0 (tdb, conf, lines); break;
|
||||
case csv: out << importCSV (tdb, conf, lines); break;
|
||||
case text: out << importText (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, lines); break;
|
||||
case task_1_6_0: out << importTask_1_6_0 (tdb, lines); break;
|
||||
case task_cmd_line: out << importTaskCmdLine (tdb, lines); break;
|
||||
case todo_sh_2_0: out << importTodoSh_2_0 (tdb, lines); break;
|
||||
case csv: out << importCSV (tdb, lines); break;
|
||||
case text: out << importText (tdb, lines); break;
|
||||
case not_a_clue: /* to stop the compiler from complaining. */ break;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -30,12 +30,15 @@
|
|||
#include <vector>
|
||||
#include <map>
|
||||
|
||||
#include "Context.h"
|
||||
#include "Date.h"
|
||||
#include "Duration.h"
|
||||
#include "T.h"
|
||||
#include "text.h"
|
||||
#include "util.h"
|
||||
|
||||
extern Context context;
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
// NOTE: These are static arrays only because there is no initializer list for
|
||||
// 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];
|
||||
sprintf (epoch, "%d", (int) test.toEpoch ());
|
||||
|
@ -248,8 +251,7 @@ bool validPriority (const std::string& input)
|
|||
////////////////////////////////////////////////////////////////////////////////
|
||||
static bool validAttribute (
|
||||
std::string& name,
|
||||
std::string& value,
|
||||
Config& conf)
|
||||
std::string& value)
|
||||
{
|
||||
guess ("attribute", attributes, name);
|
||||
if (name != "")
|
||||
|
@ -258,10 +260,10 @@ static bool validAttribute (
|
|||
guess ("color", colors, value);
|
||||
|
||||
else if (name == "due" && value != "")
|
||||
validDate (value, conf);
|
||||
validDate (value);
|
||||
|
||||
else if (name == "until" && value != "")
|
||||
validDate (value, conf);
|
||||
validDate (value);
|
||||
|
||||
else if (name == "priority")
|
||||
{
|
||||
|
@ -456,8 +458,7 @@ bool validDuration (std::string& input)
|
|||
void parse (
|
||||
std::vector <std::string>& args,
|
||||
std::string& command,
|
||||
T& task,
|
||||
Config& conf)
|
||||
T& task)
|
||||
{
|
||||
command = "";
|
||||
|
||||
|
@ -518,7 +519,7 @@ void parse (
|
|||
std::string name = lowerCase (arg.substr (0, colon));
|
||||
std::string value = arg.substr (colon + 1, std::string::npos);
|
||||
|
||||
if (validAttribute (name, value, conf))
|
||||
if (validAttribute (name, value))
|
||||
{
|
||||
if (name != "recur" || validDuration (value))
|
||||
task.setAttribute (name, value);
|
||||
|
@ -589,10 +590,10 @@ void parse (
|
|||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
void loadCustomReports (Config& conf)
|
||||
void loadCustomReports ()
|
||||
{
|
||||
std::vector <std::string> all;
|
||||
conf.all (all);
|
||||
context.config.all (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 <stdlib.h>
|
||||
#include "Config.h"
|
||||
#include "Context.h"
|
||||
#include "Table.h"
|
||||
#include "Date.h"
|
||||
#include "T.h"
|
||||
#include "text.h"
|
||||
#include "util.h"
|
||||
|
||||
extern Context context;
|
||||
|
||||
static std::map <std::string, Text::color> gsFg;
|
||||
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;
|
||||
conf.all (ruleNames);
|
||||
context.config.all (ruleNames);
|
||||
foreach (it, ruleNames)
|
||||
{
|
||||
if (it->substr (0, 6) == "color.")
|
||||
{
|
||||
Text::color fg;
|
||||
Text::color bg;
|
||||
parseColorRule (conf.get (*it), fg, bg);
|
||||
parseColorRule (context.config.get (*it), fg, bg);
|
||||
gsFg[*it] = fg;
|
||||
gsBg[*it] = bg;
|
||||
}
|
||||
|
@ -84,8 +86,7 @@ void initializeColorRules (Config& conf)
|
|||
void autoColorize (
|
||||
T& task,
|
||||
Text::color& fg,
|
||||
Text::color& bg,
|
||||
Config& conf)
|
||||
Text::color& bg)
|
||||
{
|
||||
// Note: fg, bg already contain colors specifically assigned via command.
|
||||
// Note: These rules form a hierarchy - the last rule is King.
|
||||
|
@ -208,7 +209,7 @@ void autoColorize (
|
|||
{
|
||||
Date dueDate (::atoi (due.c_str ()));
|
||||
Date now;
|
||||
Date then (now + conf.get ("due", 7) * 86400);
|
||||
Date then (now + context.config.get ("due", 7) * 86400);
|
||||
|
||||
// Overdue
|
||||
if (dueDate < now)
|
||||
|
|
|
@ -3,25 +3,26 @@
|
|||
#include <string>
|
||||
#include "Context.h"
|
||||
|
||||
Context context;
|
||||
|
||||
int main (int argc, char** argv)
|
||||
{
|
||||
try
|
||||
{
|
||||
Context c;
|
||||
c.initialize (argc, argv);
|
||||
// c.run ();
|
||||
context.initialize (argc, argv);
|
||||
// context.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;
|
||||
int quantity = c.tdb.load (tasks, c.filter);
|
||||
std::cout << "# " << quantity << " <-- c.tdb.load" << std::endl;
|
||||
int quantity = context.tdb.load (tasks, context.filter);
|
||||
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>
|
||||
#endif
|
||||
|
||||
// Global context for use by all.
|
||||
Context context;
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
static std::string shortUsage (Config& conf)
|
||||
static std::string shortUsage ()
|
||||
{
|
||||
std::stringstream out;
|
||||
Table table;
|
||||
int width = conf.get ("defaultwidth", (int) 80);
|
||||
int width = context.config.get ("defaultwidth", (int) 80);
|
||||
#ifdef HAVE_LIBNCURSES
|
||||
if (conf.get ("curses", true))
|
||||
if (context.config.get ("curses", true))
|
||||
{
|
||||
WINDOW* w = initscr ();
|
||||
width = w->_maxx + 1;
|
||||
|
@ -79,7 +80,7 @@ static std::string shortUsage (Config& conf)
|
|||
table.setColumnWidth (1, Table::minimum);
|
||||
table.setColumnWidth (2, Table::flexible);
|
||||
table.setTableWidth (width);
|
||||
table.setDateFormat (conf.get ("dateformat", "m/d/Y"));
|
||||
table.setDateFormat (context.config.get ("dateformat", "m/d/Y"));
|
||||
|
||||
int row = table.addRow ();
|
||||
table.addCell (row, 0, "Usage:");
|
||||
|
@ -219,7 +220,7 @@ static std::string shortUsage (Config& conf)
|
|||
foreach (report, all)
|
||||
{
|
||||
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)"));
|
||||
|
||||
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;
|
||||
out << shortUsage (conf)
|
||||
out << shortUsage ()
|
||||
<< "ID is the numeric identifier displayed by the 'task list' command. "
|
||||
<< "You can specify multiple IDs for task commands, and multiple tasks "
|
||||
<< "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 ();
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
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)
|
||||
{
|
||||
|
@ -323,30 +298,25 @@ int main (int argc, char** 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.
|
||||
if (!isatty (fileno (stdout)))
|
||||
{
|
||||
conf.set ("curses", "off");
|
||||
context.config.set ("curses", "off");
|
||||
|
||||
if (! conf.get (std::string ("_forcecolor"), false))
|
||||
conf.set ("color", "off");
|
||||
if (! context.config.get (std::string ("_forcecolor"), false))
|
||||
context.config.set ("color", "off");
|
||||
}
|
||||
|
||||
TDB tdb;
|
||||
std::string dataLocation = expandPath (conf.get ("data.location"));
|
||||
std::string dataLocation = expandPath (context.config.get ("data.location"));
|
||||
tdb.dataDirectory (dataLocation);
|
||||
|
||||
// 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 ();
|
||||
|
||||
// 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 == dataLocation + "/pending.data")
|
||||
|
@ -358,7 +328,7 @@ int main (int argc, char** argv)
|
|||
"overwrite your completed tasks. Please change it.");
|
||||
}
|
||||
|
||||
std::cout << runTaskCommand (argc, argv, tdb, conf);
|
||||
std::cout << runTaskCommand (argc, argv, tdb);
|
||||
}
|
||||
|
||||
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 != "")
|
||||
{
|
||||
// Load all pending tasks.
|
||||
|
@ -780,26 +750,26 @@ void updateRecurrenceMask (
|
|||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
void updateShadowFile (TDB& tdb, Config& conf)
|
||||
void updateShadowFile (TDB& tdb)
|
||||
{
|
||||
try
|
||||
{
|
||||
// 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 != "")
|
||||
{
|
||||
std::string oldCurses = conf.get ("curses");
|
||||
std::string oldColor = conf.get ("color");
|
||||
conf.set ("curses", "off");
|
||||
conf.set ("color", "off");
|
||||
std::string oldCurses = context.config.get ("curses");
|
||||
std::string oldColor = context.config.get ("color");
|
||||
context.config.set ("curses", "off");
|
||||
context.config.set ("color", "off");
|
||||
|
||||
// Run report. Use shadow.command, using default.command as a fallback
|
||||
// with "list" as a default.
|
||||
std::string command = conf.get ("shadow.command",
|
||||
conf.get ("default.command", "list"));
|
||||
std::string command = context.config.get ("shadow.command",
|
||||
context.config.get ("default.command", "list"));
|
||||
std::vector <std::string> args;
|
||||
split (args, command, ' ');
|
||||
std::string result = runTaskCommand (args, tdb, conf);
|
||||
std::string result = runTaskCommand (args, tdb);
|
||||
|
||||
std::ofstream out (shadowFile.c_str ());
|
||||
if (out.good ())
|
||||
|
@ -810,12 +780,12 @@ void updateShadowFile (TDB& tdb, Config& conf)
|
|||
else
|
||||
throw std::string ("Could not write file '") + shadowFile + "'";
|
||||
|
||||
conf.set ("curses", oldCurses);
|
||||
conf.set ("color", oldColor);
|
||||
context.config.set ("curses", oldCurses);
|
||||
context.config.set ("color", oldColor);
|
||||
}
|
||||
|
||||
// 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;
|
||||
}
|
||||
|
||||
|
@ -835,7 +805,6 @@ std::string runTaskCommand (
|
|||
int argc,
|
||||
char** argv,
|
||||
TDB& tdb,
|
||||
Config& conf,
|
||||
bool gc /* = true */,
|
||||
bool shadow /* = true */)
|
||||
{
|
||||
|
@ -843,20 +812,19 @@ std::string runTaskCommand (
|
|||
for (int i = 1; i < argc; ++i)
|
||||
args.push_back (argv[i]);
|
||||
|
||||
return runTaskCommand (args, tdb, conf, gc, shadow);
|
||||
return runTaskCommand (args, tdb, gc, shadow);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
std::string runTaskCommand (
|
||||
std::vector <std::string>& args,
|
||||
TDB& tdb,
|
||||
Config& conf,
|
||||
bool gc /* = false */,
|
||||
bool shadow /* = false */)
|
||||
{
|
||||
// If argc == 1 and the default.command configuration variable is set,
|
||||
// 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 ||
|
||||
(args.size () == 1 && args[0].substr (0, 3) == "rc:")) &&
|
||||
defaultCommand != "")
|
||||
|
@ -867,60 +835,60 @@ std::string runTaskCommand (
|
|||
std::cout << "[task " << defaultCommand << "]" << std::endl;
|
||||
}
|
||||
|
||||
loadCustomReports (conf);
|
||||
loadCustomReports ();
|
||||
|
||||
std::string command;
|
||||
T task;
|
||||
parse (args, command, task, conf);
|
||||
parse (args, command, task);
|
||||
|
||||
bool gcMod = false; // Change occurred by way of gc.
|
||||
bool cmdMod = false; // Change occurred by way of command type.
|
||||
std::string out;
|
||||
|
||||
// Read-only commands with no side effects.
|
||||
if (command == "export") { out = handleExport (tdb, task, conf); }
|
||||
else if (command == "projects") { out = handleProjects (tdb, task, conf); }
|
||||
else if (command == "tags") { out = handleTags (tdb, task, conf); }
|
||||
else if (command == "info") { out = handleInfo (tdb, task, conf); }
|
||||
else if (command == "stats") { out = handleReportStats (tdb, task, conf); }
|
||||
else if (command == "history") { out = handleReportHistory (tdb, task, conf); }
|
||||
else if (command == "ghistory") { out = handleReportGHistory (tdb, task, conf); }
|
||||
else if (command == "calendar") { out = handleReportCalendar (tdb, task, conf); }
|
||||
else if (command == "summary") { out = handleReportSummary (tdb, task, conf); }
|
||||
else if (command == "timesheet") { out = handleReportTimesheet (tdb, task, conf); }
|
||||
else if (command == "colors") { out = handleColor ( conf); }
|
||||
else if (command == "version") { out = handleVersion ( conf); }
|
||||
else if (command == "help") { out = longUsage ( conf); }
|
||||
if (command == "export") { out = handleExport (tdb, task); }
|
||||
else if (command == "projects") { out = handleProjects (tdb, task); }
|
||||
else if (command == "tags") { out = handleTags (tdb, task); }
|
||||
else if (command == "info") { out = handleInfo (tdb, task); }
|
||||
else if (command == "stats") { out = handleReportStats (tdb, task); }
|
||||
else if (command == "history") { out = handleReportHistory (tdb, task); }
|
||||
else if (command == "ghistory") { out = handleReportGHistory (tdb, task); }
|
||||
else if (command == "calendar") { out = handleReportCalendar (tdb, task); }
|
||||
else if (command == "summary") { out = handleReportSummary (tdb, task); }
|
||||
else if (command == "timesheet") { out = handleReportTimesheet (tdb, task); }
|
||||
else if (command == "colors") { out = handleColor ( ); }
|
||||
else if (command == "version") { out = handleVersion ( ); }
|
||||
else if (command == "help") { out = longUsage ( ); }
|
||||
|
||||
// Commands that cause updates.
|
||||
else if (command == "" && task.getId ()) { cmdMod = true; out = handleModify (tdb, task, conf); }
|
||||
else if (command == "add") { cmdMod = true; out = handleAdd (tdb, task, conf); }
|
||||
else if (command == "append") { cmdMod = true; out = handleAppend (tdb, task, conf); }
|
||||
else if (command == "annotate") { cmdMod = true; out = handleAnnotate (tdb, task, conf); }
|
||||
else if (command == "done") { cmdMod = true; out = handleDone (tdb, task, conf); }
|
||||
else if (command == "undelete") { cmdMod = true; out = handleUndelete (tdb, task, conf); }
|
||||
else if (command == "delete") { cmdMod = true; out = handleDelete (tdb, task, conf); }
|
||||
else if (command == "start") { cmdMod = true; out = handleStart (tdb, task, conf); }
|
||||
else if (command == "stop") { cmdMod = true; out = handleStop (tdb, task, conf); }
|
||||
else if (command == "undo") { cmdMod = true; out = handleUndo (tdb, task, conf); }
|
||||
else if (command == "import") { cmdMod = true; out = handleImport (tdb, task, conf); }
|
||||
else if (command == "duplicate") { cmdMod = true; out = handleDuplicate (tdb, task, conf); }
|
||||
else if (command == "edit") { cmdMod = true; out = handleEdit (tdb, task, conf); }
|
||||
else if (command == "" && task.getId ()) { cmdMod = true; out = handleModify (tdb, task); }
|
||||
else if (command == "add") { cmdMod = true; out = handleAdd (tdb, task); }
|
||||
else if (command == "append") { cmdMod = true; out = handleAppend (tdb, task); }
|
||||
else if (command == "annotate") { cmdMod = true; out = handleAnnotate (tdb, task); }
|
||||
else if (command == "done") { cmdMod = true; out = handleDone (tdb, task); }
|
||||
else if (command == "undelete") { cmdMod = true; out = handleUndelete (tdb, task); }
|
||||
else if (command == "delete") { cmdMod = true; out = handleDelete (tdb, task); }
|
||||
else if (command == "start") { cmdMod = true; out = handleStart (tdb, task); }
|
||||
else if (command == "stop") { cmdMod = true; out = handleStop (tdb, task); }
|
||||
else if (command == "undo") { cmdMod = true; out = handleUndo (tdb, task); }
|
||||
else if (command == "import") { cmdMod = true; out = handleImport (tdb, task); }
|
||||
else if (command == "duplicate") { cmdMod = true; out = handleDuplicate (tdb, task); }
|
||||
else if (command == "edit") { cmdMod = true; out = handleEdit (tdb, task); }
|
||||
|
||||
// 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 == "next") { if (gc) gcMod = tdb.gc (); out = handleReportNext (tdb, task, conf); }
|
||||
else if (command == "active") { if (gc) gcMod = tdb.gc (); out = handleReportActive (tdb, task, conf); }
|
||||
else if (command == "overdue") { if (gc) gcMod = tdb.gc (); out = handleReportOverdue (tdb, task, conf); }
|
||||
else if (isCustomReport (command)) { if (gc) gcMod = tdb.gc (); out = handleCustomReport (tdb, task, conf, command); }
|
||||
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); }
|
||||
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); }
|
||||
else if (isCustomReport (command)) { if (gc) gcMod = tdb.gc (); out = handleCustomReport (tdb, task, command); }
|
||||
|
||||
// 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),
|
||||
// and if an actual change occurred (gcMod || cmdMod).
|
||||
if (shadow && (gcMod || cmdMod))
|
||||
updateShadowFile (tdb, conf);
|
||||
updateShadowFile (tdb);
|
||||
|
||||
return out;
|
||||
}
|
||||
|
|
79
src/task.h
79
src/task.h
|
@ -32,50 +32,49 @@
|
|||
#include "Context.h"
|
||||
#include "T.h"
|
||||
#include "TDB.h"
|
||||
#include "Config.h"
|
||||
#include "Table.h"
|
||||
#include "Date.h"
|
||||
#include "color.h"
|
||||
#include "../auto.h"
|
||||
|
||||
// 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 validDate (std::string&, Config&);
|
||||
bool validDate (std::string&);
|
||||
bool validDuration (std::string&);
|
||||
void loadCustomReports (Config&);
|
||||
void loadCustomReports ();
|
||||
bool isCustomReport (const std::string&);
|
||||
void allCustomReports (std::vector <std::string>&);
|
||||
|
||||
// task.cpp
|
||||
void gatherNextTasks (const TDB&, T&, Config&, std::vector <T>&, std::vector <int>&);
|
||||
void nag (TDB&, T&, Config&);
|
||||
void gatherNextTasks (const TDB&, T&, std::vector <T>&, std::vector <int>&);
|
||||
void nag (TDB&, T&);
|
||||
int getDueState (const std::string&);
|
||||
void handleRecurrence (TDB&, std::vector <T>&);
|
||||
bool generateDueDates (T&, std::vector <Date>&);
|
||||
Date getNextRecurrence (Date&, std::string&);
|
||||
void updateRecurrenceMask (TDB&, std::vector <T>&, T&);
|
||||
void onChangeCallback ();
|
||||
std::string runTaskCommand (int, char**, TDB&, Config&, bool gc = true, bool shadow = true);
|
||||
std::string runTaskCommand (std::vector <std::string>&, TDB&, Config&, bool gc = false, bool shadow = false);
|
||||
std::string runTaskCommand (int, char**, TDB&, bool gc = true, bool shadow = true);
|
||||
std::string runTaskCommand (std::vector <std::string>&, TDB&, bool gc = false, bool shadow = false);
|
||||
|
||||
// command.cpp
|
||||
std::string handleAdd (TDB&, T&, Config&);
|
||||
std::string handleAppend (TDB&, T&, Config&);
|
||||
std::string handleExport (TDB&, T&, Config&);
|
||||
std::string handleDone (TDB&, T&, Config&);
|
||||
std::string handleModify (TDB&, T&, Config&);
|
||||
std::string handleProjects (TDB&, T&, Config&);
|
||||
std::string handleTags (TDB&, T&, Config&);
|
||||
std::string handleUndelete (TDB&, T&, Config&);
|
||||
std::string handleVersion (Config&);
|
||||
std::string handleDelete (TDB&, T&, Config&);
|
||||
std::string handleStart (TDB&, T&, Config&);
|
||||
std::string handleStop (TDB&, T&, Config&);
|
||||
std::string handleUndo (TDB&, T&, Config&);
|
||||
std::string handleColor (Config&);
|
||||
std::string handleAnnotate (TDB&, T&, Config&);
|
||||
std::string handleDuplicate (TDB&, T&, Config&);
|
||||
std::string handleAdd (TDB&, T&);
|
||||
std::string handleAppend (TDB&, T&);
|
||||
std::string handleExport (TDB&, T&);
|
||||
std::string handleDone (TDB&, T&);
|
||||
std::string handleModify (TDB&, T&);
|
||||
std::string handleProjects (TDB&, T&);
|
||||
std::string handleTags (TDB&, T&);
|
||||
std::string handleUndelete (TDB&, T&);
|
||||
std::string handleVersion ();
|
||||
std::string handleDelete (TDB&, T&);
|
||||
std::string handleStart (TDB&, T&);
|
||||
std::string handleStop (TDB&, T&);
|
||||
std::string handleUndo (TDB&, T&);
|
||||
std::string handleColor ();
|
||||
std::string handleAnnotate (TDB&, T&);
|
||||
std::string handleDuplicate (TDB&, T&);
|
||||
T findT (int, const std::vector <T>&);
|
||||
int deltaAppend (T&, T&);
|
||||
int deltaDescription (T&, T&);
|
||||
|
@ -84,33 +83,33 @@ int deltaAttributes (T&, T&);
|
|||
int deltaSubstitutions (T&, T&);
|
||||
|
||||
// edit.cpp
|
||||
std::string handleEdit (TDB&, T&, Config&);
|
||||
std::string handleEdit (TDB&, T&);
|
||||
|
||||
// report.cpp
|
||||
void filterSequence (std::vector<T>&, T&);
|
||||
void filter (std::vector<T>&, T&);
|
||||
std::string handleInfo (TDB&, T&, Config&);
|
||||
std::string handleCompleted (TDB&, T&, Config&);
|
||||
std::string handleReportSummary (TDB&, T&, Config&);
|
||||
std::string handleReportNext (TDB&, T&, Config&);
|
||||
std::string handleReportHistory (TDB&, T&, Config&);
|
||||
std::string handleReportGHistory (TDB&, T&, Config&);
|
||||
std::string handleReportCalendar (TDB&, T&, Config&);
|
||||
std::string handleReportActive (TDB&, T&, Config&);
|
||||
std::string handleReportOverdue (TDB&, T&, Config&);
|
||||
std::string handleReportStats (TDB&, T&, Config&);
|
||||
std::string handleReportTimesheet (TDB&, T&, Config&);
|
||||
std::string handleInfo (TDB&, T&);
|
||||
std::string handleCompleted (TDB&, T&);
|
||||
std::string handleReportSummary (TDB&, T&);
|
||||
std::string handleReportNext (TDB&, T&);
|
||||
std::string handleReportHistory (TDB&, T&);
|
||||
std::string handleReportGHistory (TDB&, T&);
|
||||
std::string handleReportCalendar (TDB&, T&);
|
||||
std::string handleReportActive (TDB&, T&);
|
||||
std::string handleReportOverdue (TDB&, T&);
|
||||
std::string handleReportStats (TDB&, T&);
|
||||
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 validSortColumns (const std::vector <std::string>&, const std::vector <std::string>&);
|
||||
|
||||
// rules.cpp
|
||||
void initializeColorRules (Config&);
|
||||
void autoColorize (T&, Text::color&, Text::color&, Config&);
|
||||
void initializeColorRules ();
|
||||
void autoColorize (T&, Text::color&, Text::color&);
|
||||
|
||||
// import.cpp
|
||||
std::string handleImport (TDB&, T&, Config&);
|
||||
std::string handleImport (TDB&, T&);
|
||||
|
||||
// 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 \
|
||||
../Duration.o ../util.o ../Config.o ../Sequence.o ../Att.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)
|
||||
|
||||
|
|
|
@ -24,9 +24,12 @@
|
|||
// USA
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
#include <Context.h>
|
||||
#include <Att.h>
|
||||
#include <test.h>
|
||||
|
||||
Context context;
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
int main (int argc, char** argv)
|
||||
{
|
||||
|
|
|
@ -29,6 +29,8 @@
|
|||
#include <util.h>
|
||||
#include <task.h>
|
||||
|
||||
Context context;
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
int main (int argc, char** argv)
|
||||
{
|
||||
|
|
|
@ -25,9 +25,12 @@
|
|||
//
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
#include <iostream>
|
||||
#include <Context.h>
|
||||
#include <Date.h>
|
||||
#include <test.h>
|
||||
|
||||
Context context;
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
int main (int argc, char** argv)
|
||||
{
|
||||
|
|
|
@ -25,9 +25,12 @@
|
|||
//
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
#include <iostream>
|
||||
#include <Context.h>
|
||||
#include <Duration.h>
|
||||
#include <test.h>
|
||||
|
||||
Context context;
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
// daily, day, Nd
|
||||
// weekly, 1w, sennight, biweekly, fortnight
|
||||
|
|
|
@ -24,9 +24,12 @@
|
|||
// USA
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
#include <Context.h>
|
||||
#include <Mod.h>
|
||||
#include <test.h>
|
||||
|
||||
Context context;
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
int main (int argc, char** argv)
|
||||
{
|
||||
|
|
|
@ -24,9 +24,12 @@
|
|||
// USA
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
#include <Context.h>
|
||||
#include <Nibbler.h>
|
||||
#include <test.h>
|
||||
|
||||
Context context;
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
int main (int argc, char** argv)
|
||||
{
|
||||
|
|
|
@ -29,6 +29,8 @@
|
|||
#include "text.h"
|
||||
#include "test.h"
|
||||
|
||||
Context context;
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
int main (int argc, char** argv)
|
||||
{
|
||||
|
@ -37,13 +39,12 @@ int main (int argc, char** argv)
|
|||
std::vector <std::string> args;
|
||||
std::string command;
|
||||
|
||||
Config conf;
|
||||
conf.set ("dateformat", "m/d/Y");
|
||||
context.config.set ("dateformat", "m/d/Y");
|
||||
|
||||
{
|
||||
T task;
|
||||
split (args, "add foo", ' ');
|
||||
parse (args, command, task, conf);
|
||||
parse (args, command, task);
|
||||
t.is (command, "add", "(1) command found");
|
||||
t.is (task.getId (), 0, "(1) zero id on add");
|
||||
t.is (task.getDescription (), "foo", "(1) correct description");
|
||||
|
@ -52,7 +53,7 @@ int main (int argc, char** argv)
|
|||
{
|
||||
T task;
|
||||
split (args, "delete 1,3-5,7", ' ');
|
||||
parse (args, command, task, conf);
|
||||
parse (args, command, task);
|
||||
std::vector <int> sequence = task.getAllIds ();
|
||||
t.is (sequence.size (), (size_t)5, "(2) sequence length");
|
||||
if (sequence.size () == 5)
|
||||
|
@ -76,7 +77,7 @@ int main (int argc, char** argv)
|
|||
{
|
||||
T task;
|
||||
split (args, "delete 1,2 3,4", ' ');
|
||||
parse (args, command, task, conf);
|
||||
parse (args, command, task);
|
||||
std::vector <int> sequence = task.getAllIds ();
|
||||
t.is (sequence.size (), (size_t)4, "(3) sequence length");
|
||||
if (sequence.size () == 4)
|
||||
|
@ -98,7 +99,7 @@ int main (int argc, char** argv)
|
|||
{
|
||||
T task;
|
||||
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 ();
|
||||
t.is (sequence.size (), (size_t)1, "(4) sequence length");
|
||||
if (sequence.size () == 1)
|
||||
|
@ -116,7 +117,7 @@ int main (int argc, char** argv)
|
|||
args.clear ();
|
||||
args.push_back ("1");
|
||||
args.push_back ("4-123 is back-ordered");
|
||||
parse (args, command, task, conf);
|
||||
parse (args, command, task);
|
||||
std::vector <int> sequence = task.getAllIds ();
|
||||
t.is (sequence.size (), (size_t)1, "(5) sequence length");
|
||||
if (sequence.size () == 1)
|
||||
|
|
|
@ -25,10 +25,13 @@
|
|||
//
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
#include <iostream>
|
||||
#include <Context.h>
|
||||
#include <Att.h>
|
||||
#include <Record.h>
|
||||
#include <test.h>
|
||||
|
||||
Context context;
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
int main (int argc, char** argv)
|
||||
{
|
||||
|
|
|
@ -25,9 +25,12 @@
|
|||
//
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
#include <iostream>
|
||||
#include <Context.h>
|
||||
#include <Sequence.h>
|
||||
#include <test.h>
|
||||
|
||||
Context context;
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
Sequence parseSequence (const std::string& input)
|
||||
{
|
||||
|
|
|
@ -25,10 +25,13 @@
|
|||
//
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
#include <unistd.h>
|
||||
#include <Context.h>
|
||||
#include <StringTable.h>
|
||||
#include <util.h>
|
||||
#include <test.h>
|
||||
|
||||
Context context;
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
int main (int argc, char** argv)
|
||||
{
|
||||
|
|
|
@ -24,10 +24,13 @@
|
|||
// USA
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
#include <Context.h>
|
||||
#include <T2.h>
|
||||
#include <Subst.h>
|
||||
#include <test.h>
|
||||
|
||||
Context context;
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
int main (int argc, char** argv)
|
||||
{
|
||||
|
|
|
@ -29,6 +29,8 @@
|
|||
#include "task.h"
|
||||
#include "test.h"
|
||||
|
||||
Context context;
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
int main (int argc, char** argv)
|
||||
{
|
||||
|
|
|
@ -29,6 +29,8 @@
|
|||
#include "task.h"
|
||||
#include "test.h"
|
||||
|
||||
Context context;
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
int main (int argc, char** argv)
|
||||
{
|
||||
|
|
|
@ -31,6 +31,8 @@
|
|||
#include "task.h"
|
||||
#include "test.h"
|
||||
|
||||
Context context;
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
int main (int argc, char** argv)
|
||||
{
|
||||
|
|
|
@ -29,6 +29,8 @@
|
|||
#include "text.h"
|
||||
#include "test.h"
|
||||
|
||||
Context context;
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
int main (int argc, char** argv)
|
||||
{
|
||||
|
|
|
@ -27,10 +27,12 @@
|
|||
#include <iostream>
|
||||
#include <vector>
|
||||
#include <string>
|
||||
#include "Config.h"
|
||||
#include "Context.h"
|
||||
#include "util.h"
|
||||
#include "text.h"
|
||||
|
||||
extern Context context;
|
||||
|
||||
static const char* newline = "\n";
|
||||
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 noline;
|
||||
|
|
|
@ -29,7 +29,6 @@
|
|||
|
||||
#include <string>
|
||||
#include <vector>
|
||||
#include "Config.h"
|
||||
#include "../auto.h"
|
||||
|
||||
// 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 lowerCase (const std::string&);
|
||||
std::string upperCase (const std::string&);
|
||||
const char* optionalBlankLine (Config&);
|
||||
const char* optionalBlankLine ();
|
||||
|
||||
#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
|
||||
|
Loading…
Add table
Add a link
Reference in a new issue