mirror of
https://github.com/GothenburgBitFactory/taskwarrior.git
synced 2025-08-22 11:13:09 +02:00
- Added all source code.
This commit is contained in:
parent
7f8fc1182d
commit
b5be083d88
27 changed files with 7842 additions and 0 deletions
191
src/Config.cpp
Normal file
191
src/Config.cpp
Normal file
|
@ -0,0 +1,191 @@
|
|||
///////////////////////////////////////////////////////////////////////////////
|
||||
// Copyright 2005 - 2008, Paul Beckingham. All rights reserved.
|
||||
//
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
#include <iostream>
|
||||
#include <fstream>
|
||||
#include <sstream>
|
||||
#include "task.h"
|
||||
#include "Config.h"
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
Config::Config ()
|
||||
{
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
Config::Config (const std::string& file)
|
||||
{
|
||||
load (file);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
// Read the Configuration filee and populate the *this map. The file format
|
||||
// is simply lines with name=value pairs. Whitespace between name, = and value
|
||||
// is not tolerated, but blank lines and comments starting with # are allowed.
|
||||
bool Config::load (const std::string& file)
|
||||
{
|
||||
std::ifstream in;
|
||||
in.open (file.c_str (), std::ifstream::in);
|
||||
if (in.good ())
|
||||
{
|
||||
std::string line;
|
||||
while (getline (in, line))
|
||||
{
|
||||
// Remove comments.
|
||||
unsigned int pound = line.find ("#");
|
||||
if (pound != std::string::npos)
|
||||
line = line.substr (0, pound);
|
||||
|
||||
line = trim (line, " \t");
|
||||
|
||||
// Skip empty lines.
|
||||
if (line.length () > 0)
|
||||
{
|
||||
unsigned int equal = line.find ("=");
|
||||
if (equal != std::string::npos)
|
||||
{
|
||||
std::string key = trim (line.substr (0, equal), " \t");
|
||||
std::string value = trim (line.substr (equal+1, line.length () - equal), " \t");
|
||||
(*this)[key] = value;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
in.close ();
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
// Return the configuration value given the specified key.
|
||||
const std::string& Config::get (const char* key)
|
||||
{
|
||||
return this->get (std::string (key));
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
// Return the configuration value given the specified key. If a default_value
|
||||
// is present, it will be the returned value in the event of a missing key.
|
||||
const std::string& Config::get (
|
||||
const char* key,
|
||||
const char* default_value)
|
||||
{
|
||||
return this->get (std::string (key), std::string (default_value));
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
// Return the configuration value given the specified key.
|
||||
const std::string& Config::get (const std::string& key)
|
||||
{
|
||||
return (*this)[key];
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
// Return the configuration value given the specified key. If a default_value
|
||||
// is present, it will be the returned value in the event of a missing key.
|
||||
const std::string& Config::get (
|
||||
const std::string& key,
|
||||
const std::string& default_value)
|
||||
{
|
||||
if ((*this).find (key) != (*this).end ())
|
||||
return (*this)[key];
|
||||
|
||||
return default_value;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
bool Config::get (const std::string& key, bool default_value)
|
||||
{
|
||||
if ((*this).find (key) != (*this).end ())
|
||||
{
|
||||
std::string value = lowerCase ((*this)[key]);
|
||||
|
||||
if (value == "t" ||
|
||||
value == "true" ||
|
||||
value == "1" ||
|
||||
value == "yes" ||
|
||||
value == "on")
|
||||
return true;
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
return default_value;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
int Config::get (const std::string& key, const int default_value)
|
||||
{
|
||||
if ((*this).find (key) != (*this).end ())
|
||||
return ::atoi ((*this)[key].c_str ());
|
||||
|
||||
return default_value;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
double Config::get (const std::string& key, const double default_value)
|
||||
{
|
||||
if ((*this).find (key) != (*this).end ())
|
||||
return ::atof ((*this)[key].c_str ());
|
||||
|
||||
return default_value;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
void Config::set (const std::string& key, const int value)
|
||||
{
|
||||
char v[24];
|
||||
sprintf (v, "%d", value);
|
||||
(*this)[key] = v;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
void Config::set (const std::string& key, const double value)
|
||||
{
|
||||
char v[32];
|
||||
sprintf (v, "%f", value);
|
||||
(*this)[key] = v;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
void Config::set (const std::string& key, const std::string& value)
|
||||
{
|
||||
(*this)[key] = value;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
// The vector form of Config::get assumes the single value is comma-separated,
|
||||
// and splits accordingly.
|
||||
void Config::get (
|
||||
const std::string& key,
|
||||
std::vector <std::string>& values)
|
||||
{
|
||||
values.clear ();
|
||||
split (values, (*this)[key], ',');
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
// The vector form of Config::set joins the values together with commas, and
|
||||
// stores the single value.
|
||||
void Config::set (
|
||||
const std::string& key,
|
||||
const std::vector <std::string>& values)
|
||||
{
|
||||
std::string conjoined;
|
||||
join (conjoined, ",", values);
|
||||
(*this)[key] = conjoined;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
// Provide a vector of all configuration keys.
|
||||
void Config::all (std::vector<std::string>& items)
|
||||
{
|
||||
foreach (i, *this)
|
||||
items.push_back (i->first);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
37
src/Config.h
Normal file
37
src/Config.h
Normal file
|
@ -0,0 +1,37 @@
|
|||
////////////////////////////////////////////////////////////////////////////////
|
||||
// Copyright 2005 - 2008, Paul Beckingham. All rights reserved.
|
||||
//
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
#ifndef INCLUDED_CONFIG
|
||||
#define INCLUDED_CONFIG
|
||||
|
||||
#include <map>
|
||||
#include <vector>
|
||||
#include <string>
|
||||
|
||||
class Config : public std::map <std::string, std::string>
|
||||
{
|
||||
public:
|
||||
Config ();
|
||||
Config (const std::string&);
|
||||
|
||||
bool load (const std::string&);
|
||||
const std::string& get (const char*);
|
||||
const std::string& get (const char*, const char*);
|
||||
const std::string& get (const std::string&);
|
||||
const std::string& get (const std::string&, const std::string&);
|
||||
bool get (const std::string&, bool);
|
||||
int get (const std::string&, const int);
|
||||
double get (const std::string&, const double);
|
||||
void get (const std::string&, std::vector <std::string>&);
|
||||
void set (const std::string&, const int);
|
||||
void set (const std::string&, const double);
|
||||
void set (const std::string&, const std::string&);
|
||||
void set (const std::string&, const std::vector <std::string>&);
|
||||
void all (std::vector <std::string>&);
|
||||
};
|
||||
|
||||
#endif
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
303
src/Date.cpp
Normal file
303
src/Date.cpp
Normal file
|
@ -0,0 +1,303 @@
|
|||
////////////////////////////////////////////////////////////////////////////////
|
||||
// Copyright 2005 - 2008, Paul Beckingham. All rights reserved.
|
||||
//
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
#include <iostream>
|
||||
#include <time.h>
|
||||
#include "task.h"
|
||||
#include "Date.h"
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
// Defaults to "now".
|
||||
Date::Date ()
|
||||
{
|
||||
mT = time (NULL);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
Date::Date (const time_t t)
|
||||
{
|
||||
mT = t;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
Date::Date (const int m, const int d, const int y)
|
||||
{
|
||||
// Error if not valid.
|
||||
struct tm t = {0};
|
||||
t.tm_mday = d;
|
||||
t.tm_mon = m - 1;
|
||||
t.tm_year = y - 1900;
|
||||
|
||||
mT = mktime (&t);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
Date::Date (const std::string& mdy)
|
||||
{
|
||||
unsigned int firstSlash = mdy.find ("/");
|
||||
unsigned int secondSlash = mdy.find ("/", firstSlash + 1);
|
||||
if (firstSlash != std::string::npos &&
|
||||
secondSlash != std::string::npos)
|
||||
{
|
||||
int m = ::atoi (mdy.substr (0, firstSlash ).c_str ());
|
||||
int d = ::atoi (mdy.substr (firstSlash + 1, secondSlash - firstSlash).c_str ());
|
||||
int y = ::atoi (mdy.substr (secondSlash + 1, std::string::npos ).c_str ());
|
||||
if (!valid (m, d, y))
|
||||
throw std::string ("\"") + mdy + "\" is not a valid date.";
|
||||
|
||||
// Duplicate Date::Date (const int, const int, const int);
|
||||
struct tm t = {0};
|
||||
t.tm_mday = d;
|
||||
t.tm_mon = m - 1;
|
||||
t.tm_year = y - 1900;
|
||||
|
||||
mT = mktime (&t);
|
||||
}
|
||||
else
|
||||
throw std::string ("\"") + mdy + "\" is not a valid date.";
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
Date::Date (const Date& rhs)
|
||||
{
|
||||
mT = rhs.mT;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
Date::~Date ()
|
||||
{
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
time_t Date::toEpoch ()
|
||||
{
|
||||
return mT;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
void Date::toEpoch (time_t& epoch)
|
||||
{
|
||||
epoch = mT;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
void Date::toMDY (int& m, int& d, int& y)
|
||||
{
|
||||
struct tm* t = localtime (&mT);
|
||||
|
||||
m = t->tm_mon + 1;
|
||||
d = t->tm_mday;
|
||||
y = t->tm_year + 1900;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
void Date::toString (std::string& output)
|
||||
{
|
||||
output = toString ();
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
std::string Date::toString (void)
|
||||
{
|
||||
int m, d, y;
|
||||
toMDY (m, d, y);
|
||||
|
||||
char formatted [11];
|
||||
sprintf (formatted, "%d/%d/%d", m, d, y);
|
||||
return std::string (formatted);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
bool Date::valid (const int m, const int d, const int y)
|
||||
{
|
||||
// Check that the year is valid.
|
||||
if (y < 0)
|
||||
return false;
|
||||
|
||||
// Check that the month is valid.
|
||||
if (m < 1 || m > 12)
|
||||
return false;
|
||||
|
||||
// Finally check that the days fall within the acceptable range for this
|
||||
// month, and whether or not this is a leap year.
|
||||
if (d < 1 || d > Date::daysInMonth (m, y))
|
||||
return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
bool Date::leapYear (int year)
|
||||
{
|
||||
bool ly = false;
|
||||
|
||||
if (!(year % 4)) ly = true;
|
||||
else if (!(year % 400)) ly = true;
|
||||
else if (!(year % 100)) ly = false;
|
||||
|
||||
return ly;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
int Date::daysInMonth (int month, int year)
|
||||
{
|
||||
static int days[2][12] =
|
||||
{
|
||||
{31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31},
|
||||
{31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31}
|
||||
};
|
||||
|
||||
return days[Date::leapYear (year) ? 1 : 0][month - 1];
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
std::string Date::monthName (int month)
|
||||
{
|
||||
static char* months[12] =
|
||||
{
|
||||
"January",
|
||||
"February",
|
||||
"March",
|
||||
"April",
|
||||
"May",
|
||||
"June",
|
||||
"July",
|
||||
"August",
|
||||
"September",
|
||||
"October",
|
||||
"November",
|
||||
"December",
|
||||
};
|
||||
|
||||
assert (month > 0);
|
||||
assert (month <= 12);
|
||||
return months[month -1];
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
void Date::dayName (int dow, std::string& name)
|
||||
{
|
||||
static char* days[7] =
|
||||
{
|
||||
"Sunday",
|
||||
"Monday",
|
||||
"Tuesday",
|
||||
"Wednesday",
|
||||
"Thursday",
|
||||
"Friday",
|
||||
"Saturday",
|
||||
};
|
||||
|
||||
name = days[dow];
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
std::string Date::dayName (int dow)
|
||||
{
|
||||
static char* days[7] =
|
||||
{
|
||||
"Sunday",
|
||||
"Monday",
|
||||
"Tuesday",
|
||||
"Wednesday",
|
||||
"Thursday",
|
||||
"Friday",
|
||||
"Saturday",
|
||||
};
|
||||
|
||||
return days[dow];
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
int Date::dayOfWeek ()
|
||||
{
|
||||
struct tm* t = localtime (&mT);
|
||||
return t->tm_wday;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
int Date::month ()
|
||||
{
|
||||
struct tm* t = localtime (&mT);
|
||||
return t->tm_mon + 1;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
int Date::day ()
|
||||
{
|
||||
struct tm* t = localtime (&mT);
|
||||
return t->tm_mday;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
int Date::year ()
|
||||
{
|
||||
struct tm* t = localtime (&mT);
|
||||
return t->tm_year + 1900;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
bool Date::operator== (const Date& rhs)
|
||||
{
|
||||
return rhs.mT == mT;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
bool Date::operator!= (const Date& rhs)
|
||||
{
|
||||
return rhs.mT != mT;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
bool Date::operator< (const Date& rhs)
|
||||
{
|
||||
return mT < rhs.mT;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
bool Date::operator> (const Date& rhs)
|
||||
{
|
||||
return mT > rhs.mT;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
bool Date::operator<= (const Date& rhs)
|
||||
{
|
||||
return mT <= rhs.mT;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
bool Date::operator>= (const Date& rhs)
|
||||
{
|
||||
return mT >= rhs.mT;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
Date Date::operator+ (const int delta)
|
||||
{
|
||||
return Date::Date (mT + delta);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
Date& Date::operator+= (const int delta)
|
||||
{
|
||||
mT += (time_t) delta;
|
||||
return *this;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
Date& Date::operator-= (const int delta)
|
||||
{
|
||||
mT -= (time_t) delta;
|
||||
return *this;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
time_t Date::operator- (const Date& rhs)
|
||||
{
|
||||
return mT - rhs.mT;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
60
src/Date.h
Normal file
60
src/Date.h
Normal file
|
@ -0,0 +1,60 @@
|
|||
////////////////////////////////////////////////////////////////////////////////
|
||||
// Copyright 2005 - 2008, Paul Beckingham. All rights reserved.
|
||||
//
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
#ifndef INCLUDED_DATE
|
||||
#define INCLUDED_DATE
|
||||
|
||||
#include <string>
|
||||
|
||||
class Date;
|
||||
|
||||
class Date
|
||||
{
|
||||
public:
|
||||
Date ();
|
||||
Date (time_t);
|
||||
Date (const int, const int, const int);
|
||||
Date (const std::string&);
|
||||
Date (const Date&);
|
||||
virtual ~Date ();
|
||||
|
||||
void toEpoch (time_t&);
|
||||
time_t toEpoch ();
|
||||
void toMDY (int&, int&, int&);
|
||||
void toString (std::string&);
|
||||
std::string toString (void);
|
||||
static bool valid (const int, const int, const int);
|
||||
|
||||
static bool leapYear (int);
|
||||
static int daysInMonth (int, int);
|
||||
static std::string monthName (int);
|
||||
static void dayName (int, std::string&);
|
||||
static std::string dayName (int);
|
||||
int dayOfWeek ();
|
||||
|
||||
int month ();
|
||||
int day ();
|
||||
int year ();
|
||||
|
||||
bool operator== (const Date&);
|
||||
bool operator!= (const Date&);
|
||||
bool operator< (const Date&);
|
||||
bool operator> (const Date&);
|
||||
bool operator<= (const Date&);
|
||||
bool operator>= (const Date&);
|
||||
|
||||
Date operator+ (const int);
|
||||
Date& operator+= (const int);
|
||||
Date& operator-= (const int);
|
||||
|
||||
time_t operator- (const Date&);
|
||||
|
||||
protected:
|
||||
time_t mT;
|
||||
};
|
||||
|
||||
#endif
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
429
src/Makefile
Normal file
429
src/Makefile
Normal file
|
@ -0,0 +1,429 @@
|
|||
# Makefile.in generated by automake 1.10 from Makefile.am.
|
||||
# src/Makefile. Generated from Makefile.in by configure.
|
||||
|
||||
# Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002,
|
||||
# 2003, 2004, 2005, 2006 Free Software Foundation, Inc.
|
||||
# This Makefile.in is free software; the Free Software Foundation
|
||||
# gives unlimited permission to copy and/or distribute it,
|
||||
# with or without modifications, as long as this notice is preserved.
|
||||
|
||||
# This program is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY, to the extent permitted by law; without
|
||||
# even the implied warranty of MERCHANTABILITY or FITNESS FOR A
|
||||
# PARTICULAR PURPOSE.
|
||||
|
||||
|
||||
|
||||
|
||||
pkgdatadir = $(datadir)/task
|
||||
pkglibdir = $(libdir)/task
|
||||
pkgincludedir = $(includedir)/task
|
||||
am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd
|
||||
install_sh_DATA = $(install_sh) -c -m 644
|
||||
install_sh_PROGRAM = $(install_sh) -c
|
||||
install_sh_SCRIPT = $(install_sh) -c
|
||||
INSTALL_HEADER = $(INSTALL_DATA)
|
||||
transform = $(program_transform_name)
|
||||
NORMAL_INSTALL = :
|
||||
PRE_INSTALL = :
|
||||
POST_INSTALL = :
|
||||
NORMAL_UNINSTALL = :
|
||||
PRE_UNINSTALL = :
|
||||
POST_UNINSTALL = :
|
||||
bin_PROGRAMS = task$(EXEEXT)
|
||||
subdir = src
|
||||
DIST_COMMON = $(srcdir)/Makefile.am $(srcdir)/Makefile.in
|
||||
ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
|
||||
am__aclocal_m4_deps = $(top_srcdir)/configure.ac
|
||||
am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \
|
||||
$(ACLOCAL_M4)
|
||||
mkinstalldirs = $(install_sh) -d
|
||||
CONFIG_HEADER = $(top_builddir)/auto.h
|
||||
CONFIG_CLEAN_FILES =
|
||||
am__installdirs = "$(DESTDIR)$(bindir)"
|
||||
binPROGRAMS_INSTALL = $(INSTALL_PROGRAM)
|
||||
PROGRAMS = $(bin_PROGRAMS)
|
||||
am_task_OBJECTS = Config.$(OBJEXT) Date.$(OBJEXT) T.$(OBJEXT) \
|
||||
TDB.$(OBJEXT) Table.$(OBJEXT) color.$(OBJEXT) parse.$(OBJEXT) \
|
||||
task.$(OBJEXT) util.$(OBJEXT) text.$(OBJEXT) rules.$(OBJEXT)
|
||||
task_OBJECTS = $(am_task_OBJECTS)
|
||||
task_LDADD = $(LDADD)
|
||||
DEFAULT_INCLUDES = -I. -I$(top_builddir)
|
||||
depcomp = $(SHELL) $(top_srcdir)/depcomp
|
||||
am__depfiles_maybe = depfiles
|
||||
CXXCOMPILE = $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) \
|
||||
$(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS)
|
||||
CXXLD = $(CXX)
|
||||
CXXLINK = $(CXXLD) $(AM_CXXFLAGS) $(CXXFLAGS) $(AM_LDFLAGS) $(LDFLAGS) \
|
||||
-o $@
|
||||
COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \
|
||||
$(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS)
|
||||
CCLD = $(CC)
|
||||
LINK = $(CCLD) $(AM_CFLAGS) $(CFLAGS) $(AM_LDFLAGS) $(LDFLAGS) -o $@
|
||||
SOURCES = $(task_SOURCES)
|
||||
DIST_SOURCES = $(task_SOURCES)
|
||||
ETAGS = etags
|
||||
CTAGS = ctags
|
||||
DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST)
|
||||
ACLOCAL = ${SHELL} /Users/paul/work/task_rel/missing --run aclocal-1.10
|
||||
AMTAR = ${SHELL} /Users/paul/work/task_rel/missing --run tar
|
||||
AUTOCONF = ${SHELL} /Users/paul/work/task_rel/missing --run autoconf
|
||||
AUTOHEADER = ${SHELL} /Users/paul/work/task_rel/missing --run autoheader
|
||||
AUTOMAKE = ${SHELL} /Users/paul/work/task_rel/missing --run automake-1.10
|
||||
AWK = awk
|
||||
CC = gcc
|
||||
CCDEPMODE = depmode=gcc3
|
||||
CFLAGS = -g -O2
|
||||
CPPFLAGS =
|
||||
CXX = g++
|
||||
CXXCPP = g++ -E
|
||||
CXXDEPMODE = depmode=gcc3
|
||||
CXXFLAGS = -g -O2
|
||||
CYGPATH_W = echo
|
||||
DEFS = -DHAVE_CONFIG_H
|
||||
DEPDIR = .deps
|
||||
ECHO_C = \c
|
||||
ECHO_N =
|
||||
ECHO_T =
|
||||
EGREP = /usr/bin/grep -E
|
||||
EXEEXT =
|
||||
GREP = /usr/bin/grep
|
||||
INSTALL = /usr/bin/install -c
|
||||
INSTALL_DATA = ${INSTALL} -m 644
|
||||
INSTALL_PROGRAM = ${INSTALL}
|
||||
INSTALL_SCRIPT = ${INSTALL}
|
||||
INSTALL_STRIP_PROGRAM = $(install_sh) -c -s
|
||||
LDFLAGS =
|
||||
LIBOBJS = ${LIBOBJDIR}mktime$U.o
|
||||
LIBS = -lncurses
|
||||
LTLIBOBJS = ${LIBOBJDIR}mktime$U.lo
|
||||
MAKEINFO = ${SHELL} /Users/paul/work/task_rel/missing --run makeinfo
|
||||
MKDIR_P = .././install-sh -c -d
|
||||
OBJEXT = o
|
||||
PACKAGE = task
|
||||
PACKAGE_BUGREPORT = bugs@beckingham.net
|
||||
PACKAGE_NAME = task
|
||||
PACKAGE_STRING = task 0.9.0
|
||||
PACKAGE_TARNAME = task
|
||||
PACKAGE_VERSION = 0.9.0
|
||||
PATH_SEPARATOR = :
|
||||
SET_MAKE =
|
||||
SHELL = /bin/sh
|
||||
STRIP =
|
||||
VERSION = 0.9.0
|
||||
abs_builddir = /Users/paul/work/task_rel/src
|
||||
abs_srcdir = /Users/paul/work/task_rel/src
|
||||
abs_top_builddir = /Users/paul/work/task_rel
|
||||
abs_top_srcdir = /Users/paul/work/task_rel
|
||||
ac_ct_CC = gcc
|
||||
ac_ct_CXX = g++
|
||||
am__include = include
|
||||
am__leading_dot = .
|
||||
am__quote =
|
||||
am__tar = ${AMTAR} chof - "$$tardir"
|
||||
am__untar = ${AMTAR} xf -
|
||||
bindir = ${exec_prefix}/bin
|
||||
build_alias =
|
||||
builddir = .
|
||||
datadir = ${datarootdir}
|
||||
datarootdir = ${prefix}/share
|
||||
docdir = ${datarootdir}/doc/${PACKAGE_TARNAME}
|
||||
dvidir = ${docdir}
|
||||
exec_prefix = ${prefix}
|
||||
host_alias =
|
||||
htmldir = ${docdir}
|
||||
includedir = ${prefix}/include
|
||||
infodir = ${datarootdir}/info
|
||||
install_sh = $(SHELL) /Users/paul/work/task_rel/install-sh
|
||||
libdir = ${exec_prefix}/lib
|
||||
libexecdir = ${exec_prefix}/libexec
|
||||
localedir = ${datarootdir}/locale
|
||||
localstatedir = ${prefix}/var
|
||||
mandir = ${datarootdir}/man
|
||||
mkdir_p = $(top_builddir)/./install-sh -c -d
|
||||
oldincludedir = /usr/include
|
||||
pdfdir = ${docdir}
|
||||
prefix = /usr/local
|
||||
program_transform_name = s,x,x,
|
||||
psdir = ${docdir}
|
||||
sbindir = ${exec_prefix}/sbin
|
||||
sharedstatedir = ${prefix}/com
|
||||
srcdir = .
|
||||
subdirs = src
|
||||
sysconfdir = ${prefix}/etc
|
||||
target_alias =
|
||||
top_builddir = ..
|
||||
top_srcdir = ..
|
||||
task_SOURCES = Config.cpp Date.cpp T.cpp TDB.cpp Table.cpp color.cpp parse.cpp task.cpp util.cpp text.cpp rules.cpp Config.h Date.h T.h TDB.h Table.h color.h stlmacros.h task.h
|
||||
all: all-am
|
||||
|
||||
.SUFFIXES:
|
||||
.SUFFIXES: .cpp .o .obj
|
||||
$(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps)
|
||||
@for dep in $?; do \
|
||||
case '$(am__configure_deps)' in \
|
||||
*$$dep*) \
|
||||
cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh \
|
||||
&& exit 0; \
|
||||
exit 1;; \
|
||||
esac; \
|
||||
done; \
|
||||
echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu src/Makefile'; \
|
||||
cd $(top_srcdir) && \
|
||||
$(AUTOMAKE) --gnu src/Makefile
|
||||
.PRECIOUS: Makefile
|
||||
Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status
|
||||
@case '$?' in \
|
||||
*config.status*) \
|
||||
cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \
|
||||
*) \
|
||||
echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)'; \
|
||||
cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \
|
||||
esac;
|
||||
|
||||
$(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES)
|
||||
cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
|
||||
|
||||
$(top_srcdir)/configure: $(am__configure_deps)
|
||||
cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
|
||||
$(ACLOCAL_M4): $(am__aclocal_m4_deps)
|
||||
cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
|
||||
install-binPROGRAMS: $(bin_PROGRAMS)
|
||||
@$(NORMAL_INSTALL)
|
||||
test -z "$(bindir)" || $(MKDIR_P) "$(DESTDIR)$(bindir)"
|
||||
@list='$(bin_PROGRAMS)'; for p in $$list; do \
|
||||
p1=`echo $$p|sed 's/$(EXEEXT)$$//'`; \
|
||||
if test -f $$p \
|
||||
; then \
|
||||
f=`echo "$$p1" | sed 's,^.*/,,;$(transform);s/$$/$(EXEEXT)/'`; \
|
||||
echo " $(INSTALL_PROGRAM_ENV) $(binPROGRAMS_INSTALL) '$$p' '$(DESTDIR)$(bindir)/$$f'"; \
|
||||
$(INSTALL_PROGRAM_ENV) $(binPROGRAMS_INSTALL) "$$p" "$(DESTDIR)$(bindir)/$$f" || exit 1; \
|
||||
else :; fi; \
|
||||
done
|
||||
|
||||
uninstall-binPROGRAMS:
|
||||
@$(NORMAL_UNINSTALL)
|
||||
@list='$(bin_PROGRAMS)'; for p in $$list; do \
|
||||
f=`echo "$$p" | sed 's,^.*/,,;s/$(EXEEXT)$$//;$(transform);s/$$/$(EXEEXT)/'`; \
|
||||
echo " rm -f '$(DESTDIR)$(bindir)/$$f'"; \
|
||||
rm -f "$(DESTDIR)$(bindir)/$$f"; \
|
||||
done
|
||||
|
||||
clean-binPROGRAMS:
|
||||
-test -z "$(bin_PROGRAMS)" || rm -f $(bin_PROGRAMS)
|
||||
task$(EXEEXT): $(task_OBJECTS) $(task_DEPENDENCIES)
|
||||
@rm -f task$(EXEEXT)
|
||||
$(CXXLINK) $(task_OBJECTS) $(task_LDADD) $(LIBS)
|
||||
|
||||
mostlyclean-compile:
|
||||
-rm -f *.$(OBJEXT)
|
||||
|
||||
distclean-compile:
|
||||
-rm -f *.tab.c
|
||||
|
||||
include ./$(DEPDIR)/Config.Po
|
||||
include ./$(DEPDIR)/Date.Po
|
||||
include ./$(DEPDIR)/T.Po
|
||||
include ./$(DEPDIR)/TDB.Po
|
||||
include ./$(DEPDIR)/Table.Po
|
||||
include ./$(DEPDIR)/color.Po
|
||||
include ./$(DEPDIR)/parse.Po
|
||||
include ./$(DEPDIR)/rules.Po
|
||||
include ./$(DEPDIR)/task.Po
|
||||
include ./$(DEPDIR)/text.Po
|
||||
include ./$(DEPDIR)/util.Po
|
||||
|
||||
.cpp.o:
|
||||
$(CXXCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $<
|
||||
mv -f $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po
|
||||
# source='$<' object='$@' libtool=no \
|
||||
# DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) \
|
||||
# $(CXXCOMPILE) -c -o $@ $<
|
||||
|
||||
.cpp.obj:
|
||||
$(CXXCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ `$(CYGPATH_W) '$<'`
|
||||
mv -f $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po
|
||||
# source='$<' object='$@' libtool=no \
|
||||
# DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) \
|
||||
# $(CXXCOMPILE) -c -o $@ `$(CYGPATH_W) '$<'`
|
||||
|
||||
ID: $(HEADERS) $(SOURCES) $(LISP) $(TAGS_FILES)
|
||||
list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \
|
||||
unique=`for i in $$list; do \
|
||||
if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
|
||||
done | \
|
||||
$(AWK) ' { files[$$0] = 1; } \
|
||||
END { for (i in files) print i; }'`; \
|
||||
mkid -fID $$unique
|
||||
tags: TAGS
|
||||
|
||||
TAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \
|
||||
$(TAGS_FILES) $(LISP)
|
||||
tags=; \
|
||||
here=`pwd`; \
|
||||
list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \
|
||||
unique=`for i in $$list; do \
|
||||
if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
|
||||
done | \
|
||||
$(AWK) ' { files[$$0] = 1; } \
|
||||
END { for (i in files) print i; }'`; \
|
||||
if test -z "$(ETAGS_ARGS)$$tags$$unique"; then :; else \
|
||||
test -n "$$unique" || unique=$$empty_fix; \
|
||||
$(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \
|
||||
$$tags $$unique; \
|
||||
fi
|
||||
ctags: CTAGS
|
||||
CTAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \
|
||||
$(TAGS_FILES) $(LISP)
|
||||
tags=; \
|
||||
here=`pwd`; \
|
||||
list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \
|
||||
unique=`for i in $$list; do \
|
||||
if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
|
||||
done | \
|
||||
$(AWK) ' { files[$$0] = 1; } \
|
||||
END { for (i in files) print i; }'`; \
|
||||
test -z "$(CTAGS_ARGS)$$tags$$unique" \
|
||||
|| $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \
|
||||
$$tags $$unique
|
||||
|
||||
GTAGS:
|
||||
here=`$(am__cd) $(top_builddir) && pwd` \
|
||||
&& cd $(top_srcdir) \
|
||||
&& gtags -i $(GTAGS_ARGS) $$here
|
||||
|
||||
distclean-tags:
|
||||
-rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags
|
||||
|
||||
distdir: $(DISTFILES)
|
||||
@srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \
|
||||
topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \
|
||||
list='$(DISTFILES)'; \
|
||||
dist_files=`for file in $$list; do echo $$file; done | \
|
||||
sed -e "s|^$$srcdirstrip/||;t" \
|
||||
-e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \
|
||||
case $$dist_files in \
|
||||
*/*) $(MKDIR_P) `echo "$$dist_files" | \
|
||||
sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \
|
||||
sort -u` ;; \
|
||||
esac; \
|
||||
for file in $$dist_files; do \
|
||||
if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \
|
||||
if test -d $$d/$$file; then \
|
||||
dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \
|
||||
if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \
|
||||
cp -pR $(srcdir)/$$file $(distdir)$$dir || exit 1; \
|
||||
fi; \
|
||||
cp -pR $$d/$$file $(distdir)$$dir || exit 1; \
|
||||
else \
|
||||
test -f $(distdir)/$$file \
|
||||
|| cp -p $$d/$$file $(distdir)/$$file \
|
||||
|| exit 1; \
|
||||
fi; \
|
||||
done
|
||||
check-am: all-am
|
||||
check: check-am
|
||||
all-am: Makefile $(PROGRAMS)
|
||||
installdirs:
|
||||
for dir in "$(DESTDIR)$(bindir)"; do \
|
||||
test -z "$$dir" || $(MKDIR_P) "$$dir"; \
|
||||
done
|
||||
install: install-am
|
||||
install-exec: install-exec-am
|
||||
install-data: install-data-am
|
||||
uninstall: uninstall-am
|
||||
|
||||
install-am: all-am
|
||||
@$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am
|
||||
|
||||
installcheck: installcheck-am
|
||||
install-strip:
|
||||
$(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \
|
||||
install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \
|
||||
`test -z '$(STRIP)' || \
|
||||
echo "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'"` install
|
||||
mostlyclean-generic:
|
||||
|
||||
clean-generic:
|
||||
|
||||
distclean-generic:
|
||||
-test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES)
|
||||
|
||||
maintainer-clean-generic:
|
||||
@echo "This command is intended for maintainers to use"
|
||||
@echo "it deletes files that may require special tools to rebuild."
|
||||
clean: clean-am
|
||||
|
||||
clean-am: clean-binPROGRAMS clean-generic mostlyclean-am
|
||||
|
||||
distclean: distclean-am
|
||||
-rm -rf ./$(DEPDIR)
|
||||
-rm -f Makefile
|
||||
distclean-am: clean-am distclean-compile distclean-generic \
|
||||
distclean-tags
|
||||
|
||||
dvi: dvi-am
|
||||
|
||||
dvi-am:
|
||||
|
||||
html: html-am
|
||||
|
||||
info: info-am
|
||||
|
||||
info-am:
|
||||
|
||||
install-data-am:
|
||||
|
||||
install-dvi: install-dvi-am
|
||||
|
||||
install-exec-am: install-binPROGRAMS
|
||||
|
||||
install-html: install-html-am
|
||||
|
||||
install-info: install-info-am
|
||||
|
||||
install-man:
|
||||
|
||||
install-pdf: install-pdf-am
|
||||
|
||||
install-ps: install-ps-am
|
||||
|
||||
installcheck-am:
|
||||
|
||||
maintainer-clean: maintainer-clean-am
|
||||
-rm -rf ./$(DEPDIR)
|
||||
-rm -f Makefile
|
||||
maintainer-clean-am: distclean-am maintainer-clean-generic
|
||||
|
||||
mostlyclean: mostlyclean-am
|
||||
|
||||
mostlyclean-am: mostlyclean-compile mostlyclean-generic
|
||||
|
||||
pdf: pdf-am
|
||||
|
||||
pdf-am:
|
||||
|
||||
ps: ps-am
|
||||
|
||||
ps-am:
|
||||
|
||||
uninstall-am: uninstall-binPROGRAMS
|
||||
|
||||
.MAKE: install-am install-strip
|
||||
|
||||
.PHONY: CTAGS GTAGS all all-am check check-am clean clean-binPROGRAMS \
|
||||
clean-generic ctags distclean distclean-compile \
|
||||
distclean-generic distclean-tags distdir dvi dvi-am html \
|
||||
html-am info info-am install install-am install-binPROGRAMS \
|
||||
install-data install-data-am install-dvi install-dvi-am \
|
||||
install-exec install-exec-am install-html install-html-am \
|
||||
install-info install-info-am install-man install-pdf \
|
||||
install-pdf-am install-ps install-ps-am install-strip \
|
||||
installcheck installcheck-am installdirs maintainer-clean \
|
||||
maintainer-clean-generic mostlyclean mostlyclean-compile \
|
||||
mostlyclean-generic pdf pdf-am ps ps-am tags uninstall \
|
||||
uninstall-am uninstall-binPROGRAMS
|
||||
|
||||
# Tell versions [3.59,3.63) of GNU make to not export all variables.
|
||||
# Otherwise a system limit (for SysV at least) may be exceeded.
|
||||
.NOEXPORT:
|
2
src/Makefile.am
Normal file
2
src/Makefile.am
Normal file
|
@ -0,0 +1,2 @@
|
|||
bin_PROGRAMS = task
|
||||
task_SOURCES = Config.cpp Date.cpp T.cpp TDB.cpp Table.cpp color.cpp parse.cpp task.cpp util.cpp text.cpp rules.cpp Config.h Date.h T.h TDB.h Table.h color.h stlmacros.h task.h
|
429
src/Makefile.in
Normal file
429
src/Makefile.in
Normal file
|
@ -0,0 +1,429 @@
|
|||
# Makefile.in generated by automake 1.10 from Makefile.am.
|
||||
# @configure_input@
|
||||
|
||||
# Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002,
|
||||
# 2003, 2004, 2005, 2006 Free Software Foundation, Inc.
|
||||
# This Makefile.in is free software; the Free Software Foundation
|
||||
# gives unlimited permission to copy and/or distribute it,
|
||||
# with or without modifications, as long as this notice is preserved.
|
||||
|
||||
# This program is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY, to the extent permitted by law; without
|
||||
# even the implied warranty of MERCHANTABILITY or FITNESS FOR A
|
||||
# PARTICULAR PURPOSE.
|
||||
|
||||
@SET_MAKE@
|
||||
|
||||
VPATH = @srcdir@
|
||||
pkgdatadir = $(datadir)/@PACKAGE@
|
||||
pkglibdir = $(libdir)/@PACKAGE@
|
||||
pkgincludedir = $(includedir)/@PACKAGE@
|
||||
am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd
|
||||
install_sh_DATA = $(install_sh) -c -m 644
|
||||
install_sh_PROGRAM = $(install_sh) -c
|
||||
install_sh_SCRIPT = $(install_sh) -c
|
||||
INSTALL_HEADER = $(INSTALL_DATA)
|
||||
transform = $(program_transform_name)
|
||||
NORMAL_INSTALL = :
|
||||
PRE_INSTALL = :
|
||||
POST_INSTALL = :
|
||||
NORMAL_UNINSTALL = :
|
||||
PRE_UNINSTALL = :
|
||||
POST_UNINSTALL = :
|
||||
bin_PROGRAMS = task$(EXEEXT)
|
||||
subdir = src
|
||||
DIST_COMMON = $(srcdir)/Makefile.am $(srcdir)/Makefile.in
|
||||
ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
|
||||
am__aclocal_m4_deps = $(top_srcdir)/configure.ac
|
||||
am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \
|
||||
$(ACLOCAL_M4)
|
||||
mkinstalldirs = $(install_sh) -d
|
||||
CONFIG_HEADER = $(top_builddir)/auto.h
|
||||
CONFIG_CLEAN_FILES =
|
||||
am__installdirs = "$(DESTDIR)$(bindir)"
|
||||
binPROGRAMS_INSTALL = $(INSTALL_PROGRAM)
|
||||
PROGRAMS = $(bin_PROGRAMS)
|
||||
am_task_OBJECTS = Config.$(OBJEXT) Date.$(OBJEXT) T.$(OBJEXT) \
|
||||
TDB.$(OBJEXT) Table.$(OBJEXT) color.$(OBJEXT) parse.$(OBJEXT) \
|
||||
task.$(OBJEXT) util.$(OBJEXT) text.$(OBJEXT) rules.$(OBJEXT)
|
||||
task_OBJECTS = $(am_task_OBJECTS)
|
||||
task_LDADD = $(LDADD)
|
||||
DEFAULT_INCLUDES = -I. -I$(top_builddir)@am__isrc@
|
||||
depcomp = $(SHELL) $(top_srcdir)/depcomp
|
||||
am__depfiles_maybe = depfiles
|
||||
CXXCOMPILE = $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) \
|
||||
$(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS)
|
||||
CXXLD = $(CXX)
|
||||
CXXLINK = $(CXXLD) $(AM_CXXFLAGS) $(CXXFLAGS) $(AM_LDFLAGS) $(LDFLAGS) \
|
||||
-o $@
|
||||
COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \
|
||||
$(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS)
|
||||
CCLD = $(CC)
|
||||
LINK = $(CCLD) $(AM_CFLAGS) $(CFLAGS) $(AM_LDFLAGS) $(LDFLAGS) -o $@
|
||||
SOURCES = $(task_SOURCES)
|
||||
DIST_SOURCES = $(task_SOURCES)
|
||||
ETAGS = etags
|
||||
CTAGS = ctags
|
||||
DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST)
|
||||
ACLOCAL = @ACLOCAL@
|
||||
AMTAR = @AMTAR@
|
||||
AUTOCONF = @AUTOCONF@
|
||||
AUTOHEADER = @AUTOHEADER@
|
||||
AUTOMAKE = @AUTOMAKE@
|
||||
AWK = @AWK@
|
||||
CC = @CC@
|
||||
CCDEPMODE = @CCDEPMODE@
|
||||
CFLAGS = @CFLAGS@
|
||||
CPPFLAGS = @CPPFLAGS@
|
||||
CXX = @CXX@
|
||||
CXXCPP = @CXXCPP@
|
||||
CXXDEPMODE = @CXXDEPMODE@
|
||||
CXXFLAGS = @CXXFLAGS@
|
||||
CYGPATH_W = @CYGPATH_W@
|
||||
DEFS = @DEFS@
|
||||
DEPDIR = @DEPDIR@
|
||||
ECHO_C = @ECHO_C@
|
||||
ECHO_N = @ECHO_N@
|
||||
ECHO_T = @ECHO_T@
|
||||
EGREP = @EGREP@
|
||||
EXEEXT = @EXEEXT@
|
||||
GREP = @GREP@
|
||||
INSTALL = @INSTALL@
|
||||
INSTALL_DATA = @INSTALL_DATA@
|
||||
INSTALL_PROGRAM = @INSTALL_PROGRAM@
|
||||
INSTALL_SCRIPT = @INSTALL_SCRIPT@
|
||||
INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@
|
||||
LDFLAGS = @LDFLAGS@
|
||||
LIBOBJS = @LIBOBJS@
|
||||
LIBS = @LIBS@
|
||||
LTLIBOBJS = @LTLIBOBJS@
|
||||
MAKEINFO = @MAKEINFO@
|
||||
MKDIR_P = @MKDIR_P@
|
||||
OBJEXT = @OBJEXT@
|
||||
PACKAGE = @PACKAGE@
|
||||
PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@
|
||||
PACKAGE_NAME = @PACKAGE_NAME@
|
||||
PACKAGE_STRING = @PACKAGE_STRING@
|
||||
PACKAGE_TARNAME = @PACKAGE_TARNAME@
|
||||
PACKAGE_VERSION = @PACKAGE_VERSION@
|
||||
PATH_SEPARATOR = @PATH_SEPARATOR@
|
||||
SET_MAKE = @SET_MAKE@
|
||||
SHELL = @SHELL@
|
||||
STRIP = @STRIP@
|
||||
VERSION = @VERSION@
|
||||
abs_builddir = @abs_builddir@
|
||||
abs_srcdir = @abs_srcdir@
|
||||
abs_top_builddir = @abs_top_builddir@
|
||||
abs_top_srcdir = @abs_top_srcdir@
|
||||
ac_ct_CC = @ac_ct_CC@
|
||||
ac_ct_CXX = @ac_ct_CXX@
|
||||
am__include = @am__include@
|
||||
am__leading_dot = @am__leading_dot@
|
||||
am__quote = @am__quote@
|
||||
am__tar = @am__tar@
|
||||
am__untar = @am__untar@
|
||||
bindir = @bindir@
|
||||
build_alias = @build_alias@
|
||||
builddir = @builddir@
|
||||
datadir = @datadir@
|
||||
datarootdir = @datarootdir@
|
||||
docdir = @docdir@
|
||||
dvidir = @dvidir@
|
||||
exec_prefix = @exec_prefix@
|
||||
host_alias = @host_alias@
|
||||
htmldir = @htmldir@
|
||||
includedir = @includedir@
|
||||
infodir = @infodir@
|
||||
install_sh = @install_sh@
|
||||
libdir = @libdir@
|
||||
libexecdir = @libexecdir@
|
||||
localedir = @localedir@
|
||||
localstatedir = @localstatedir@
|
||||
mandir = @mandir@
|
||||
mkdir_p = @mkdir_p@
|
||||
oldincludedir = @oldincludedir@
|
||||
pdfdir = @pdfdir@
|
||||
prefix = @prefix@
|
||||
program_transform_name = @program_transform_name@
|
||||
psdir = @psdir@
|
||||
sbindir = @sbindir@
|
||||
sharedstatedir = @sharedstatedir@
|
||||
srcdir = @srcdir@
|
||||
subdirs = @subdirs@
|
||||
sysconfdir = @sysconfdir@
|
||||
target_alias = @target_alias@
|
||||
top_builddir = @top_builddir@
|
||||
top_srcdir = @top_srcdir@
|
||||
task_SOURCES = Config.cpp Date.cpp T.cpp TDB.cpp Table.cpp color.cpp parse.cpp task.cpp util.cpp text.cpp rules.cpp Config.h Date.h T.h TDB.h Table.h color.h stlmacros.h task.h
|
||||
all: all-am
|
||||
|
||||
.SUFFIXES:
|
||||
.SUFFIXES: .cpp .o .obj
|
||||
$(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps)
|
||||
@for dep in $?; do \
|
||||
case '$(am__configure_deps)' in \
|
||||
*$$dep*) \
|
||||
cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh \
|
||||
&& exit 0; \
|
||||
exit 1;; \
|
||||
esac; \
|
||||
done; \
|
||||
echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu src/Makefile'; \
|
||||
cd $(top_srcdir) && \
|
||||
$(AUTOMAKE) --gnu src/Makefile
|
||||
.PRECIOUS: Makefile
|
||||
Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status
|
||||
@case '$?' in \
|
||||
*config.status*) \
|
||||
cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \
|
||||
*) \
|
||||
echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)'; \
|
||||
cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \
|
||||
esac;
|
||||
|
||||
$(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES)
|
||||
cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
|
||||
|
||||
$(top_srcdir)/configure: $(am__configure_deps)
|
||||
cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
|
||||
$(ACLOCAL_M4): $(am__aclocal_m4_deps)
|
||||
cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
|
||||
install-binPROGRAMS: $(bin_PROGRAMS)
|
||||
@$(NORMAL_INSTALL)
|
||||
test -z "$(bindir)" || $(MKDIR_P) "$(DESTDIR)$(bindir)"
|
||||
@list='$(bin_PROGRAMS)'; for p in $$list; do \
|
||||
p1=`echo $$p|sed 's/$(EXEEXT)$$//'`; \
|
||||
if test -f $$p \
|
||||
; then \
|
||||
f=`echo "$$p1" | sed 's,^.*/,,;$(transform);s/$$/$(EXEEXT)/'`; \
|
||||
echo " $(INSTALL_PROGRAM_ENV) $(binPROGRAMS_INSTALL) '$$p' '$(DESTDIR)$(bindir)/$$f'"; \
|
||||
$(INSTALL_PROGRAM_ENV) $(binPROGRAMS_INSTALL) "$$p" "$(DESTDIR)$(bindir)/$$f" || exit 1; \
|
||||
else :; fi; \
|
||||
done
|
||||
|
||||
uninstall-binPROGRAMS:
|
||||
@$(NORMAL_UNINSTALL)
|
||||
@list='$(bin_PROGRAMS)'; for p in $$list; do \
|
||||
f=`echo "$$p" | sed 's,^.*/,,;s/$(EXEEXT)$$//;$(transform);s/$$/$(EXEEXT)/'`; \
|
||||
echo " rm -f '$(DESTDIR)$(bindir)/$$f'"; \
|
||||
rm -f "$(DESTDIR)$(bindir)/$$f"; \
|
||||
done
|
||||
|
||||
clean-binPROGRAMS:
|
||||
-test -z "$(bin_PROGRAMS)" || rm -f $(bin_PROGRAMS)
|
||||
task$(EXEEXT): $(task_OBJECTS) $(task_DEPENDENCIES)
|
||||
@rm -f task$(EXEEXT)
|
||||
$(CXXLINK) $(task_OBJECTS) $(task_LDADD) $(LIBS)
|
||||
|
||||
mostlyclean-compile:
|
||||
-rm -f *.$(OBJEXT)
|
||||
|
||||
distclean-compile:
|
||||
-rm -f *.tab.c
|
||||
|
||||
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/Config.Po@am__quote@
|
||||
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/Date.Po@am__quote@
|
||||
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/T.Po@am__quote@
|
||||
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/TDB.Po@am__quote@
|
||||
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/Table.Po@am__quote@
|
||||
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/color.Po@am__quote@
|
||||
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/parse.Po@am__quote@
|
||||
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/rules.Po@am__quote@
|
||||
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/task.Po@am__quote@
|
||||
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/text.Po@am__quote@
|
||||
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/util.Po@am__quote@
|
||||
|
||||
.cpp.o:
|
||||
@am__fastdepCXX_TRUE@ $(CXXCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $<
|
||||
@am__fastdepCXX_TRUE@ mv -f $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po
|
||||
@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='$<' object='$@' libtool=no @AMDEPBACKSLASH@
|
||||
@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
|
||||
@am__fastdepCXX_FALSE@ $(CXXCOMPILE) -c -o $@ $<
|
||||
|
||||
.cpp.obj:
|
||||
@am__fastdepCXX_TRUE@ $(CXXCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ `$(CYGPATH_W) '$<'`
|
||||
@am__fastdepCXX_TRUE@ mv -f $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po
|
||||
@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='$<' object='$@' libtool=no @AMDEPBACKSLASH@
|
||||
@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
|
||||
@am__fastdepCXX_FALSE@ $(CXXCOMPILE) -c -o $@ `$(CYGPATH_W) '$<'`
|
||||
|
||||
ID: $(HEADERS) $(SOURCES) $(LISP) $(TAGS_FILES)
|
||||
list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \
|
||||
unique=`for i in $$list; do \
|
||||
if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
|
||||
done | \
|
||||
$(AWK) ' { files[$$0] = 1; } \
|
||||
END { for (i in files) print i; }'`; \
|
||||
mkid -fID $$unique
|
||||
tags: TAGS
|
||||
|
||||
TAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \
|
||||
$(TAGS_FILES) $(LISP)
|
||||
tags=; \
|
||||
here=`pwd`; \
|
||||
list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \
|
||||
unique=`for i in $$list; do \
|
||||
if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
|
||||
done | \
|
||||
$(AWK) ' { files[$$0] = 1; } \
|
||||
END { for (i in files) print i; }'`; \
|
||||
if test -z "$(ETAGS_ARGS)$$tags$$unique"; then :; else \
|
||||
test -n "$$unique" || unique=$$empty_fix; \
|
||||
$(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \
|
||||
$$tags $$unique; \
|
||||
fi
|
||||
ctags: CTAGS
|
||||
CTAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \
|
||||
$(TAGS_FILES) $(LISP)
|
||||
tags=; \
|
||||
here=`pwd`; \
|
||||
list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \
|
||||
unique=`for i in $$list; do \
|
||||
if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
|
||||
done | \
|
||||
$(AWK) ' { files[$$0] = 1; } \
|
||||
END { for (i in files) print i; }'`; \
|
||||
test -z "$(CTAGS_ARGS)$$tags$$unique" \
|
||||
|| $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \
|
||||
$$tags $$unique
|
||||
|
||||
GTAGS:
|
||||
here=`$(am__cd) $(top_builddir) && pwd` \
|
||||
&& cd $(top_srcdir) \
|
||||
&& gtags -i $(GTAGS_ARGS) $$here
|
||||
|
||||
distclean-tags:
|
||||
-rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags
|
||||
|
||||
distdir: $(DISTFILES)
|
||||
@srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \
|
||||
topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \
|
||||
list='$(DISTFILES)'; \
|
||||
dist_files=`for file in $$list; do echo $$file; done | \
|
||||
sed -e "s|^$$srcdirstrip/||;t" \
|
||||
-e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \
|
||||
case $$dist_files in \
|
||||
*/*) $(MKDIR_P) `echo "$$dist_files" | \
|
||||
sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \
|
||||
sort -u` ;; \
|
||||
esac; \
|
||||
for file in $$dist_files; do \
|
||||
if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \
|
||||
if test -d $$d/$$file; then \
|
||||
dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \
|
||||
if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \
|
||||
cp -pR $(srcdir)/$$file $(distdir)$$dir || exit 1; \
|
||||
fi; \
|
||||
cp -pR $$d/$$file $(distdir)$$dir || exit 1; \
|
||||
else \
|
||||
test -f $(distdir)/$$file \
|
||||
|| cp -p $$d/$$file $(distdir)/$$file \
|
||||
|| exit 1; \
|
||||
fi; \
|
||||
done
|
||||
check-am: all-am
|
||||
check: check-am
|
||||
all-am: Makefile $(PROGRAMS)
|
||||
installdirs:
|
||||
for dir in "$(DESTDIR)$(bindir)"; do \
|
||||
test -z "$$dir" || $(MKDIR_P) "$$dir"; \
|
||||
done
|
||||
install: install-am
|
||||
install-exec: install-exec-am
|
||||
install-data: install-data-am
|
||||
uninstall: uninstall-am
|
||||
|
||||
install-am: all-am
|
||||
@$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am
|
||||
|
||||
installcheck: installcheck-am
|
||||
install-strip:
|
||||
$(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \
|
||||
install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \
|
||||
`test -z '$(STRIP)' || \
|
||||
echo "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'"` install
|
||||
mostlyclean-generic:
|
||||
|
||||
clean-generic:
|
||||
|
||||
distclean-generic:
|
||||
-test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES)
|
||||
|
||||
maintainer-clean-generic:
|
||||
@echo "This command is intended for maintainers to use"
|
||||
@echo "it deletes files that may require special tools to rebuild."
|
||||
clean: clean-am
|
||||
|
||||
clean-am: clean-binPROGRAMS clean-generic mostlyclean-am
|
||||
|
||||
distclean: distclean-am
|
||||
-rm -rf ./$(DEPDIR)
|
||||
-rm -f Makefile
|
||||
distclean-am: clean-am distclean-compile distclean-generic \
|
||||
distclean-tags
|
||||
|
||||
dvi: dvi-am
|
||||
|
||||
dvi-am:
|
||||
|
||||
html: html-am
|
||||
|
||||
info: info-am
|
||||
|
||||
info-am:
|
||||
|
||||
install-data-am:
|
||||
|
||||
install-dvi: install-dvi-am
|
||||
|
||||
install-exec-am: install-binPROGRAMS
|
||||
|
||||
install-html: install-html-am
|
||||
|
||||
install-info: install-info-am
|
||||
|
||||
install-man:
|
||||
|
||||
install-pdf: install-pdf-am
|
||||
|
||||
install-ps: install-ps-am
|
||||
|
||||
installcheck-am:
|
||||
|
||||
maintainer-clean: maintainer-clean-am
|
||||
-rm -rf ./$(DEPDIR)
|
||||
-rm -f Makefile
|
||||
maintainer-clean-am: distclean-am maintainer-clean-generic
|
||||
|
||||
mostlyclean: mostlyclean-am
|
||||
|
||||
mostlyclean-am: mostlyclean-compile mostlyclean-generic
|
||||
|
||||
pdf: pdf-am
|
||||
|
||||
pdf-am:
|
||||
|
||||
ps: ps-am
|
||||
|
||||
ps-am:
|
||||
|
||||
uninstall-am: uninstall-binPROGRAMS
|
||||
|
||||
.MAKE: install-am install-strip
|
||||
|
||||
.PHONY: CTAGS GTAGS all all-am check check-am clean clean-binPROGRAMS \
|
||||
clean-generic ctags distclean distclean-compile \
|
||||
distclean-generic distclean-tags distdir dvi dvi-am html \
|
||||
html-am info info-am install install-am install-binPROGRAMS \
|
||||
install-data install-data-am install-dvi install-dvi-am \
|
||||
install-exec install-exec-am install-html install-html-am \
|
||||
install-info install-info-am install-man install-pdf \
|
||||
install-pdf-am install-ps install-ps-am install-strip \
|
||||
installcheck installcheck-am installdirs maintainer-clean \
|
||||
maintainer-clean-generic mostlyclean mostlyclean-compile \
|
||||
mostlyclean-generic pdf pdf-am ps ps-am tags uninstall \
|
||||
uninstall-am uninstall-binPROGRAMS
|
||||
|
||||
# Tell versions [3.59,3.63) of GNU make to not export all variables.
|
||||
# Otherwise a system limit (for SysV at least) may be exceeded.
|
||||
.NOEXPORT:
|
510
src/T.cpp
Normal file
510
src/T.cpp
Normal file
|
@ -0,0 +1,510 @@
|
|||
////////////////////////////////////////////////////////////////////////////////
|
||||
// Copyright 2006 - 2008, Paul Beckingham. All rights reserved.
|
||||
//
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
#include <iostream>
|
||||
#include <algorithm>
|
||||
#include "task.h"
|
||||
#include "T.h"
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
// Default
|
||||
T::T ()
|
||||
{
|
||||
mUUID = uuid ();
|
||||
mStatus = pending;
|
||||
mId = 0;
|
||||
mTags.clear ();
|
||||
mAttributes.clear ();
|
||||
mDescription = "";
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
// Initialize by parsing storage format
|
||||
T::T (const std::string& line)
|
||||
{
|
||||
parse (line);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
T::T (const T& other)
|
||||
{
|
||||
mStatus = other.mStatus;
|
||||
mUUID = other.mUUID;
|
||||
mId = other.mId;
|
||||
mDescription = other.mDescription;
|
||||
mTags = other.mTags;
|
||||
mRemoveTags = other.mRemoveTags;
|
||||
mAttributes = other.mAttributes;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
T& T::operator= (const T& other)
|
||||
{
|
||||
if (this != &other)
|
||||
{
|
||||
mStatus = other.mStatus;
|
||||
mUUID = other.mUUID;
|
||||
mId = other.mId;
|
||||
mDescription = other.mDescription;
|
||||
mTags = other.mTags;
|
||||
mRemoveTags = other.mRemoveTags;
|
||||
mAttributes = other.mAttributes;
|
||||
}
|
||||
|
||||
return *this;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
T::~T ()
|
||||
{
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
bool T::hasTag (const std::string& tag) const
|
||||
{
|
||||
std::vector <std::string>::const_iterator it = find (mTags.begin (), mTags.end (), tag);
|
||||
if (it != mTags.end ())
|
||||
return true;
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
// SPECIAL METHOD - DO NOT REMOVE
|
||||
void T::getRemoveTags (std::vector<std::string>& all)
|
||||
{
|
||||
all = mRemoveTags;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
// SPECIAL METHOD - DO NOT REMOVE
|
||||
void T::addRemoveTag (const std::string& tag)
|
||||
{
|
||||
if (tag.find (' ') != std::string::npos)
|
||||
throw std::string ("T::addRemoveTag - tags may not contain spaces");
|
||||
|
||||
mRemoveTags.push_back (tag);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
void T::getTags (std::vector<std::string>& all) const
|
||||
{
|
||||
all = mTags;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
void T::addTag (const std::string& tag)
|
||||
{
|
||||
if (tag.find (' ') != std::string::npos)
|
||||
throw std::string ("T::addTag - tags may not contain spaces");
|
||||
|
||||
if (tag[0] == '+')
|
||||
{
|
||||
if (! hasTag (tag.substr (1, std::string::npos)))
|
||||
mTags.push_back (tag.substr (1, std::string::npos));
|
||||
}
|
||||
else
|
||||
{
|
||||
if (! hasTag (tag))
|
||||
mTags.push_back (tag);
|
||||
}
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
void T::addTags (const std::vector <std::string>& tags)
|
||||
{
|
||||
for (unsigned int i = 0; i < tags.size (); ++i)
|
||||
{
|
||||
if (tags[i].find (' ') != std::string::npos)
|
||||
throw std::string ("T::addTags - tags may not contain spaces");
|
||||
|
||||
if (tags[i][0] == '+')
|
||||
{
|
||||
if (! hasTag (tags[i].substr (1, std::string::npos)))
|
||||
mTags.push_back (tags[i].substr (1, std::string::npos));
|
||||
}
|
||||
else
|
||||
{
|
||||
if (! hasTag (tags[i]))
|
||||
mTags.push_back (tags[i]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
void T::removeTag (const std::string& tag)
|
||||
{
|
||||
std::vector <std::string> copy;
|
||||
for (unsigned int i = 0; i < mTags.size (); ++i)
|
||||
if (mTags[i] != tag)
|
||||
copy.push_back (mTags[i]);
|
||||
|
||||
mTags = copy;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
void T::removeTags ()
|
||||
{
|
||||
mTags.clear ();
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
void T::getAttributes (std::map<std::string, std::string>& all)
|
||||
{
|
||||
all = mAttributes;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
const std::string T::getAttribute (const std::string& name)
|
||||
{
|
||||
if (mAttributes.find (name) != mAttributes.end ())
|
||||
return mAttributes[name];
|
||||
|
||||
return "";
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
void T::setAttribute (const std::string& name, const std::string& value)
|
||||
{
|
||||
if (name.find (' ') != std::string::npos)
|
||||
throw std::string ("An attribute name may not contain spaces");
|
||||
|
||||
if (value.find (' ') != std::string::npos)
|
||||
throw std::string ("An attribute value may not contain spaces");
|
||||
|
||||
mAttributes[name] = value;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
void T::setAttributes (const std::map <std::string, std::string>& attributes)
|
||||
{
|
||||
foreach (i, attributes)
|
||||
{
|
||||
if (i->first.find (' ') != std::string::npos)
|
||||
throw std::string ("An attribute name may not contain spaces");
|
||||
|
||||
if (i->second.find (' ') != std::string::npos)
|
||||
throw std::string ("An attribute value may not contain spaces");
|
||||
|
||||
mAttributes[i->first] = i->second;
|
||||
}
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
void T::removeAttributes ()
|
||||
{
|
||||
mAttributes.clear ();
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
void T::removeAttribute (const std::string& name)
|
||||
{
|
||||
std::map <std::string, std::string> copy = mAttributes;
|
||||
mAttributes.clear ();
|
||||
foreach (i, copy)
|
||||
if (i->first != name)
|
||||
mAttributes[i->first] = i->second;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
void T::getSubstitution (std::string& from, std::string& to) const
|
||||
{
|
||||
from = mFrom;
|
||||
to = mTo;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
void T::setSubstitution (const std::string& from, const std::string& to)
|
||||
{
|
||||
mFrom = from;
|
||||
mTo = to;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
// uuid status [tags] [attributes] description
|
||||
//
|
||||
// uuid \x{8}-\x{4}-\x{4}-\x{4}-\x{12}
|
||||
// status - O X
|
||||
// tags \w+ \s ...
|
||||
// attributes \w+:\w+ \s ...
|
||||
// description .+
|
||||
//
|
||||
const std::string T::compose () const
|
||||
{
|
||||
// UUID
|
||||
std::string line = mUUID + ' ';
|
||||
|
||||
// Status
|
||||
if (mStatus == pending) line += "- [";
|
||||
else if (mStatus == completed) line += "+ [";
|
||||
else if (mStatus == deleted) line += "X [";
|
||||
|
||||
// Tags
|
||||
for (unsigned int i = 0; i < mTags.size (); ++i)
|
||||
{
|
||||
line += (i > 0 ? " " : "");
|
||||
line += mTags[i];
|
||||
}
|
||||
|
||||
line += "] [";
|
||||
|
||||
// Attributes
|
||||
int count = 0;
|
||||
foreach (i, mAttributes)
|
||||
{
|
||||
std::string converted = i->second;
|
||||
|
||||
// Date attributes may need conversion to epoch.
|
||||
if (i->first == "due" ||
|
||||
i->first == "start" ||
|
||||
i->first == "entry" ||
|
||||
i->first == "end")
|
||||
{
|
||||
if (i->second.find ("/") != std::string::npos)
|
||||
validDate (converted);
|
||||
}
|
||||
|
||||
line += (count > 0 ? " " : "");
|
||||
line += i->first + ":" + converted;
|
||||
|
||||
++count;
|
||||
}
|
||||
|
||||
line += "] ";
|
||||
|
||||
// Description
|
||||
line += mDescription;
|
||||
line += "\n";
|
||||
|
||||
if (line.length () > T_LINE_MAX)
|
||||
throw std::string ("Line too long");
|
||||
|
||||
return line;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
const std::string T::composeCSV ()
|
||||
{
|
||||
// UUID
|
||||
std::string line = "'" + mUUID + "',";
|
||||
|
||||
// Status
|
||||
if (mStatus == pending) line += "'pending',";
|
||||
else if (mStatus == completed) line += "'completed',";
|
||||
else if (mStatus == deleted) line += "'deleted',";
|
||||
|
||||
// Tags
|
||||
line += "'";
|
||||
for (unsigned int i = 0; i < mTags.size (); ++i)
|
||||
{
|
||||
line += (i > 0 ? " " : "");
|
||||
line += mTags[i];
|
||||
}
|
||||
|
||||
line += "',";
|
||||
std::string value = mAttributes["entry"];
|
||||
line += value + ",";
|
||||
|
||||
value = mAttributes["start"];
|
||||
if (value != "")
|
||||
line += value;
|
||||
line += ",";
|
||||
|
||||
value = mAttributes["due"];
|
||||
if (value != "")
|
||||
line += value;
|
||||
line += ",";
|
||||
|
||||
value = mAttributes["end"];
|
||||
if (value != "")
|
||||
line += value;
|
||||
line += ",";
|
||||
|
||||
value = mAttributes["project"];
|
||||
if (value != "")
|
||||
line += "'" + value + "'";
|
||||
line += ",";
|
||||
|
||||
value = mAttributes["priority"];
|
||||
if (value != "")
|
||||
line += "'" + value + "'";
|
||||
line += ",";
|
||||
|
||||
value = mAttributes["fg"];
|
||||
if (value != "")
|
||||
line += "'" + value + "'";
|
||||
line += ",";
|
||||
|
||||
value = mAttributes["bg"];
|
||||
if (value != "")
|
||||
line += "'" + value + "'";
|
||||
line += ",";
|
||||
|
||||
line += "'" + mDescription + "'\n";
|
||||
|
||||
return line;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
// Read all file formats, write only the latest.
|
||||
void T::parse (const std::string& line)
|
||||
{
|
||||
switch (determineVersion (line))
|
||||
{
|
||||
// File format version 1, from 2006.11.27 - 2007.12.31
|
||||
case 1:
|
||||
{
|
||||
// Generate a UUID for forward support.
|
||||
mUUID = uuid ();
|
||||
|
||||
if (line.length () > 6) // ^\[\]\s\[\]\n
|
||||
{
|
||||
if (line[0] == 'X')
|
||||
setStatus (deleted);
|
||||
|
||||
unsigned int openTagBracket = line.find ("[");
|
||||
unsigned int closeTagBracket = line.find ("]", openTagBracket);
|
||||
if (openTagBracket != std::string::npos &&
|
||||
closeTagBracket != std::string::npos)
|
||||
{
|
||||
unsigned int openAttrBracket = line.find ("[", closeTagBracket);
|
||||
unsigned int closeAttrBracket = line.find ("]", openAttrBracket);
|
||||
if (openAttrBracket != std::string::npos &&
|
||||
closeAttrBracket != std::string::npos)
|
||||
{
|
||||
std::string tags = line.substr (
|
||||
openTagBracket + 1, closeTagBracket - openTagBracket - 1);
|
||||
std::vector <std::string> rawTags;
|
||||
split (mTags, tags, ' ');
|
||||
|
||||
std::string attributes = line.substr (
|
||||
openAttrBracket + 1, closeAttrBracket - openAttrBracket - 1);
|
||||
std::vector <std::string> pairs;
|
||||
split (pairs, attributes, ' ');
|
||||
for (unsigned int i = 0; i < pairs.size (); ++i)
|
||||
{
|
||||
std::vector <std::string> pair;
|
||||
split (pair, pairs[i], ':');
|
||||
if (pair[1] != "")
|
||||
mAttributes[pair[0]] = pair[1];
|
||||
}
|
||||
|
||||
mDescription = line.substr (closeAttrBracket + 2, std::string::npos);
|
||||
}
|
||||
else
|
||||
throw std::string ("Missing attribute brackets");
|
||||
}
|
||||
else
|
||||
throw std::string ("Missing tag brackets");
|
||||
}
|
||||
else
|
||||
throw std::string ("Line too short");
|
||||
}
|
||||
break;
|
||||
|
||||
// File format version 2, from 2008.1.1
|
||||
case 2:
|
||||
{
|
||||
if (line.length () > 46) // ^.{36} . \[\] \[\] \n
|
||||
{
|
||||
mUUID = line.substr (0, 36);
|
||||
|
||||
mStatus = line[37] == '+' ? completed
|
||||
: line[37] == 'X' ? deleted
|
||||
: pending;
|
||||
|
||||
unsigned int openTagBracket = line.find ("[");
|
||||
unsigned int closeTagBracket = line.find ("]", openTagBracket);
|
||||
if (openTagBracket != std::string::npos &&
|
||||
closeTagBracket != std::string::npos)
|
||||
{
|
||||
unsigned int openAttrBracket = line.find ("[", closeTagBracket);
|
||||
unsigned int closeAttrBracket = line.find ("]", openAttrBracket);
|
||||
if (openAttrBracket != std::string::npos &&
|
||||
closeAttrBracket != std::string::npos)
|
||||
{
|
||||
std::string tags = line.substr (
|
||||
openTagBracket + 1, closeTagBracket - openTagBracket - 1);
|
||||
std::vector <std::string> rawTags;
|
||||
split (mTags, tags, ' ');
|
||||
|
||||
std::string attributes = line.substr (
|
||||
openAttrBracket + 1, closeAttrBracket - openAttrBracket - 1);
|
||||
std::vector <std::string> pairs;
|
||||
split (pairs, attributes, ' ');
|
||||
for (unsigned int i = 0; i < pairs.size (); ++i)
|
||||
{
|
||||
std::vector <std::string> pair;
|
||||
split (pair, pairs[i], ':');
|
||||
if (pair[1] != "")
|
||||
mAttributes[pair[0]] = pair[1];
|
||||
}
|
||||
|
||||
mDescription = line.substr (closeAttrBracket + 2, std::string::npos);
|
||||
}
|
||||
else
|
||||
throw std::string ("Missing attribute brackets");
|
||||
}
|
||||
else
|
||||
throw std::string ("Missing tag brackets");
|
||||
}
|
||||
else
|
||||
throw std::string ("Line too short");
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
throw std::string ();
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
// If this code is inaccurate, data corruption ensues.
|
||||
int T::determineVersion (const std::string& line)
|
||||
{
|
||||
// Version 1 looks like:
|
||||
//
|
||||
// [tags] [attributes] description\n
|
||||
// X [tags] [attributes] description\n
|
||||
//
|
||||
// Scan for the first character being either the bracket or X.
|
||||
if (line[0] == '[' ||
|
||||
line[0] == 'X')
|
||||
return 1;
|
||||
|
||||
// Version 2 looks like:
|
||||
//
|
||||
// uuid status [tags] [attributes] description\n
|
||||
//
|
||||
// Where uuid looks like:
|
||||
//
|
||||
// 27755d92-c5e9-4c21-bd8e-c3dd9e6d3cf7
|
||||
//
|
||||
// Scan for the hyphens in the uuid, the following space, and a valid status
|
||||
// character.
|
||||
if (line[8] == '-' &&
|
||||
line[13] == '-' &&
|
||||
line[18] == '-' &&
|
||||
line[23] == '-' &&
|
||||
line[36] == ' ' &&
|
||||
(line[37] == '-' || line[37] == '+' || line[37] == 'X'))
|
||||
return 2;
|
||||
|
||||
// Version 3?
|
||||
//
|
||||
// Fortunately, with the hindsight that will come with version 3, the
|
||||
// identifying characteristics of 1 and 2 may be modified such that if 3 has
|
||||
// a UUID followed by a status, then there is still a way to differentiate
|
||||
// between 2 and 3.
|
||||
//
|
||||
// The danger is that a version 2 binary reads and misinterprets a version 2
|
||||
// file. This is why it is a good idea to rely on an explicit version
|
||||
// declaration rather than chance positioning.
|
||||
|
||||
// Zero means 'no idea'.
|
||||
return 0;
|
||||
}
|
||||
|
80
src/T.h
Normal file
80
src/T.h
Normal file
|
@ -0,0 +1,80 @@
|
|||
////////////////////////////////////////////////////////////////////////////////
|
||||
// Copyright 2006 - 2007, Paul Beckingham. All rights reserved.
|
||||
//
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
#ifndef INCLUDED_T
|
||||
#define INCLUDED_T
|
||||
|
||||
#include <string>
|
||||
#include <vector>
|
||||
#include <map>
|
||||
|
||||
// Length of longest line.
|
||||
#define T_LINE_MAX 8192
|
||||
|
||||
class T
|
||||
{
|
||||
public:
|
||||
enum status {pending, completed, deleted};
|
||||
|
||||
T (); // Default constructor
|
||||
T (const std::string&); // Initialize by parsing storage format
|
||||
T (const T&); // Copy constructor
|
||||
T& operator= (const T&); // Assignment operator
|
||||
~T (); // Destructor
|
||||
|
||||
std::string getUUID () const { return mUUID; }
|
||||
void setUUID (const std::string& uuid) { mUUID = uuid; }
|
||||
|
||||
int getId () const { return mId; }
|
||||
void setId (int id) { mId = id; }
|
||||
|
||||
status getStatus () const { return mStatus; }
|
||||
void setStatus (status s) { mStatus = s; }
|
||||
|
||||
const std::string getDescription () const { return mDescription; }
|
||||
void setDescription (const std::string& description) { mDescription = description; }
|
||||
|
||||
void getSubstitution (std::string&, std::string&) const;
|
||||
void setSubstitution (const std::string&, const std::string&);
|
||||
|
||||
bool hasTag (const std::string&) const;
|
||||
|
||||
void getRemoveTags (std::vector<std::string>&); // SPECIAL
|
||||
void addRemoveTag (const std::string&); // SPECIAL
|
||||
|
||||
void getTags (std::vector<std::string>&) const;
|
||||
void addTag (const std::string&);
|
||||
void addTags (const std::vector <std::string>&);
|
||||
void removeTag (const std::string&);
|
||||
void removeTags ();
|
||||
void getAttributes (std::map<std::string, std::string>&);
|
||||
const std::string getAttribute (const std::string&);
|
||||
void setAttribute (const std::string&, const std::string&);
|
||||
void setAttributes (const std::map <std::string, std::string>&);
|
||||
void removeAttribute (const std::string&);
|
||||
void removeAttributes ();
|
||||
|
||||
const std::string compose () const;
|
||||
const std::string composeCSV ();
|
||||
void parse (const std::string&);
|
||||
|
||||
private:
|
||||
int determineVersion (const std::string&);
|
||||
|
||||
private:
|
||||
status mStatus;
|
||||
std::string mUUID;
|
||||
int mId;
|
||||
std::string mDescription;
|
||||
std::vector<std::string> mTags;
|
||||
std::vector<std::string> mRemoveTags;
|
||||
std::map<std::string, std::string> mAttributes;
|
||||
|
||||
std::string mFrom;
|
||||
std::string mTo;
|
||||
};
|
||||
|
||||
#endif
|
||||
////////////////////////////////////////////////////////////////////////////////
|
467
src/TDB.cpp
Normal file
467
src/TDB.cpp
Normal file
|
@ -0,0 +1,467 @@
|
|||
////////////////////////////////////////////////////////////////////////////////
|
||||
// Copyright 2007, 2008, Paul Beckingham. All rights reserved.
|
||||
//
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
#include <iostream>
|
||||
#include <fstream>
|
||||
#include <sys/file.h>
|
||||
#include <unistd.h>
|
||||
|
||||
#include "task.h"
|
||||
#include "TDB.h"
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
TDB::TDB ()
|
||||
: mPendingFile ("")
|
||||
, mCompletedFile ("")
|
||||
, mLogFile ("")
|
||||
{
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
TDB::~TDB ()
|
||||
{
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
void TDB::dataDirectory (const std::string& directory)
|
||||
{
|
||||
if (! access (directory.c_str (), F_OK))
|
||||
{
|
||||
mPendingFile = directory + "/pending.data";
|
||||
mCompletedFile = directory + "/completed.data";
|
||||
mLogFile = directory + "/command.log";
|
||||
}
|
||||
else
|
||||
{
|
||||
std::string error = "Directory '";
|
||||
error += directory;
|
||||
error += "' does not exist, or is not readable and writable.";
|
||||
throw error;
|
||||
}
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
// Combine allPendingT with allCompletedT.
|
||||
// Note: this method is O(N1) + O(N2), where N2 is not bounded.
|
||||
bool TDB::allT (std::vector <T>& all) const
|
||||
{
|
||||
all.clear ();
|
||||
|
||||
// Retrieve all the pending records.
|
||||
std::vector <T> allp;
|
||||
if (allPendingT (allp))
|
||||
{
|
||||
std::vector <T>::iterator i;
|
||||
for (i = allp.begin (); i != allp.end (); ++i)
|
||||
all.push_back (*i);
|
||||
|
||||
// Retrieve all the completed records.
|
||||
std::vector <T> allc;
|
||||
if (allCompletedT (allc))
|
||||
{
|
||||
for (i = allc.begin (); i != allc.end (); ++i)
|
||||
all.push_back (*i);
|
||||
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
// Only accesses to the pending file result in Tasks that have assigned ids.
|
||||
bool TDB::pendingT (std::vector <T>& all) const
|
||||
{
|
||||
all.clear ();
|
||||
|
||||
std::vector <std::string> lines;
|
||||
if (readLockedFile (mPendingFile, lines))
|
||||
{
|
||||
int id = 1;
|
||||
|
||||
std::vector <std::string>::iterator it;
|
||||
for (it = lines.begin (); it != lines.end (); ++it)
|
||||
{
|
||||
T t (*it);
|
||||
t.setId (id++);
|
||||
if (t.getStatus () == T::pending)
|
||||
all.push_back (t);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
// Only accesses to the pending file result in Tasks that have assigned ids.
|
||||
bool TDB::allPendingT (std::vector <T>& all) const
|
||||
{
|
||||
all.clear ();
|
||||
|
||||
std::vector <std::string> lines;
|
||||
if (readLockedFile (mPendingFile, lines))
|
||||
{
|
||||
int id = 1;
|
||||
|
||||
std::vector <std::string>::iterator it;
|
||||
for (it = lines.begin (); it != lines.end (); ++it)
|
||||
{
|
||||
T t (*it);
|
||||
t.setId (id++);
|
||||
all.push_back (t);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
bool TDB::completedT (std::vector <T>& all) const
|
||||
{
|
||||
all.clear ();
|
||||
|
||||
std::vector <std::string> lines;
|
||||
if (readLockedFile (mCompletedFile, lines))
|
||||
{
|
||||
std::vector <std::string>::iterator it;
|
||||
for (it = lines.begin (); it != lines.end (); ++it)
|
||||
{
|
||||
T t (*it);
|
||||
if (t.getStatus () != T::deleted)
|
||||
all.push_back (t);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
bool TDB::allCompletedT (std::vector <T>& all) const
|
||||
{
|
||||
all.clear ();
|
||||
|
||||
std::vector <std::string> lines;
|
||||
if (readLockedFile (mCompletedFile, lines))
|
||||
{
|
||||
std::vector <std::string>::iterator it;
|
||||
for (it = lines.begin (); it != lines.end (); ++it)
|
||||
{
|
||||
T t (*it);
|
||||
all.push_back (t);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
bool TDB::deleteT (const T& t) const
|
||||
{
|
||||
T task (t);
|
||||
|
||||
std::vector <T> all;
|
||||
allPendingT (all);
|
||||
|
||||
std::vector <T>::iterator it;
|
||||
for (it = all.begin (); it != all.end (); ++it)
|
||||
if (task.getId () == it->getId ())
|
||||
{
|
||||
it->setStatus (T::deleted);
|
||||
|
||||
char endTime[16];
|
||||
sprintf (endTime, "%u", (unsigned int) time (NULL));
|
||||
it->setAttribute ("end", endTime);
|
||||
|
||||
return overwritePending (all);
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
bool TDB::completeT (const T& t) const
|
||||
{
|
||||
T task (t);
|
||||
|
||||
std::vector <T> all;
|
||||
allPendingT (all);
|
||||
|
||||
std::vector <T>::iterator it;
|
||||
for (it = all.begin (); it != all.end (); ++it)
|
||||
if (task.getId () == it->getId ())
|
||||
{
|
||||
it->setStatus (T::completed);
|
||||
|
||||
char endTime[16];
|
||||
sprintf (endTime, "%u", (unsigned int) time (NULL));
|
||||
it->setAttribute ("end", endTime);
|
||||
|
||||
return overwritePending (all);
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
bool TDB::addT (const T& t) const
|
||||
{
|
||||
T task (t);
|
||||
|
||||
std::vector <std::string> tags;
|
||||
task.getTags (tags);
|
||||
|
||||
// TODO This logic smells funny.
|
||||
// +tag or -tag are both considered valid tags to add to a new pending task.
|
||||
// Generating an error here would not be friendly.
|
||||
for (unsigned int i = 0; i < tags.size (); ++i)
|
||||
{
|
||||
if (tags[i][0] == '-' || tags[i][0] == '+')
|
||||
{
|
||||
task.removeTag (tags[i]);
|
||||
task.addTag (tags[i].substr (1, std::string::npos));
|
||||
}
|
||||
}
|
||||
|
||||
if (task.getStatus () == T::pending)
|
||||
return writePending (task);
|
||||
|
||||
return writeCompleted (task);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
bool TDB::modifyT (const T& t) const
|
||||
{
|
||||
T modified (t);
|
||||
|
||||
std::vector <T> all;
|
||||
allPendingT (all);
|
||||
|
||||
std::vector <T> pending;
|
||||
|
||||
std::vector <T>::iterator it;
|
||||
for (it = all.begin (); it != all.end (); ++it)
|
||||
{
|
||||
if (it->getId () == t.getId ())
|
||||
{
|
||||
modified.setUUID (it->getUUID ());
|
||||
pending.push_back (modified);
|
||||
}
|
||||
else
|
||||
pending.push_back (*it);
|
||||
}
|
||||
|
||||
return overwritePending (pending);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
bool TDB::logRead (std::vector <std::string>& entries) const
|
||||
{
|
||||
entries.clear ();
|
||||
return readLockedFile (mLogFile, entries);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
bool TDB::logCommand (int argc, char** argv) const
|
||||
{
|
||||
// Get time info.
|
||||
time_t now;
|
||||
time (&now);
|
||||
struct tm* t = localtime (&now);
|
||||
|
||||
// Generate timestamp.
|
||||
char timestamp[20];
|
||||
sprintf (timestamp, "%04d-%02d-%02d %02d:%02d:%02d",
|
||||
t->tm_year + 1900,
|
||||
t->tm_mon + 1,
|
||||
t->tm_mday,
|
||||
t->tm_hour,
|
||||
t->tm_min,
|
||||
t->tm_sec);
|
||||
|
||||
std::string command = timestamp;
|
||||
command += " \"";
|
||||
for (int i = 0; i < argc; ++i)
|
||||
command += std::string (i ? " " : "") + argv[i];
|
||||
command += "\"\n";
|
||||
|
||||
if (! access (mLogFile.c_str (), F_OK | W_OK))
|
||||
{
|
||||
FILE* out;
|
||||
if ((out = fopen (mLogFile.c_str (), "a")))
|
||||
{
|
||||
#ifdef HAVE_FLOCK
|
||||
int retry = 0;
|
||||
while (flock (fileno (out), LOCK_EX) && ++retry <= 3)
|
||||
delay (0.25);
|
||||
#endif
|
||||
|
||||
fprintf (out, command.c_str ());
|
||||
|
||||
fclose (out);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
bool TDB::lock (FILE* file) const
|
||||
{
|
||||
#ifdef HAVE_FLOCK
|
||||
return flock (fileno (file), LOCK_EX) ? false : true;
|
||||
#else
|
||||
return true;
|
||||
#endif
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
bool TDB::overwritePending (std::vector <T>& all) const
|
||||
{
|
||||
// Write a single task to the pending file
|
||||
FILE* out;
|
||||
if ((out = fopen (mPendingFile.c_str (), "w")))
|
||||
{
|
||||
#ifdef HAVE_FLOCK
|
||||
int retry = 0;
|
||||
while (flock (fileno (out), LOCK_EX) && ++retry <= 3)
|
||||
delay (0.25);
|
||||
#endif
|
||||
|
||||
std::vector <T>::iterator it;
|
||||
for (it = all.begin (); it != all.end (); ++it)
|
||||
fprintf (out, it->compose ().c_str ());
|
||||
|
||||
fclose (out);
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
bool TDB::writePending (const T& t) const
|
||||
{
|
||||
// Write a single task to the pending file
|
||||
FILE* out;
|
||||
if ((out = fopen (mPendingFile.c_str (), "a")))
|
||||
{
|
||||
#ifdef HAVE_FLOCK
|
||||
int retry = 0;
|
||||
while (flock (fileno (out), LOCK_EX) && ++retry <= 3)
|
||||
delay (0.25);
|
||||
#endif
|
||||
|
||||
fprintf (out, t.compose ().c_str ());
|
||||
|
||||
fclose (out);
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
bool TDB::writeCompleted (const T& t) const
|
||||
{
|
||||
// Write a single task to the pending file
|
||||
FILE* out;
|
||||
if ((out = fopen (mCompletedFile.c_str (), "a")))
|
||||
{
|
||||
#ifdef HAVE_FLOCK
|
||||
int retry = 0;
|
||||
while (flock (fileno (out), LOCK_EX) && ++retry <= 3)
|
||||
delay (0.25);
|
||||
#endif
|
||||
|
||||
fprintf (out, t.compose ().c_str ());
|
||||
|
||||
fclose (out);
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
bool TDB::readLockedFile (
|
||||
const std::string& file,
|
||||
std::vector <std::string>& contents) const
|
||||
{
|
||||
contents.clear ();
|
||||
|
||||
if (! access (file.c_str (), F_OK | R_OK))
|
||||
{
|
||||
FILE* in;
|
||||
if ((in = fopen (file.c_str (), "r")))
|
||||
{
|
||||
#ifdef HAVE_FLOCK
|
||||
int retry = 0;
|
||||
while (flock (fileno (in), LOCK_EX) && ++retry <= 3)
|
||||
delay (0.25);
|
||||
#endif
|
||||
|
||||
char line[T_LINE_MAX];
|
||||
while (fgets (line, T_LINE_MAX, in))
|
||||
{
|
||||
int length = ::strlen (line);
|
||||
if (length > 1)
|
||||
{
|
||||
line[length - 1] = '\0'; // Kill \n
|
||||
contents.push_back (line);
|
||||
}
|
||||
}
|
||||
|
||||
fclose (in);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
int TDB::gc () const
|
||||
{
|
||||
int count = 0;
|
||||
|
||||
// Read everything from the pending file.
|
||||
std::vector <T> all;
|
||||
allPendingT (all);
|
||||
|
||||
// A list of the truly pending tasks.
|
||||
std::vector <T> pending;
|
||||
|
||||
std::vector<T>::iterator it;
|
||||
for (it = all.begin (); it != all.end (); ++it)
|
||||
{
|
||||
// Some tasks stay in the pending file.
|
||||
if (it->getStatus () == T::pending)
|
||||
pending.push_back (*it);
|
||||
|
||||
// Others are transferred to the completed file.
|
||||
else
|
||||
{
|
||||
writeCompleted (*it);
|
||||
++count;
|
||||
}
|
||||
}
|
||||
|
||||
// Dump all clean tasks into pending.
|
||||
overwritePending (pending);
|
||||
return count;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
47
src/TDB.h
Normal file
47
src/TDB.h
Normal file
|
@ -0,0 +1,47 @@
|
|||
////////////////////////////////////////////////////////////////////////////////
|
||||
// Copyright 2007, 2008, Paul Beckingham. All rights reserved.
|
||||
//
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
#ifndef INCLUDED_TDB
|
||||
#define INCLUDED_TDB
|
||||
|
||||
#include <vector>
|
||||
#include <string>
|
||||
#include "T.h"
|
||||
|
||||
class TDB
|
||||
{
|
||||
public:
|
||||
TDB ();
|
||||
~TDB ();
|
||||
|
||||
void dataDirectory (const std::string&);
|
||||
bool allT (std::vector <T>&) const;
|
||||
bool pendingT (std::vector <T>&) const;
|
||||
bool allPendingT (std::vector <T>&) const;
|
||||
bool completedT (std::vector <T>&) const;
|
||||
bool allCompletedT (std::vector <T>&) const;
|
||||
bool deleteT (const T&) const;
|
||||
bool completeT (const T&) const;
|
||||
bool addT (const T&) const;
|
||||
bool modifyT (const T&) const;
|
||||
bool logRead (std::vector <std::string>&) const;
|
||||
bool logCommand (int, char**) const;
|
||||
int gc () const;
|
||||
|
||||
private:
|
||||
bool lock (FILE*) const;
|
||||
bool overwritePending (std::vector <T>&) const;
|
||||
bool writePending (const T&) const;
|
||||
bool writeCompleted (const T&) const;
|
||||
bool readLockedFile (const std::string&, std::vector <std::string>&) const;
|
||||
|
||||
private:
|
||||
std::string mPendingFile;
|
||||
std::string mCompletedFile;
|
||||
std::string mLogFile;
|
||||
};
|
||||
|
||||
#endif
|
||||
////////////////////////////////////////////////////////////////////////////////
|
1064
src/Table.cpp
Normal file
1064
src/Table.cpp
Normal file
File diff suppressed because it is too large
Load diff
115
src/Table.h
Normal file
115
src/Table.h
Normal file
|
@ -0,0 +1,115 @@
|
|||
////////////////////////////////////////////////////////////////////////////////
|
||||
// Copyright 2006 - 2008, Paul Beckingham.
|
||||
// All rights reserved.
|
||||
//
|
||||
// TODO Implement height
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
#ifndef INCLUDED_TABLE
|
||||
#define INCLUDED_TABLE
|
||||
|
||||
#include <map>
|
||||
#include <vector>
|
||||
#include <string>
|
||||
#include "color.h"
|
||||
|
||||
class Table
|
||||
{
|
||||
public:
|
||||
enum just {left, center, right};
|
||||
enum order {ascendingNumeric, ascendingCharacter, ascendingPriority,
|
||||
ascendingDate, descendingNumeric, descendingCharacter,
|
||||
descendingPriority, descendingDate};
|
||||
enum sizing {minimum = -1, flexible = 0};
|
||||
|
||||
Table ();
|
||||
virtual ~Table ();
|
||||
|
||||
void setTableColor (Text::color, Text::color);
|
||||
void setTableFg (Text::color);
|
||||
void setTableBg (Text::color);
|
||||
void setTablePadding (int);
|
||||
void setTableIntraPadding (int);
|
||||
void setTableWidth (int);
|
||||
|
||||
int addColumn (const std::string&);
|
||||
void setColumnColor (int, Text::color, Text::color);
|
||||
void setColumnFg (int, Text::color);
|
||||
void setColumnBg (int, Text::color);
|
||||
void setColumnUnderline (int);
|
||||
void setColumnPadding (int, int);
|
||||
void setColumnWidth (int, int);
|
||||
void setColumnWidth (int, sizing);
|
||||
void setColumnJustification (int, just);
|
||||
void setColumnCommify (int);
|
||||
void sortOn (int, order);
|
||||
|
||||
int addRow ();
|
||||
void setRowColor (int, Text::color, Text::color);
|
||||
void setRowFg (int, Text::color);
|
||||
void setRowBg (int, Text::color);
|
||||
|
||||
void addCell (int, int, const std::string&);
|
||||
void addCell (int, int, char);
|
||||
void addCell (int, int, int);
|
||||
void addCell (int, int, float);
|
||||
void addCell (int, int, double);
|
||||
void setCellColor (int, int, Text::color, Text::color);
|
||||
void setCellFg (int, int, Text::color);
|
||||
void setCellBg (int, int, Text::color);
|
||||
|
||||
void suppressWS ();
|
||||
|
||||
int rowCount ();
|
||||
int columnCount ();
|
||||
const std::string render ();
|
||||
|
||||
private:
|
||||
std::string getCell (int, int);
|
||||
Text::color getFg (int, int);
|
||||
Text::color getHeaderFg (int);
|
||||
Text::color getBg (int, int);
|
||||
Text::color getHeaderBg (int);
|
||||
Text::attr getHeaderUnderline (int);
|
||||
int getPadding (int);
|
||||
int getIntraPadding ();
|
||||
void calculateColumnWidths ();
|
||||
just getJustification (int, int);
|
||||
just getHeaderJustification (int);
|
||||
const std::string formatHeader (int, int, int);
|
||||
const std::string formatCell (int, int, int, int);
|
||||
void formatCell (int, int, int, int, std::vector <std::string>&, std::string&);
|
||||
void optimize (std::string&);
|
||||
void sort (std::vector <int>&);
|
||||
void clean (std::string&);
|
||||
|
||||
private:
|
||||
std::vector <std::string> mColumns;
|
||||
int mRows;
|
||||
int mIntraPadding;
|
||||
std::map <std::string, Text::color> mFg;
|
||||
std::map <std::string, Text::color> mBg;
|
||||
std::map <std::string, Text::attr> mUnderline;
|
||||
|
||||
// Padding...
|
||||
int mTablePadding;
|
||||
std::vector <int> mColumnPadding;
|
||||
|
||||
// Width...
|
||||
int mTableWidth;
|
||||
std::vector <int> mSpecifiedWidth;
|
||||
std::vector <int> mMaxDataWidth;
|
||||
std::vector <int> mCalculatedWidth;
|
||||
|
||||
std::map <std::string, just> mJustification;
|
||||
std::map <int, bool> mCommify;
|
||||
std::map <std::string, std::string> mData;
|
||||
std::vector <int> mSortColumns;
|
||||
std::map <int, order> mSortOrder;
|
||||
|
||||
// Misc...
|
||||
bool mSuppressWS;
|
||||
};
|
||||
|
||||
#endif
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
64
src/color.cpp
Normal file
64
src/color.cpp
Normal file
|
@ -0,0 +1,64 @@
|
|||
////////////////////////////////////////////////////////////////////////////////
|
||||
// Copyright 2008, Paul Beckingham. All rights reserved.
|
||||
//
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
#include <string>
|
||||
#include "color.h"
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
std::string Text::colorName (Text::color c)
|
||||
{
|
||||
switch (c)
|
||||
{
|
||||
case black: return "black";
|
||||
case red: return "red";
|
||||
case green: return "green";
|
||||
case yellow: return "yellow";
|
||||
case blue: return "blue";
|
||||
case magenta: return "magenta";
|
||||
case cyan: return "cyan";
|
||||
case white: return "white";
|
||||
case nocolor: return "";
|
||||
}
|
||||
|
||||
return "";
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
Text::color Text::colorCode (const std::string& c)
|
||||
{
|
||||
if (c == "black") return black;
|
||||
if (c == "red") return red;
|
||||
if (c == "green") return green;
|
||||
if (c == "yellow") return yellow;
|
||||
if (c == "blue") return blue;
|
||||
if (c == "magenta") return magenta;
|
||||
if (c == "cyan") return cyan;
|
||||
if (c == "white") return white;
|
||||
|
||||
return nocolor;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
std::string Text::attrName (Text::attr a)
|
||||
{
|
||||
switch (a)
|
||||
{
|
||||
case underline: return "underline";
|
||||
case normal: return "";
|
||||
}
|
||||
|
||||
return "";
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
Text::attr Text::attrCode (const std::string& a)
|
||||
{
|
||||
if (a == "underline") return underline;
|
||||
|
||||
return normal;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
23
src/color.h
Normal file
23
src/color.h
Normal file
|
@ -0,0 +1,23 @@
|
|||
////////////////////////////////////////////////////////////////////////////////
|
||||
// Copyright 2008, Paul Beckingham.
|
||||
// All rights reserved.
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
#ifndef INCLUDED_COLOR
|
||||
#define INCLUDED_COLOR
|
||||
|
||||
namespace Text
|
||||
{
|
||||
enum color {nocolor = 0, black, red, green, yellow, blue, magenta, cyan, white};
|
||||
enum attr {normal = 0, underline};
|
||||
|
||||
std::string colorName (Text::color);
|
||||
Text::color colorCode (const std::string&);
|
||||
|
||||
std::string attrName (Text::attr);
|
||||
Text::attr attrCode (const std::string&);
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
49
src/library.h
Normal file
49
src/library.h
Normal file
|
@ -0,0 +1,49 @@
|
|||
////////////////////////////////////////////////////////////////////////////////
|
||||
// Copyright 2004 - 2008, Paul Beckingham. All rights reserved.
|
||||
//
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
#ifndef INCLUDED_LIBRARY
|
||||
#define INCLUDED_LIBRARY
|
||||
|
||||
#include <string>
|
||||
#include <vector>
|
||||
#include <sys/types.h>
|
||||
|
||||
#include "stlmacros.h"
|
||||
|
||||
#ifndef max
|
||||
#define max(a,b) ((a) > (b) ? (a) : (b))
|
||||
#endif
|
||||
|
||||
// text.cpp
|
||||
void wrapText (std::vector <std::string>&, const std::string&, const int);
|
||||
std::string trimLeft (const std::string& in, const std::string& t = " ");
|
||||
std::string trimRight (const std::string& in, const std::string& t = " ");
|
||||
std::string trim (const std::string& in, const std::string& t = " ");
|
||||
std::wstring trimLeft (const std::wstring& in, const std::wstring& t = L" "); // UNICODE safe
|
||||
std::wstring trimRight (const std::wstring& in, const std::wstring& t = L" "); // UNICODE safe
|
||||
std::wstring trim (const std::wstring& in, const std::wstring& t = L" "); // UNICODE safe
|
||||
void extractParagraphs (const std::string&, std::vector<std::string>&);
|
||||
void extractLine (std::string&, std::string&, int);
|
||||
void split (std::vector<std::string>&, const std::string&, const char);
|
||||
void split (std::vector<std::string>&, const std::string&, const std::string&);
|
||||
void join (std::string&, const std::string&, const std::vector<std::string>&);
|
||||
std::string commify (const std::string&);
|
||||
std::string lowerCase (const std::string&);
|
||||
|
||||
// misc.cpp
|
||||
void delay (float);
|
||||
|
||||
// list.cpp
|
||||
int autoComplete (const std::string&, const std::vector<std::string>&, std::vector<std::string>&);
|
||||
|
||||
// units.cpp
|
||||
void formatTimeDeltaDays (std::string&, time_t);
|
||||
std::string formatSeconds (time_t);
|
||||
|
||||
// uuid.cpp
|
||||
const std::string uuid ();
|
||||
|
||||
#endif
|
||||
////////////////////////////////////////////////////////////////////////////////
|
329
src/parse.cpp
Normal file
329
src/parse.cpp
Normal file
|
@ -0,0 +1,329 @@
|
|||
////////////////////////////////////////////////////////////////////////////////
|
||||
// Copyright 2006 - 2008, Paul Beckingham. All rights reserved.
|
||||
//
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
#include <iostream>
|
||||
#include <string>
|
||||
#include <vector>
|
||||
#include <map>
|
||||
|
||||
#include "Date.h"
|
||||
#include "task.h"
|
||||
#include "T.h"
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
static char* colors[] =
|
||||
{
|
||||
"black",
|
||||
"blue",
|
||||
"red",
|
||||
"green",
|
||||
"magenta",
|
||||
"cyan",
|
||||
"yellow",
|
||||
"white",
|
||||
"",
|
||||
};
|
||||
|
||||
static char* attributes[] =
|
||||
{
|
||||
"project",
|
||||
"priority",
|
||||
"fg",
|
||||
"bg",
|
||||
"due",
|
||||
"entry",
|
||||
"start",
|
||||
"end",
|
||||
"",
|
||||
};
|
||||
|
||||
static char* commands[] =
|
||||
{
|
||||
"active",
|
||||
"add",
|
||||
"calendar",
|
||||
"completed",
|
||||
"delete",
|
||||
"done",
|
||||
"export",
|
||||
"history",
|
||||
"info",
|
||||
"list",
|
||||
"long",
|
||||
"ls",
|
||||
"next",
|
||||
"overdue",
|
||||
"projects",
|
||||
"start",
|
||||
"stats",
|
||||
"summary",
|
||||
"tags",
|
||||
"usage",
|
||||
"version",
|
||||
"",
|
||||
};
|
||||
|
||||
void guess (const std::string& type, char** list, std::string& candidate)
|
||||
{
|
||||
std::vector <std::string> options;
|
||||
for (int i = 0; list[i][0]; ++i)
|
||||
options.push_back (list[i]);
|
||||
|
||||
std::vector <std::string> matches;
|
||||
autoComplete (candidate, options, matches);
|
||||
if (1 == matches.size ())
|
||||
candidate = matches[0];
|
||||
|
||||
else if (0 == matches.size ())
|
||||
throw std::string ("Unrecognized ") + type + " '" + candidate + "'";
|
||||
|
||||
else
|
||||
{
|
||||
std::string error = "Ambiguous ";
|
||||
error += type;
|
||||
error += " '";
|
||||
error += candidate;
|
||||
error += "' - could be either of ";
|
||||
for (unsigned int i = 0; i < matches.size (); ++i)
|
||||
{
|
||||
if (i)
|
||||
error += ", ";
|
||||
error += matches[i];
|
||||
}
|
||||
|
||||
throw error;
|
||||
}
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
static bool isCommand (const std::string& candidate)
|
||||
{
|
||||
std::vector <std::string> options;
|
||||
for (int i = 0; commands[i][0]; ++i)
|
||||
options.push_back (commands[i]);
|
||||
|
||||
std::vector <std::string> matches;
|
||||
autoComplete (candidate, options, matches);
|
||||
if (0 == matches.size ())
|
||||
return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
bool validDate (std::string& date)
|
||||
{
|
||||
unsigned int firstSlash = date.find ("/");
|
||||
unsigned int secondSlash = date.find ("/", firstSlash + 1);
|
||||
if (firstSlash != std::string::npos &&
|
||||
secondSlash != std::string::npos)
|
||||
{
|
||||
int m = ::atoi (date.substr (0, firstSlash ).c_str ());
|
||||
int d = ::atoi (date.substr (firstSlash + 1, secondSlash - firstSlash).c_str ());
|
||||
int y = ::atoi (date.substr (secondSlash + 1, std::string::npos ).c_str ());
|
||||
if (!Date::valid (m, d, y))
|
||||
throw std::string ("\"") + date + "\" is not a valid date.";
|
||||
|
||||
// Convert to epoch form.
|
||||
Date dt (m, d, y);
|
||||
time_t t;
|
||||
dt.toEpoch (t);
|
||||
char converted[12];
|
||||
sprintf (converted, "%u", (unsigned int) t);
|
||||
date = converted;
|
||||
}
|
||||
else
|
||||
throw std::string ("Badly formed date - use the MM/DD/YYYY format");
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
static bool validPriority (std::string& input)
|
||||
{
|
||||
if (input != "H" &&
|
||||
input != "M" &&
|
||||
input != "L" &&
|
||||
input != "")
|
||||
throw std::string ("\"") +
|
||||
input +
|
||||
"\" is not a valid priority. Use H, M, L or leave blank.";
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
static bool validAttribute (std::string& name, std::string& value)
|
||||
{
|
||||
guess ("attribute", attributes, name);
|
||||
|
||||
if ((name == "fg" || name == "bg") && value != "")
|
||||
guess ("color", colors, value);
|
||||
|
||||
else if (name == "due" && value != "")
|
||||
validDate (value);
|
||||
|
||||
else if (name == "priority")
|
||||
{
|
||||
for (std::string::iterator i = value.begin (); i != value.end (); ++i)
|
||||
*i = ::toupper (*i);
|
||||
|
||||
return validPriority (value);
|
||||
}
|
||||
|
||||
else if (name == "entry" ||
|
||||
name == "start" ||
|
||||
name == "end")
|
||||
throw std::string ("\"") +
|
||||
name +
|
||||
"\" is not an attribute you may modify directly.";
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
static bool validId (const std::string& input)
|
||||
{
|
||||
for (unsigned int i = 0; i < input.length (); ++i)
|
||||
if (!::isdigit (input[i]))
|
||||
return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
static bool validTag (std::string& input)
|
||||
{
|
||||
if ((input[0] == '-' || input[0] == '+') &&
|
||||
input.length () > 1)
|
||||
return true;
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
static bool validDescription (const std::string& input)
|
||||
{
|
||||
if (input.length () > 0)
|
||||
return true;
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
static bool validCommand (std::string& input)
|
||||
{
|
||||
guess ("command", commands, input);
|
||||
return true;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
static bool validSubstitution (
|
||||
std::string& input,
|
||||
std::string& from,
|
||||
std::string& to)
|
||||
{
|
||||
unsigned int first = input.find ('/');
|
||||
if (first != std::string::npos)
|
||||
{
|
||||
unsigned int second = input.find ('/', first + 1);
|
||||
if (second != std::string::npos)
|
||||
{
|
||||
unsigned int third = input.find ('/', second + 1);
|
||||
if (third != std::string::npos)
|
||||
{
|
||||
if (first == 0 &&
|
||||
first < second &&
|
||||
second < third &&
|
||||
third == input.length () - 1)
|
||||
{
|
||||
from = input.substr (first + 1, second - first - 1);
|
||||
to = input.substr (second + 1, third - second - 1);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
// Token Distinguishing characteristic
|
||||
// ------- -----------------------------
|
||||
// command first positional
|
||||
// id \d+
|
||||
// description default, accumulate
|
||||
// substitution /\w+/\w*/
|
||||
// tags [-+]\w+
|
||||
// attributes \w+:.+
|
||||
//
|
||||
void parse (
|
||||
std::vector <std::string>& args,
|
||||
std::string& command,
|
||||
T& task)
|
||||
{
|
||||
command = "";
|
||||
|
||||
std::string descCandidate = "";
|
||||
for (unsigned int i = 0; i < args.size (); ++i)
|
||||
{
|
||||
std::string arg (args[i]);
|
||||
unsigned int colon; // Pointer to colon in argument.
|
||||
std::string from;
|
||||
std::string to;
|
||||
|
||||
// An id is the first argument found that contains all digits.
|
||||
if (command != "add" && // "add" doesn't require an ID
|
||||
task.getId () == 0 &&
|
||||
validId (arg))
|
||||
task.setId (::atoi (arg.c_str ()));
|
||||
|
||||
// Tags begin with + or - and contain arbitrary text.
|
||||
else if (validTag (arg))
|
||||
{
|
||||
if (arg[0] == '+')
|
||||
task.addTag (arg.substr (1, std::string::npos));
|
||||
else if (arg[0] == '-')
|
||||
task.addRemoveTag (arg.substr (1, std::string::npos));
|
||||
}
|
||||
|
||||
// Attributes contain a constant string followed by a colon, followed by a
|
||||
// value.
|
||||
else if ((colon = arg.find (":")) != std::string::npos)
|
||||
{
|
||||
std::string name = arg.substr (0, colon);
|
||||
std::string value = arg.substr (colon + 1, std::string::npos);
|
||||
|
||||
if (validAttribute (name, value))
|
||||
task.setAttribute (name, value);
|
||||
}
|
||||
|
||||
// Substitution of description text.
|
||||
else if (validSubstitution (arg, from, to))
|
||||
{
|
||||
task.setSubstitution (from, to);
|
||||
}
|
||||
|
||||
// Command.
|
||||
else if (command == "")
|
||||
{
|
||||
if (!isCommand (arg))
|
||||
descCandidate += std::string (arg) + " ";
|
||||
else if (validCommand (arg))
|
||||
command = arg;
|
||||
}
|
||||
|
||||
// Anything else is just considered description.
|
||||
else
|
||||
descCandidate += std::string (arg) + " ";
|
||||
}
|
||||
|
||||
if (validDescription (descCandidate))
|
||||
task.setDescription (descCandidate);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
182
src/rules.cpp
Normal file
182
src/rules.cpp
Normal file
|
@ -0,0 +1,182 @@
|
|||
////////////////////////////////////////////////////////////////////////////////
|
||||
// Copyright 2006 - 2008, Paul Beckingham. All rights reserved.
|
||||
//
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
#include <iostream>
|
||||
#include "Config.h"
|
||||
#include "Table.h"
|
||||
#include "Date.h"
|
||||
#include "T.h"
|
||||
#include "task.h"
|
||||
|
||||
static std::map <std::string, Text::color> gsFg;
|
||||
static std::map <std::string, Text::color> gsBg;
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
// There are three supported variants:
|
||||
// 1) "fg"
|
||||
// 2) "on bg"
|
||||
// 3) "fg on bg"
|
||||
static void parseColorRule (
|
||||
const std::string& rule,
|
||||
Text::color& fg,
|
||||
Text::color& bg)
|
||||
{
|
||||
fg = Text::nocolor;
|
||||
bg = Text::nocolor;
|
||||
bool error = false;
|
||||
|
||||
std::vector <std::string> words;
|
||||
split (words, rule, ' ');
|
||||
switch (words.size ())
|
||||
{
|
||||
case 1: // "fg" - no spaces.
|
||||
fg = Text::colorCode (words[0]);
|
||||
break;
|
||||
|
||||
case 2: // "on bg" - one space, "on" before.
|
||||
if (words[0] == "on")
|
||||
bg = Text::colorCode (words[1]);
|
||||
else
|
||||
error = true;
|
||||
break;
|
||||
|
||||
case 3: // "fg on bg" - two spaces, "on" between them.
|
||||
if (words[1] == "on")
|
||||
{
|
||||
fg = Text::colorCode (words[0]);
|
||||
bg = Text::colorCode (words[2]);
|
||||
}
|
||||
else
|
||||
error = true;
|
||||
break;
|
||||
|
||||
case 0:
|
||||
default:
|
||||
error = true;
|
||||
break;
|
||||
}
|
||||
|
||||
if (error)
|
||||
std::cout << "Malformed color rule '" << rule << "'" << std::endl;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
void initializeColorRules (Config& conf)
|
||||
{
|
||||
std::vector <std::string> ruleNames;
|
||||
conf.all (ruleNames);
|
||||
foreach (it, ruleNames)
|
||||
{
|
||||
if (it->substr (0, 6) == "color.")
|
||||
{
|
||||
Text::color fg;
|
||||
Text::color bg;
|
||||
parseColorRule (conf.get (*it), fg, bg);
|
||||
gsFg[*it] = fg;
|
||||
gsBg[*it] = bg;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
void autoColorize (T& task, Text::color& fg, Text::color& bg)
|
||||
{
|
||||
fg = Text::nocolor;
|
||||
bg = Text::nocolor;
|
||||
|
||||
// Colorization of the tagged.
|
||||
if (gsFg["color.tagged"] != Text::nocolor ||
|
||||
gsBg["color.tagged"] != Text::nocolor)
|
||||
{
|
||||
std::vector <std::string> tags;
|
||||
task.getTags (tags);
|
||||
if (tags.size ())
|
||||
{
|
||||
fg = gsFg["color.tagged"];
|
||||
bg = gsBg["color.tagged"];
|
||||
}
|
||||
}
|
||||
|
||||
// Colorization of the low priority.
|
||||
if (gsFg["color.pri.L"] != Text::nocolor ||
|
||||
gsBg["color.pri.L"] != Text::nocolor)
|
||||
{
|
||||
if (task.getAttribute ("priority") == "L")
|
||||
{
|
||||
fg = gsFg["color.pri.L"];
|
||||
bg = gsBg["color.pri.L"];
|
||||
}
|
||||
}
|
||||
|
||||
// Colorization of the medium priority.
|
||||
if (gsFg["color.pri.M"] != Text::nocolor ||
|
||||
gsBg["color.pri.M"] != Text::nocolor)
|
||||
{
|
||||
if (task.getAttribute ("priority") == "M")
|
||||
{
|
||||
fg = gsFg["color.pri.M"];
|
||||
bg = gsBg["color.pri.M"];
|
||||
}
|
||||
}
|
||||
|
||||
// Colorization of the high priority.
|
||||
if (gsFg["color.pri.H"] != Text::nocolor ||
|
||||
gsBg["color.pri.H"] != Text::nocolor)
|
||||
{
|
||||
if (task.getAttribute ("priority") == "H")
|
||||
{
|
||||
fg = gsFg["color.pri.H"];
|
||||
bg = gsBg["color.pri.H"];
|
||||
}
|
||||
}
|
||||
|
||||
// Colorization of the priority-less.
|
||||
if (gsFg["color.pri.none"] != Text::nocolor ||
|
||||
gsBg["color.pri.none"] != Text::nocolor)
|
||||
{
|
||||
if (task.getAttribute ("priority") == "")
|
||||
{
|
||||
fg = gsFg["color.pri.none"];
|
||||
bg = gsBg["color.pri.none"];
|
||||
}
|
||||
}
|
||||
|
||||
// Colorization of the active.
|
||||
if (gsFg["color.active"] != Text::nocolor ||
|
||||
gsBg["color.active"] != Text::nocolor)
|
||||
{
|
||||
if (task.getAttribute ("start") != "")
|
||||
{
|
||||
fg = gsFg["color.active"];
|
||||
bg = gsBg["color.active"];
|
||||
}
|
||||
}
|
||||
|
||||
// Colorization of the due and overdue.
|
||||
std::string due = task.getAttribute ("due");
|
||||
if (due != "")
|
||||
{
|
||||
Date dueDate (::atoi (due.c_str ()));
|
||||
Date now;
|
||||
Date then (now + 7 * 86400);
|
||||
|
||||
// Overdue
|
||||
if (dueDate < now)
|
||||
{
|
||||
fg = gsFg["color.overdue"];
|
||||
bg = gsBg["color.overdue"];
|
||||
}
|
||||
|
||||
// Imminent
|
||||
else if (dueDate < then)
|
||||
{
|
||||
fg = gsFg["color.due"];
|
||||
bg = gsBg["color.due"];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
18
src/stlmacros.h
Normal file
18
src/stlmacros.h
Normal file
|
@ -0,0 +1,18 @@
|
|||
////////////////////////////////////////////////////////////////////////////////
|
||||
// Copyright 2006 - 2008, Paul Beckingham. All rights reserved.
|
||||
//
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
#ifndef INCLUDED_STLMACROS
|
||||
#define INCLUDED_STLMACROS
|
||||
|
||||
#define foreach(i, c) \
|
||||
for (typeof (c) *foreach_p = & (c); \
|
||||
foreach_p; \
|
||||
foreach_p = 0) \
|
||||
for (typeof (foreach_p->begin()) i = foreach_p->begin(); \
|
||||
i != foreach_p->end(); \
|
||||
++i)
|
||||
|
||||
#endif
|
||||
////////////////////////////////////////////////////////////////////////////////
|
2682
src/task.cpp
Normal file
2682
src/task.cpp
Normal file
File diff suppressed because it is too large
Load diff
79
src/task.h
Normal file
79
src/task.h
Normal file
|
@ -0,0 +1,79 @@
|
|||
////////////////////////////////////////////////////////////////////////////////
|
||||
// Copyright 2006 - 2008, Paul Beckingham. All rights reserved.
|
||||
//
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#include <string>
|
||||
#include <vector>
|
||||
#include <map>
|
||||
#include <sys/types.h>
|
||||
#include "Config.h"
|
||||
#include "Table.h"
|
||||
#include "color.h"
|
||||
#include "TDB.h"
|
||||
#include "T.h"
|
||||
#include "stlmacros.h"
|
||||
#include "../auto.h"
|
||||
|
||||
#ifndef max
|
||||
#define max(a,b) ((a) > (b) ? (a) : (b))
|
||||
#endif
|
||||
|
||||
// parse.cpp
|
||||
void parse (std::vector <std::string>&, std::string&, T&);
|
||||
bool validDate (std::string&);
|
||||
|
||||
// task.cpp
|
||||
void handleAdd (const TDB&, T&, Config&);
|
||||
void handleProjects (const TDB&, T&, Config&);
|
||||
void handleTags (const TDB&, T&, Config&);
|
||||
void handleList (const TDB&, T&, Config&);
|
||||
void handleInfo (const TDB&, T&, Config&);
|
||||
void handleLongList (const TDB&, T&, Config&);
|
||||
void handleSmallList (const TDB&, T&, Config&);
|
||||
void handleCompleted (const TDB&, T&, Config&);
|
||||
void handleReportSummary (const TDB&, T&, Config&);
|
||||
void handleReportNext (const TDB&, T&, Config&);
|
||||
void handleReportHistory (const TDB&, T&, Config&);
|
||||
void handleReportUsage (const TDB&, T&, Config&);
|
||||
void handleReportCalendar (const TDB&, T&, Config&);
|
||||
void handleReportActive (const TDB&, T&, Config&);
|
||||
void handleReportOverdue (const TDB&, T&, Config&);
|
||||
void handleReportStats (const TDB&, T&, Config&);
|
||||
void handleVersion (Config&);
|
||||
void handleExport (const TDB&, T&, Config&);
|
||||
void handleDelete (const TDB&, T&, Config&);
|
||||
void handleStart (const TDB&, T&, Config&);
|
||||
void handleDone (const TDB&, T&, Config&);
|
||||
void handleModify (const TDB&, T&, Config&);
|
||||
void gatherNextTasks (const TDB&, T&, Config&, std::vector <T>&, std::vector <int>&);
|
||||
void nag (const TDB&, T&, Config&);
|
||||
|
||||
// util.cpp
|
||||
bool confirm (const std::string&);
|
||||
void wrapText (std::vector <std::string>&, const std::string&, const int);
|
||||
std::string trimLeft (const std::string& in, const std::string& t = " ");
|
||||
std::string trimRight (const std::string& in, const std::string& t = " ");
|
||||
std::string trim (const std::string& in, const std::string& t = " ");
|
||||
std::wstring trimLeft (const std::wstring& in, const std::wstring& t = L" "); // UNICODE safe
|
||||
std::wstring trimRight (const std::wstring& in, const std::wstring& t = L" "); // UNICODE safe
|
||||
std::wstring trim (const std::wstring& in, const std::wstring& t = L" "); // UNICODE safe
|
||||
void extractParagraphs (const std::string&, std::vector<std::string>&);
|
||||
void extractLine (std::string&, std::string&, int);
|
||||
void split (std::vector<std::string>&, const std::string&, const char);
|
||||
void split (std::vector<std::string>&, const std::string&, const std::string&);
|
||||
void join (std::string&, const std::string&, const std::vector<std::string>&);
|
||||
std::string commify (const std::string&);
|
||||
std::string lowerCase (const std::string&);
|
||||
void delay (float);
|
||||
int autoComplete (const std::string&, const std::vector<std::string>&, std::vector<std::string>&);
|
||||
void formatTimeDeltaDays (std::string&, time_t);
|
||||
std::string formatSeconds (time_t);
|
||||
const std::string uuid ();
|
||||
|
||||
// rules.cpp
|
||||
void initializeColorRules (Config&);
|
||||
void autoColorize (T&, Text::color&, Text::color&);
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
5
src/tests/.gitignore
vendored
Normal file
5
src/tests/.gitignore
vendored
Normal file
|
@ -0,0 +1,5 @@
|
|||
t.t
|
||||
tdb.t
|
||||
pending.data
|
||||
completed.data
|
||||
|
24
src/tests/Makefile
Normal file
24
src/tests/Makefile
Normal file
|
@ -0,0 +1,24 @@
|
|||
PROJECT = t.t tdb.t
|
||||
CFLAGS = -I.. -I../../../library/include -Wall -pedantic -ggdb3 -fno-rtti
|
||||
LFLAGS = -L/usr/local/lib -L../../../library/lib -lcompany -lpcre -lncurses -lcurl
|
||||
|
||||
all: $(PROJECT)
|
||||
|
||||
install: $(PROJECT)
|
||||
@echo unimplemented
|
||||
|
||||
test: $(PROJECT)
|
||||
@echo unimplemented
|
||||
|
||||
clean:
|
||||
-rm *.o $(PROJECT)
|
||||
|
||||
.cpp.o:
|
||||
g++ -c $(CFLAGS) $<
|
||||
|
||||
t.t: t.t.o ../T.o ../parse.o ../../../library/lib/libcompany.a
|
||||
g++ t.t.o ../T.o ../parse.o $(LFLAGS) -o t.t
|
||||
|
||||
tdb.t: tdb.t.o ../TDB.o ../T.o ../parse.o ../../../library/lib/libcompany.a
|
||||
g++ tdb.t.o ../TDB.o ../T.o ../parse.o $(LFLAGS) -o tdb.t
|
||||
|
37
src/tests/t.t.cpp
Normal file
37
src/tests/t.t.cpp
Normal file
|
@ -0,0 +1,37 @@
|
|||
////////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
#include <T.h>
|
||||
#include <library.h>
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
int main (int argc, char** argv)
|
||||
{
|
||||
plan (4);
|
||||
|
||||
T t;
|
||||
std::string s = t.compose ();
|
||||
is ((int)s.length (), 46, "T::T (); T::compose ()");
|
||||
diag (s);
|
||||
|
||||
t.setStatus (T::completed);
|
||||
s = t.compose ();
|
||||
is (s[37], '+', "T::setStatus (completed)");
|
||||
diag (s);
|
||||
|
||||
t.setStatus (T::deleted);
|
||||
s = t.compose ();
|
||||
is (s[37], 'X', "T::setStatus (deleted)");
|
||||
diag (s);
|
||||
|
||||
// Round trip test.
|
||||
std::string sample = "00000000-0000-0000-0000-000000000000 - [] [] Sample";
|
||||
T t2;
|
||||
t2.parse (sample);
|
||||
sample += "\n";
|
||||
is (t2.compose (), sample, "T::parse -> T::compose round trip");
|
||||
return 0;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
127
src/tests/tdb.t.cpp
Normal file
127
src/tests/tdb.t.cpp
Normal file
|
@ -0,0 +1,127 @@
|
|||
////////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
#include <iostream>
|
||||
#include <unistd.h>
|
||||
|
||||
#include <TDB.h>
|
||||
#include <library.h>
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
int main (int argc, char** argv)
|
||||
{
|
||||
plan (43);
|
||||
|
||||
try
|
||||
{
|
||||
// Remove any residual test file.
|
||||
unlink ("./pending.data");
|
||||
unlink ("./completed.data");
|
||||
|
||||
// Try reading an empty database.
|
||||
TDB tdb;
|
||||
tdb.dataDirectory (".");
|
||||
std::vector <T> all;
|
||||
ok (!tdb.pendingT (all), "TDB::pendingT read empty db");
|
||||
is ((int) all.size (), 0, "empty db");
|
||||
ok (!tdb.allPendingT (all), "TDB::allPendingT read empty db");
|
||||
is ((int) all.size (), 0, "empty db");
|
||||
ok (!tdb.completedT (all), "TDB::completedT read empty db");
|
||||
is ((int) all.size (), 0, "empty db");
|
||||
ok (!tdb.allCompletedT (all), "TDB::allCompletedT read empty db");
|
||||
is ((int) all.size (), 0, "empty db");
|
||||
|
||||
// Add a new task.
|
||||
T t1;
|
||||
t1.setId (1);
|
||||
t1.setStatus (T::pending);
|
||||
t1.setAttribute ("project", "p1");
|
||||
t1.setDescription ("task 1");
|
||||
diag (t1.compose ());
|
||||
ok (tdb.addT (t1), "TDB::addT t1");
|
||||
|
||||
// Verify as above.
|
||||
ok (tdb.pendingT (all), "TDB::pendingT read db");
|
||||
is ((int) all.size (), 1, "empty db");
|
||||
ok (tdb.allPendingT (all), "TDB::allPendingT read db");
|
||||
is ((int) all.size (), 1, "empty db");
|
||||
ok (!tdb.completedT (all), "TDB::completedT read empty db");
|
||||
is ((int) all.size (), 0, "empty db");
|
||||
ok (!tdb.allCompletedT (all), "TDB::allCompletedT read empty db");
|
||||
is ((int) all.size (), 0, "empty db");
|
||||
|
||||
// TODO Modify task.
|
||||
fail ("modify");
|
||||
fail ("verify");
|
||||
|
||||
// Complete task.
|
||||
ok (tdb.completeT (t1), "TDB::completeT t1");;
|
||||
ok (!tdb.pendingT (all), "TDB::pendingT read db");
|
||||
is ((int) all.size (), 0, "empty db");
|
||||
ok (tdb.allPendingT (all), "TDB::allPendingT read db");
|
||||
is ((int) all.size (), 1, "empty db");
|
||||
ok (!tdb.completedT (all), "TDB::completedT read empty db");
|
||||
is ((int) all.size (), 0, "empty db");
|
||||
ok (!tdb.allCompletedT (all), "TDB::allCompletedT read empty db");
|
||||
is ((int) all.size (), 0, "empty db");
|
||||
|
||||
is (tdb.gc (), 1, "TDB::gc");
|
||||
ok (!tdb.pendingT (all), "TDB::pendingT read empty db");
|
||||
is ((int) all.size (), 0, "empty db");
|
||||
ok (!tdb.allPendingT (all), "TDB::allPendingT read empty db");
|
||||
is ((int) all.size (), 0, "empty db");
|
||||
ok (tdb.completedT (all), "TDB::completedT read db");
|
||||
is ((int) all.size (), 1, "empty db");
|
||||
ok (tdb.allCompletedT (all), "TDB::allCompletedT read db");
|
||||
is ((int) all.size (), 1, "empty db");
|
||||
|
||||
// Add a new task.
|
||||
T t2;
|
||||
t2.setId (2);
|
||||
t2.setAttribute ("project", "p2");
|
||||
t2.setDescription ("task 2");
|
||||
diag (t2.compose ());
|
||||
ok (tdb.addT (t2), "TDB::addT t2");
|
||||
|
||||
fail ("verify");
|
||||
|
||||
// Delete task.
|
||||
ok (tdb.deleteT (t2), "TDB::deleteT t2");
|
||||
|
||||
fail ("verify");
|
||||
|
||||
// GC the files.
|
||||
is (tdb.gc (), 1, "1 <- TDB::gc");
|
||||
|
||||
// Read log file.
|
||||
std::vector <std::string> entries;
|
||||
tdb.logRead (entries);
|
||||
std::vector <std::string>::iterator it;
|
||||
for (it = entries.begin (); it != entries.end (); ++it)
|
||||
diag (*it);
|
||||
|
||||
// TODO Verify contents of above transactions.
|
||||
fail ("verify");
|
||||
}
|
||||
|
||||
catch (std::string& error)
|
||||
{
|
||||
diag (error);
|
||||
return -1;
|
||||
}
|
||||
|
||||
catch (...)
|
||||
{
|
||||
diag ("Unknown error.");
|
||||
return -2;
|
||||
}
|
||||
|
||||
/*
|
||||
unlink ("./pending.data");
|
||||
unlink ("./completed.data");
|
||||
*/
|
||||
return 0;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
277
src/text.cpp
Normal file
277
src/text.cpp
Normal file
|
@ -0,0 +1,277 @@
|
|||
////////////////////////////////////////////////////////////////////////////////
|
||||
// Copyright 2004 - 2008, Paul Beckingham. All rights reserved.
|
||||
//
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
#include <iostream>
|
||||
#include <vector>
|
||||
#include <string>
|
||||
#include "task.h"
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
void wrapText (
|
||||
std::vector <std::string>& lines,
|
||||
const std::string& text,
|
||||
const int width)
|
||||
{
|
||||
std::string copy = text;
|
||||
std::string line;
|
||||
|
||||
while (copy.length ())
|
||||
{
|
||||
extractLine (copy, line, width);
|
||||
lines.push_back (line);
|
||||
}
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
void split (std::vector<std::string>& results, const std::string& input, const char delimiter)
|
||||
{
|
||||
std::string temp = input;
|
||||
std::string::size_type i;
|
||||
while ((i = temp.find (delimiter)) != std::string::npos)
|
||||
{
|
||||
std::string token = temp.substr (0, i);
|
||||
results.push_back (token);
|
||||
temp.erase (0, i + 1);
|
||||
}
|
||||
|
||||
if (temp.length ()) results.push_back (temp);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
void split (std::vector<std::string>& results, const std::string& input, const std::string& delimiter)
|
||||
{
|
||||
std::string temp = input;
|
||||
std::string::size_type i;
|
||||
while ((i = temp.find (delimiter)) != std::string::npos)
|
||||
{
|
||||
std::string token = temp.substr (0, i);
|
||||
results.push_back (token);
|
||||
temp.erase (0, i + delimiter.length ());
|
||||
}
|
||||
|
||||
if (temp.length ()) results.push_back (temp);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
void join (
|
||||
std::string& result,
|
||||
const std::string& separator,
|
||||
const std::vector<std::string>& items)
|
||||
{
|
||||
result = "";
|
||||
unsigned int size = items.size ();
|
||||
for (unsigned int i = 0; i < size; ++i)
|
||||
{
|
||||
result += items[i];
|
||||
if (i < size - 1)
|
||||
result += separator;
|
||||
}
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
void extractParagraphs (const std::string& input, std::vector<std::string>& output)
|
||||
{
|
||||
std::string copy = input;
|
||||
while (1)
|
||||
{
|
||||
unsigned int so = copy.find ("<p>");
|
||||
unsigned int eo = copy.find ("</p>");
|
||||
|
||||
if (so == std::string::npos && eo == std::string::npos)
|
||||
break;
|
||||
|
||||
std::string extract = trim (copy.substr (so + 3, eo - so - 3));
|
||||
copy = copy.substr (eo + 4, std::string::npos);
|
||||
output.push_back (extract);
|
||||
}
|
||||
|
||||
// There were no paragraphs.
|
||||
if (!output.size ())
|
||||
output.push_back (input);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
std::string trimLeft (const std::string& in, const std::string& t /*= " "*/)
|
||||
{
|
||||
std::string out = in;
|
||||
return out.erase (0, in.find_first_not_of (t));
|
||||
}
|
||||
|
||||
// UNICODE safe
|
||||
std::wstring trimLeft (const std::wstring& in, const std::wstring& t /*= L" "*/)
|
||||
{
|
||||
std::wstring out = in;
|
||||
return out.erase (0, in.find_first_not_of (t));
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
std::string trimRight (const std::string& in, const std::string& t /*= " "*/)
|
||||
{
|
||||
std::string out = in;
|
||||
return out.erase (out.find_last_not_of (t) + 1);
|
||||
}
|
||||
|
||||
// UNICODE safe
|
||||
std::wstring trimRight (const std::wstring& in, const std::wstring& t /*= L" "*/)
|
||||
{
|
||||
std::wstring out = in;
|
||||
return out.erase (out.find_last_not_of (t) + 1);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
std::string trim (const std::string& in, const std::string& t /*= " "*/)
|
||||
{
|
||||
std::string out = in;
|
||||
return trimLeft (trimRight (out, t), t);
|
||||
}
|
||||
|
||||
// UNICODE safe
|
||||
std::wstring trim (const std::wstring& in, const std::wstring& t /*= L" "*/)
|
||||
{
|
||||
std::wstring out = in;
|
||||
return trimLeft (trimRight (out, t), t);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
// Remove enclosing balanced quotes. Assumes trimmed text.
|
||||
void unquoteText (std::string& text)
|
||||
{
|
||||
char quote = text[0];
|
||||
if (quote == '\'' || quote == '"')
|
||||
if (text[text.length () - 1] == quote)
|
||||
text = text.substr (1, text.length () - 3);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
void extractLine (std::string& text, std::string& line, int length)
|
||||
{
|
||||
unsigned int eol = text.find ("\n");
|
||||
|
||||
// Special case: found \n in first length characters.
|
||||
if (eol != std::string::npos && eol < (unsigned) length)
|
||||
{
|
||||
line = text.substr (0, eol); // strip \n
|
||||
text = text.substr (eol + 1, std::string::npos);
|
||||
return;
|
||||
}
|
||||
|
||||
// Special case: no \n, and less than length characters total.
|
||||
// special case: text.find ("\n") == std::string::npos && text.length () < length
|
||||
if (eol == std::string::npos && text.length () <= (unsigned) length)
|
||||
{
|
||||
line = text;
|
||||
text = "";
|
||||
return;
|
||||
}
|
||||
|
||||
// Safe to ASSERT text.length () > length
|
||||
|
||||
// Look for the last space prior to length
|
||||
eol = length;
|
||||
while (eol && text[eol] != ' ' && text[eol] != '\n')
|
||||
--eol;
|
||||
|
||||
// If a space was found, break there.
|
||||
if (eol)
|
||||
{
|
||||
line = text.substr (0, eol);
|
||||
text = text.substr (eol + 1, std::string::npos);
|
||||
}
|
||||
|
||||
// If no space was found, hyphenate.
|
||||
else
|
||||
{
|
||||
line = text.substr (0, length - 1) + "-";
|
||||
text = text.substr (length - 1, std::string::npos);
|
||||
}
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
std::string commify (const std::string& data)
|
||||
{
|
||||
// First scan for decimal point and end of digits.
|
||||
int decimalPoint = -1;
|
||||
int end = -1;
|
||||
|
||||
int i;
|
||||
for (int i = 0; i < (int) data.length (); ++i)
|
||||
{
|
||||
if (::isdigit (data[i]))
|
||||
end = i;
|
||||
|
||||
if (data[i] == '.')
|
||||
decimalPoint = i;
|
||||
}
|
||||
|
||||
std::string result;
|
||||
if (decimalPoint != -1)
|
||||
{
|
||||
// In reverse order, transfer all digits up to, and including the decimal
|
||||
// point.
|
||||
for (i = (int) data.length () - 1; i >= decimalPoint; --i)
|
||||
result += data[i];
|
||||
|
||||
int consecutiveDigits = 0;
|
||||
for (; i >= 0; --i)
|
||||
{
|
||||
if (::isdigit (data[i]))
|
||||
{
|
||||
result += data[i];
|
||||
|
||||
if (++consecutiveDigits == 3 && i && ::isdigit (data[i - 1]))
|
||||
{
|
||||
result += ',';
|
||||
consecutiveDigits = 0;
|
||||
}
|
||||
}
|
||||
else
|
||||
result += data[i];
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// In reverse order, transfer all digits up to, but not including the last
|
||||
// digit.
|
||||
for (i = (int) data.length () - 1; i > end; --i)
|
||||
result += data[i];
|
||||
|
||||
int consecutiveDigits = 0;
|
||||
for (; i >= 0; --i)
|
||||
{
|
||||
if (::isdigit (data[i]))
|
||||
{
|
||||
result += data[i];
|
||||
|
||||
if (++consecutiveDigits == 3 && i && ::isdigit (data[i - 1]))
|
||||
{
|
||||
result += ',';
|
||||
consecutiveDigits = 0;
|
||||
}
|
||||
}
|
||||
else
|
||||
result += data[i];
|
||||
}
|
||||
}
|
||||
|
||||
// reverse result into data.
|
||||
std::string done;
|
||||
for (int i = (int) result.length () - 1; i >= 0; --i)
|
||||
done += result[i];
|
||||
|
||||
return done;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
std::string lowerCase (const std::string& input)
|
||||
{
|
||||
std::string output = input;
|
||||
for (int i = 0; i < (int) input.length (); ++i)
|
||||
if (::isupper (input[i]))
|
||||
output[i] = ::tolower (input[i]);
|
||||
|
||||
return output;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
212
src/util.cpp
Normal file
212
src/util.cpp
Normal file
|
@ -0,0 +1,212 @@
|
|||
////////////////////////////////////////////////////////////////////////////////
|
||||
// Copyright 2006 - 2008, Paul Beckingham. All rights reserved.
|
||||
//
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
#include <iostream>
|
||||
#include <vector>
|
||||
#include <string>
|
||||
#include <sys/types.h>
|
||||
#include <sys/time.h>
|
||||
#include <unistd.h>
|
||||
#include <stdio.h>
|
||||
#include "Table.h"
|
||||
#include "task.h"
|
||||
#include "../auto.h"
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
bool confirm (const std::string& question)
|
||||
{
|
||||
std::cout << question << " (y/n) ";
|
||||
std::string answer;
|
||||
std::cin >> answer;
|
||||
|
||||
answer = trim (answer);
|
||||
if (answer == "y" || answer == "Y")
|
||||
return true;
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
void delay (float f)
|
||||
{
|
||||
struct timeval t;
|
||||
t.tv_sec = (int) f;
|
||||
t.tv_usec = int ((f - (int)f) * 1000000);
|
||||
|
||||
select (0, NULL, NULL, NULL, &t);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
// Convert a quantity in seconds to a more readable format.
|
||||
// Long version:
|
||||
// 0-59 S seconds
|
||||
// 60-3599 M minutes, S seconds
|
||||
// 3600-86399 H hours, M minutes, S seconds
|
||||
// 86400- D days, H hours, M minutes, S seconds
|
||||
// Short version:
|
||||
// 0-59 S seconds
|
||||
// 60-3599 M minutes, S seconds
|
||||
// 3600-86399 H hours, M minutes, S seconds
|
||||
//
|
||||
void formatTimeDeltaDays (std::string& output, time_t delta)
|
||||
{
|
||||
char formatted[24];
|
||||
float days = (float) delta / 86400.0;
|
||||
|
||||
if (days > 365)
|
||||
sprintf (formatted, "%.1f yrs", (days / 365.2422));
|
||||
else if (days > 84)
|
||||
sprintf (formatted, "%1d mths", (int) (days / 30.6));
|
||||
else if (days > 13)
|
||||
sprintf (formatted, "%d wks", (int) (days / 7.0));
|
||||
else if (days > 5.0)
|
||||
sprintf (formatted, "%d days", (int) days);
|
||||
else if (days > 1.0)
|
||||
sprintf (formatted, "%.1f days", days);
|
||||
else if (days * 24 > 1.0)
|
||||
sprintf (formatted, "%d hrs", (int) (days * 24.0));
|
||||
else if (days * 24 * 60 > 1)
|
||||
sprintf (formatted, "%d mins", (int) (days * 24 * 60));
|
||||
else if (days * 24 * 60 * 60 > 1)
|
||||
sprintf (formatted, "%d secs", (int) (days * 24 * 60 * 60));
|
||||
else
|
||||
strcpy (formatted, "-");
|
||||
|
||||
output = formatted;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
std::string formatSeconds (time_t delta)
|
||||
{
|
||||
char formatted[24];
|
||||
float days = (float) delta / 86400.0;
|
||||
|
||||
if (days > 365)
|
||||
sprintf (formatted, "%.1f yrs", (days / 365.2422));
|
||||
else if (days > 84)
|
||||
sprintf (formatted, "%1d mths", (int) (days / 30.6));
|
||||
else if (days > 13)
|
||||
sprintf (formatted, "%d wks", (int) (days / 7.0));
|
||||
else if (days > 5.0)
|
||||
sprintf (formatted, "%d days", (int) days);
|
||||
else if (days > 1.0)
|
||||
sprintf (formatted, "%.1f days", days);
|
||||
else if (days * 24 > 1.0)
|
||||
sprintf (formatted, "%d hrs", (int) (days * 24.0));
|
||||
else if (days * 24 * 60 > 1)
|
||||
sprintf (formatted, "%d mins", (int) (days * 24 * 60));
|
||||
else if (days * 24 * 60 * 60 > 1)
|
||||
sprintf (formatted, "%d secs", (int) (days * 24 * 60 * 60));
|
||||
else
|
||||
strcpy (formatted, "-");
|
||||
|
||||
return std::string (formatted);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
int autoComplete (
|
||||
const std::string& partial,
|
||||
const std::vector<std::string>& list,
|
||||
std::vector<std::string>& matches)
|
||||
{
|
||||
matches.erase (matches.begin (), matches.end ());
|
||||
|
||||
// Handle trivial case.
|
||||
unsigned int length = partial.length ();
|
||||
if (length)
|
||||
{
|
||||
for (unsigned int i = 0; i < list.size (); ++i)
|
||||
{
|
||||
// Special case where there is an exact match.
|
||||
if (partial == list[i])
|
||||
{
|
||||
matches.erase (matches.begin (), matches.end ());
|
||||
matches.push_back (list[i]);
|
||||
return 1;
|
||||
}
|
||||
|
||||
// Maintain a list of partial matches.
|
||||
if (length <= list[i].length () &&
|
||||
! strncmp (partial.c_str (), list[i].c_str (), length))
|
||||
matches.push_back (list[i]);
|
||||
}
|
||||
}
|
||||
|
||||
return matches.size ();
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
#ifdef HAVE_UUID
|
||||
|
||||
#include <uuid/uuid.h>
|
||||
|
||||
const std::string uuid ()
|
||||
{
|
||||
uuid_t id;
|
||||
uuid_generate (id);
|
||||
char buffer[100];
|
||||
uuid_unparse_lower (id, buffer);
|
||||
|
||||
return std::string (buffer);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
#else
|
||||
#warning "Using custom UUID generator"
|
||||
|
||||
#include <stdlib.h>
|
||||
static char randomHexDigit ()
|
||||
{
|
||||
static char digits[] = "0123456789abcdef";
|
||||
return digits[random () % 16];
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
const std::string uuid ()
|
||||
{
|
||||
// xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx
|
||||
char id [37];
|
||||
id[0] = randomHexDigit ();
|
||||
id[1] = randomHexDigit ();
|
||||
id[2] = randomHexDigit ();
|
||||
id[3] = randomHexDigit ();
|
||||
id[4] = randomHexDigit ();
|
||||
id[5] = randomHexDigit ();
|
||||
id[6] = randomHexDigit ();
|
||||
id[7] = randomHexDigit ();
|
||||
id[8] = '-';
|
||||
id[9] = randomHexDigit ();
|
||||
id[10] = randomHexDigit ();
|
||||
id[11] = randomHexDigit ();
|
||||
id[12] = randomHexDigit ();
|
||||
id[13] = '-';
|
||||
id[14] = randomHexDigit ();
|
||||
id[15] = randomHexDigit ();
|
||||
id[16] = randomHexDigit ();
|
||||
id[17] = randomHexDigit ();
|
||||
id[18] = '-';
|
||||
id[19] = randomHexDigit ();
|
||||
id[20] = randomHexDigit ();
|
||||
id[21] = randomHexDigit ();
|
||||
id[22] = randomHexDigit ();
|
||||
id[23] = '-';
|
||||
id[24] = randomHexDigit ();
|
||||
id[25] = randomHexDigit ();
|
||||
id[26] = randomHexDigit ();
|
||||
id[27] = randomHexDigit ();
|
||||
id[28] = randomHexDigit ();
|
||||
id[29] = randomHexDigit ();
|
||||
id[30] = randomHexDigit ();
|
||||
id[31] = randomHexDigit ();
|
||||
id[32] = randomHexDigit ();
|
||||
id[33] = randomHexDigit ();
|
||||
id[34] = randomHexDigit ();
|
||||
id[35] = randomHexDigit ();
|
||||
|
||||
return id;
|
||||
}
|
||||
#endif
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
Loading…
Add table
Add a link
Reference in a new issue