Compare commits

..

1 Commits

Author SHA1 Message Date
Federico Hernandez
462f27fce7 Changed epoch to be 12/22 for UTC 2009-08-18 14:34:17 +02:00
69 changed files with 509 additions and 1432 deletions

1
.gitignore vendored
View File

@@ -15,4 +15,5 @@ www.xls
src/tests/all.log
src/tests/*.data
*~
movie*
.*.swp

View File

@@ -17,8 +17,6 @@ The following submitted code, packages or analysis, and deserve special thanks:
P.C. Shyamshankar
Johan Friis
Steven de Brouwer
Pietro Cerutti
Cory Donnelly
Thanks to the following, who submitted detailed bug reports and excellent suggestions:
Eugene Kramer
@@ -36,10 +34,6 @@ Thanks to the following, who submitted detailed bug reports and excellent sugges
Eric Farris
Bruce Dillahunty
Askme Too
Mike Adonay
Thomas@BIC
Ian Mortimer
Zach Frazier
Joe Pulliam
Juergen Daubert

View File

@@ -1,99 +1,7 @@
------ current release ---------------------------
1.8.5 (12/05/2009)
+ Added feature to allow the user to quit when asked to confirm multiple
changes. Now task asks "Proceed with change? (Yes/no/all/quit)".
+ Added feature #341 that makes explicit references to the task and taskrc
man pages, both in the auto-generated .taskrc file and the version command
output (thanks to Cory Donnelly).
+ Added feature - #310 that simplified and make clearer an error message
that complained about things that were beyond user control (thanks to
John Florian).
+ Fixed bug that was causing the 'completed' report to sort incorrectly.
+ Fixed bug #321 where all shell input was converted to lower case (thanks
to Juergen Daubert).
+ Fixed bug #327 that allowed the removal of a due date from a recurring
task.
+ Fixed bug #317 which colored tasks in the 'completed' report according
to due dates, which are no longer relevant to a completed task (thanks
to Cory Donnelly).
+ Fixed bug that was causing the 'completed' report to sort incorrectly.
+ Fixed bug #322 which failed to propagate rc overrides to shell commands.
+ Fixed redundant messages when exiting shell mode.
+ Fixed bug #333 which failed to display the ID of a duplicated task (thanks
to Cory Donnelly).
+ Fixed bug #332 where task complained that the 'recur_ind' custom report
column was invalid. It was misnamed in the documentation, which should
have read 'recurrence_indicator'. Also, the 'tag_indicator' column was
not mentioned anywhere (thanks to T. Charles Yun).
+ Fixed bug #319 that caused task to not properly detect the removal of a
tag when obtaining confirmation from the user fora bulk modification
(thanks to Cory Donnelly).
------ old releases ------------------------------
1.8.4 (11/17/2009) 12c4983936d27317df100f05da8244139dd06a3f
+ Fixed bug that caused wait: dates to not be properly rendered in a
readable and preferred format with the "edit" command.
+ Fixed bug that caused a hang on cygwin, when a task with multiple
annotations was edited (thanks to Joe Pulliam).
+ Fixed bug #314 where the edit command fails when data.location includes
directories containing spaces (thanks to Cory Donnelly).
+ Added a warning (issue #312) when modifying recurring tasks, that all
instances of that task may be modified. When task confirms a bulk edit
the recurrence is again indicated (thanks to Cory Donnelly).
1.8.3 (10/21/2009) bcdcbeeea0d92f21c3565aebfaf6332b959f4025
+ Added support for Haiku R1/alpha1
1.8.2 (9/7/2009) f243f0ed443ecd7dde779de8a6525222591024db
+ Added feature #282 that returns useful exit codes to the shell. Now a
script can detect whether no tasks were returned by a report (thanks to
Pietro Cerutti).
+ Fixed bug #287 that causes color control codes to be written to shadow
files (thanks to Richard Querin).
+ Fixed bug #289 which imported task from todo.sh without valid uuids
(thanks to Ben Jackson).
+ Fixed bug #291 which generated a false warning about an unrecognized
variable when enabling default.projects in .taskrc (thanks to Thomas@BIC).
+ Fixed bug #288 which failed to propagate rc file overrides on the command
line to the default command (thanks to Zach Frazier).
1.8.1 (8/20/2009) 35792e7874d2bb664abb1a0a67960b7fe7e0fccf
+ Fixed bug #231 that broke the build on OpenBSD 32-bit due to a time_t
and int collision (thanks to Pietro Cerutti).
+ Fixed bug #241 that prevented bash's tab-completion of projects in Fedora
11 and likely anything using bash-4 (thanks to John Florian).
+ Fixed bug #242 that sometimes causes the ID echoed after a task is added
to be incorrect (thanks to John Florian).
+ Fixed bug #245 that quoted date fields on export, that were subsequently
improperly parsed on import (thanks to John Florian).
+ Fixed bug #248 where single and double quotes are both stored as
ampersand-quot-semi (thanks to John Florian).
+ Fixed bug #249 that caused annotations with the same date to be lost after
a "task edit" command (thanks to Federico Hernandez).
+ Fixed bug #250 whereby rc.dateformat was not observed when parsing the
creation date of an annotation (thanks to Federico Hernandez).
+ Fixed bug #251 whereby the presence of annotations cause the .hasnt attribute
modifier to not work (thanks to John Florian).
+ Fixed bug #252 that prevented use of attribute modifiers on dates to effect
a range, such as "task ls due.after:eom due.before:eoy" (thanks to John
Florian).
+ Fixed bug #256 that allowed a recurring task with no due date.
+ Fixed bug #257 where an extant ~/.taskrc file prevented the override and
automatic creation of an alternate rc file (thanks to Zach Frazier).
+ Fixed bug #259 that cause a build failure on Snow Leopard 10a432.
+ Fixed bug #260 whereby the start, stop and delete commands did not complain
when filter arguments were specified, even though they were ignored
(thanks to T. Charles Yun).
+ Fixed bug that allowed a recurring task to be added without a due date.
+ Fixed bug that displays the wrong .taskrc file name on override (thanks to
Federico Hernandez).
+ Fixed bug that failed to suppress color control code in the header and footnote
when redirecting output to a file (thanks to John Florian).
1.8.0 (7/21/2009) 14977ef317bd004dae2f2c313e806af9f2a2140c
1.8.0 (7/21/2009)
+ Added zsh tab completion script (thanks to P.C. Shyamshankar).
+ Fixed bug that cause the _forcecolor configuration variable to be
considered obsolete (thank to Bruce Dillahunty).
@@ -162,7 +70,9 @@
and completed tasks.
+ Now over 1,600 unit tests, helping to maintain code quality.
1.7.1 (6/8/2009) 1422a15cbc470cff590bf06daad20d01fe1b05ef
------ old releases ------------------------------
1.7.1 (6/8/2009)
+ Fixed build failure on OpenBSD (thanks to Mike Adonay).
+ Took the opportunity of a patch release to update the various email
addresses and URLs in the various documents.

30
NEWS
View File

@@ -1,5 +1,5 @@
New Features in task 1.8
New Features in task 1.8.0
- Attribute modifiers, for precise queries
- Improved calendar feature
@@ -9,26 +9,26 @@ New Features in task 1.8
- In addition to being a standard part of Fedora 10 and 11 (yum install task),
task is now also a standard part of Cygwin 1.5
- There are new demo movies on taskwarrior.org
- Shell-friendly exit codes
Please refer to the ChangeLog file for full details. There are too many to
list here.
Task has been built and tested on the following configurations:
* OS X 10.6 Snow Leopard and 10.5 Leopard
* Fedora 12 Constantine and 11 Leonidas
* Ubuntu 9.10 Karmic Koala and 9.04 Jaunty Jackalope
* Slackware 12.2
* Arch Linux
* Gentoo Linux
* SliTaz Linux
* CRUX Linux
* Solaris 10 and 8
* OpenBSD 4.5
* FreeBSD
* Cygwin 1.5
* Haiku R1/alpha1
- OS X 10.5 Leopard
- OS X 10.4 Tiger
- Fedora Core 11 Leonidas
- Fedora Core 10 Cambridge
- Ubuntu 9.04 Jaunty Jackalope
- Ubuntu 8.10 Intrepid Ibex
- Ubuntu 8.04 Hardy Heron
- Slackware 12.2
- Arch Linux
- Solaris 10
- Solaris 8
- OpenBSD 4.5
- FreeBSD
- Cygwin 1.5.25-14
While Task has undergone testing, bugs are sure to remain. If you encounter a
bug, please enter a new issue at:

4
README
View File

@@ -12,8 +12,8 @@ At the site you'll find a wiki, discussion forums, downloads, news and more.
Your contributions are especially welcome. Whether it comes in the form of
code patches, ideas, discussion, bug reports, encouragement or criticism, your
input is needed.
code patches, ideas, discussion, bug reports or just encouragement, your input
is needed.
Please send your support questions and code patches to:

View File

@@ -2,11 +2,10 @@
# Process this file with autoconf to produce a configure script.
AC_PREREQ(2.61)
AC_INIT(task, 1.8.5, support@taskwarrior.org)
AC_INIT(task, 1.8.0, support@taskwarrior.org)
CFLAGS="${CFLAGS=}"
CXXFLAGS="${CXXFLAGS=}"
# this macro is used to get the arguments supplied
# to the configure script (./configure --enable-debug)
# Check if we have enable debug support.

View File

@@ -1,4 +1,4 @@
.TH task-tutorial 5 2009-11-18 "task 1.8.5" "User Manuals"
.TH task-tutorial 5 2009-07-14 "Task 1.8.0" "User Manuals"
.SH NAME
task-tutorial \- A tutorial for the task(1) command line todo manager.

View File

@@ -1,4 +1,4 @@
.TH task 1 2009-11-18 "task 1.8.5" "User Manuals"
.TH task 1 2009-07-14 "Task 1.8.0" "User Manuals"
.SH NAME
task \- A command line todo manager.

View File

@@ -1,4 +1,4 @@
.TH taskrc 5 2009-11-18 "task 1.8.5" "User Manuals"
.TH taskrc 5 2009-07-14 "Task 1.8.0" "User Manuals"
.SH NAME
taskrc \- Configuration file for the task(1) command
@@ -384,9 +384,8 @@ The description for report X when running the "task help" command.
.TP
.B report.X.columns
The columns that will be used when generating the report X. Valid columns are:
id, uuid, project, priority, entry, start, due, recur, recur_indicator, age,
age_compact, active, tags, tag_indicator, description, description_only.
The IDs are separated by commas.
id, uuid, project, priority, entry, start, due, recur, recur_ind, age, age_compact,
active, tags, description, description_only. The IDs are separated by commas.
.TP
.B report.X.labels

View File

@@ -1,4 +1,4 @@
# setup.hint for task 1.8.1-1
# setup.hint for task 1.7.1-1
category: Utils
requires: libncurses9 cygwin
sdesc: A command-line to do list manager

View File

@@ -1,4 +1,4 @@
task 1.8.1-1
task 1.7.1-1
------------------------------------------
A command-line to do list manager that can be used
@@ -28,10 +28,10 @@ Language:
------------------------------------
Build instructions:
unpack task-1.8.1-1-src.tar.bz2
unpack task-1.7.1-1-src.tar.bz2
if you use setup to install this src package,
it will be unpacked under /usr/src automatically
cd /usr/src/task-1.8.1-1
cd /usr/src/task-1.7.1-1
./configure --prefix=/usr
make
make install
@@ -42,4 +42,4 @@ task was packaged for cygwin by
Federico Hernandez <ultrafredde@gmail.com> and
is licensed under the GPL
---- task-1.8.1-1 -- 2009-08-20 ----
---- task-1.7.1-1 -- 2009-06-17 ----

View File

@@ -1,8 +1,8 @@
diff -Nrup task-1.8.1-1/CYGWIN-PATCHES/setup.hint task-1.8.1-1.cygwin/CYGWIN-PATCHES/setup.hint
--- task-1.8.1-1/CYGWIN-PATCHES/setup.hint 1970-01-01 01:00:00.000000000 +0100
+++ task-1.8.1-1.cygwin/CYGWIN-PATCHES/setup.hint 2009-08-20 15:47:56.304750000 +0200
diff -Nrup task-1.7.1-1/CYGWIN-PATCHES/setup.hint task-1.7.1-1.cygwin/CYGWIN-PATCHES/setup.hint
--- task-1.7.1-1/CYGWIN-PATCHES/setup.hint 1970-01-01 01:00:00.000000000 +0100
+++ task-1.7.1-1.cygwin/CYGWIN-PATCHES/setup.hint 2009-06-17 15:47:56.304750000 +0200
@@ -0,0 +1,10 @@
+# setup.hint for task 1.8.1-1
+# setup.hint for task 1.7.1-1
+category: Utils
+requires: libncurses9 cygwin
+sdesc: A command-line to do list manager
@@ -12,11 +12,11 @@ diff -Nrup task-1.8.1-1/CYGWIN-PATCHES/setup.hint task-1.8.1-1.cygwin/CYGWIN-PAT
+reports and graphs, lots of manipulation commands,
+low-level API, abbreviations for all commands and
+options, multiuser file locking, recurring tasks."
diff -Nrup task-1.8.1-1/CYGWIN-PATCHES/task-1.8.1-1.README task-1.8.1-1.cygwin/CYGWIN-PATCHES/task-1.8.1-1.README
--- task-1.8.1-1/CYGWIN-PATCHES/task-1.8.1-1.README 1970-01-01 01:00:00.000000000 +0100
+++ task-1.8.1-1.cygwin/CYGWIN-PATCHES/task-1.8.1-1.README 2009-08-20 15:47:44.320375000 +0200
diff -Nrup task-1.7.1-1/CYGWIN-PATCHES/task-1.7.1-1.README task-1.7.1-1.cygwin/CYGWIN-PATCHES/task-1.7.1-1.README
--- task-1.7.1-1/CYGWIN-PATCHES/task-1.7.1-1.README 1970-01-01 01:00:00.000000000 +0100
+++ task-1.7.1-1.cygwin/CYGWIN-PATCHES/task-1.7.1-1.README 2009-06-17 15:47:44.320375000 +0200
@@ -0,0 +1,45 @@
+task 1.8.1-1
+task 1.7.1-1
+------------------------------------------
+
+A command-line to do list manager that can be used
@@ -46,10 +46,10 @@ diff -Nrup task-1.8.1-1/CYGWIN-PATCHES/task-1.8.1-1.README task-1.8.1-1.cygwin/C
+------------------------------------
+
+Build instructions:
+ unpack task-1.8.1-1-src.tar.bz2
+ unpack task-1.7.1-1-src.tar.bz2
+ if you use setup to install this src package,
+ it will be unpacked under /usr/src automatically
+ cd /usr/src/task-1.8.1-1
+ cd /usr/src/task-1.7.1-1
+ ./configure --prefix=/usr
+ make
+ make install
@@ -60,4 +60,4 @@ diff -Nrup task-1.8.1-1/CYGWIN-PATCHES/task-1.8.1-1.README task-1.8.1-1.cygwin/C
+Federico Hernandez <ultrafredde@gmail.com> and
+is licensed under the GPL
+
+---- task-1.8.1-1 -- 2009-08-20 ----
+---- task-1.7.1-1 -- 2009-06-17 ----

View File

@@ -1,4 +1,4 @@
task 1.8.1-1
task 1.7.1-1
------------------------------------------
A command-line to do list manager that can be used
@@ -28,10 +28,10 @@ Language:
------------------------------------
Build instructions:
unpack task-1.8.1-1-src.tar.bz2
unpack task-1.7.1-1-src.tar.bz2
if you use setup to install this src package,
it will be unpacked under /usr/src automatically
cd /usr/src/task-1.8.1-1
cd /usr/src/task-1.7.1-1
./configure --prefix=/usr
make
make install
@@ -42,4 +42,4 @@ task was packaged for cygwin by
Federico Hernandez <ultrafredde@gmail.com> and
is licensed under the GPL
---- task-1.8.1-1 -- 2009-08-20 ----
---- task-1.7.1-1 -- 2009-06-17 ----

View File

@@ -1,6 +1,6 @@
Name: task
Version: 1.8.1
Release: 1%{?dist}
Version: 1.8.0
Release: 0%{?dist}
Summary: A command-line to do list manager
Group: Applications/Productivity
@@ -40,25 +40,18 @@ rm -rf $RPM_BUILD_ROOT
%files
%defattr(-,root,root,-)
%doc AUTHORS ChangeLog COPYING NEWS README scripts i18n
%doc AUTHORS ChangeLog COPYING NEWS README scripts
%{_bindir}/task
%{_mandir}/man1/task.1.gz
%{_mandir}/man5/taskrc.5.gz
%{_mandir}/man5/task-tutorial.5.gz
%config(noreplace) %{_sysconfdir}/bash_completion.d
%{_sysconfdir}/bash_completion.d
%changelog
* Thu Aug 20 2009 Federico Hernandez <ultrafredde@gmail.com> - 1.8.1-1
Intial RPM for task bugfix release 1.8.1
* Tue Jul 21 2009 Federico Hernandez <ultrafredde@gmail.com> - 1.8.0-1
* Mon Jun 15 2009 Federico Hernandez <ultrafredde@gmail.com> - 1.8.0-0
Intial RPM for task release 1.8.0
* Mon Jul 13 2009 Federico Hernandez <ultrafredde@gmail.com> - 1.8.0.beta3-1
Intial RPM for task beta release 1.8.0.beta3
* Wed Jul 08 2009 Federico Hernandez <ultrafredde@gmail.com> - 1.8.0.beta2-1
Intial RPM for task beta release 1.8.0.beta2
* Tue Jul 07 2009 Federico Hernandez <ultrafredde@gmail.com> - 1.8.0.beta1-1
Intial RPM for task beta release 1.8.0.beta1
Installs now bash_completion file
* Tue Jun 08 2009 Federico Hernandez <ultrafredde@gmail.com> - 1.7.1-2
- Fixed inclusion of manpages.
* Tue Jun 08 2009 Federico Hernandez <ultrafredde@gmail.com> - 1.7.1-1

View File

@@ -1 +1 @@
<pkg-contents spec="1.12"><f n="task" o="root" g="wheel" p="33261" pt="/Users/paul/task.git/package-config/osx/binary/task" m="false" t="file"><mod>group</mod><mod>owner</mod></f></pkg-contents>
<pkg-contents spec="1.12"><f n="task" o="paul" g="staff" p="33261" pt="/Users/paul/task.git/package-config/osx/binary/task" m="false" t="file"/></pkg-contents>

View File

@@ -1 +1 @@
<pkgref spec="1.12" uuid="C71026FD-E252-42CD-89C3-2F6F087AAF17"><config><identifier>com.beckingham.task182.task.pkg</identifier><version>1.8.2</version><description></description><post-install type="none"/><requireAuthorization/><installFrom mod="true">/Users/paul/task.git/package-config/osx/binary/task</installFrom><installTo mod="true" relocatable="true">/usr/local/bin</installTo><flags><followSymbolicLinks/></flags><packageStore type="internal"></packageStore><mod>installTo</mod><mod>locationType</mod><mod>relocatable</mod><mod>identifier</mod><mod>parent</mod><mod>version</mod><mod>installTo.path</mod></config><contents><file-list>01task-contents.xml</file-list><filter>/CVS$</filter><filter>/\.svn$</filter><filter>/\.cvsignore$</filter><filter>/\.cvspass$</filter><filter>/\.DS_Store$</filter></contents></pkgref>
<pkgref spec="1.12" uuid="C71026FD-E252-42CD-89C3-2F6F087AAF17"><config><identifier>com.beckingham.task180.task.pkg</identifier><version>1.8.0</version><description></description><post-install type="none"/><requireAuthorization/><installFrom mod="true">/Users/paul/task.git/package-config/osx/binary/task</installFrom><installTo mod="true" relocatable="true">/usr/local/bin</installTo><flags><followSymbolicLinks/></flags><packageStore type="internal"></packageStore><mod>parent</mod><mod>locationType</mod><mod>relocatable</mod><mod>version</mod><mod>installTo.path</mod><mod>installTo</mod></config><contents><file-list>01task-contents.xml</file-list><filter>/CVS$</filter><filter>/\.svn$</filter><filter>/\.cvsignore$</filter><filter>/\.cvspass$</filter><filter>/\.DS_Store$</filter></contents></pkgref>

View File

@@ -1 +1 @@
<pkmkdoc spec="1.12"><properties><title>Task 1.8.2</title><build>/Users/paul/Desktop/task-1.8.2.pkg</build><organization>com.beckingham</organization><userSees ui="both"/><min-target os="3"/><domain anywhere="true" system="true"/></properties><distribution><versions min-spec="1.000000"/><scripts></scripts></distribution><contents><choice title="task" id="choice0" starts_selected="true" starts_enabled="true" starts_hidden="false"><pkgref id="com.beckingham.task182.task.pkg"/><choice-reqs><requirement id="tosv" operator="ge" value="'10.6.0'" selected="no" enabled="no" hidden="unchanged" startSelected="unchanged" startEnabled="unchanged" startHidden="unchanged"/></choice-reqs></choice></contents><resources bg-scale="proportional" bg-align="center"><locale lang="en"><resource mod="true" type="license">/Users/paul/task.git/package-config/osx/binary/COPYING.txt</resource><resource mod="true" type="readme">/Users/paul/task.git/package-config/osx/binary/README.txt</resource></locale></resources><flags/><item type="file">01task.xml</item><mod>properties.title</mod><mod>properties.customizeOption</mod><mod>properties.anywhereDomain</mod><mod>properties.systemDomain</mod></pkmkdoc>
<pkmkdoc spec="1.12"><properties><title>Task 1.8.0</title><build>/Users/paul/Desktop/task-1.8.0.pkg</build><organization>com.beckingham</organization><userSees ui="easy"/><min-target os="3"/><domain anywhere="true" system="true"/></properties><distribution><versions min-spec="1.000000"/><scripts></scripts></distribution><contents><choice title="task" id="choice0" starts_selected="true" starts_enabled="true" starts_hidden="false"><pkgref id="com.beckingham.task180.task.pkg"/><choice-reqs><requirement id="tosv" operator="ge" value="'10.5.0'" selected="no" enabled="no" hidden="unchanged" startSelected="unchanged" startEnabled="unchanged" startHidden="unchanged"/></choice-reqs></choice></contents><resources bg-scale="proportional" bg-align="center"><locale lang="en"><resource mod="true" type="license">/Users/paul/task.git/package-config/osx/binary/COPYING.txt</resource><resource mod="true" type="readme">/Users/paul/task.git/package-config/osx/binary/README.txt</resource></locale></resources><flags/><item type="file">01task.xml</item><mod>properties.title</mod><mod>properties.anywhereDomain</mod><mod>properties.systemDomain</mod></pkmkdoc>

View File

@@ -1,32 +1,8 @@
task (1.8.1-0ubuntu1) jaunty; urgency=low
* Initial deb package for task bugfix release 1.8.1
-- Federico Hernandez <ultrafredde@gmail.com> Thu, 20 Aug 2009 20:26:33 +0200
task (1.8.0-0ubuntu1) jaunty; urgency=low
* Initial deb package for task release 1.8.0
-- Federico Hernandez <ultrafredde@gmail.com> Tue, 21 Jul 2009 15:26:33 +0200
task (1.8.0-0ubuntu1~beta3) jaunty; urgency=low
* Initial deb package for task beta release 1.8.0.beta3
-- Federico Hernandez <ultrafredde@gmail.com> Mon, 13 Jul 2009 15:09:38 +0200
task (1.8.0-0ubuntu1~beta2) jaunty; urgency=low
* Initial deb package for task beta release 1.8.0.beta2
-- Federico Hernandez <ultrafredde@gmail.com> Wed, 08 Jul 2009 15:40:50 +0200
task (1.8.0-0ubuntu1~beta1) jaunty; urgency=low
* Initial deb package for task beta release 1.8.0.beta1
-- Federico Hernandez <ultrafredde@gmail.com> Tue, 07 Jul 2009 01:35:28 +0200
-- Federico Hernandez <ultrafredde@gmail.com> Thu, 11 Jun 2009 23:02:28 +0200
task (1.7.1-0ubuntu1) jaunty; urgency=low

View File

@@ -1,6 +1,6 @@
This package was debianized by:
Federico Hernandez <ultrafredde@gmail.com> on Thu, 20 Aug 2009 20:26:33 +0200
Federico Hernandez <ultrafredde@gmail.com> on Thu, 11 Jun 2009 23:02:28 +0200
It was downloaded from:
@@ -9,9 +9,6 @@ It was downloaded from:
Upstream Authors:
Paul Beckingham <paul@beckingham.net>
Federico Hernandez
David J Patrick
John Florian
Damian Glenny
Andy Lester
H. İbrahim Güngör
@@ -20,18 +17,18 @@ Upstream Authors:
Benjamin Tegarden
Chris Pride
Richard Querin
Federico Hernandez
T. Charles Yun
David J Patrick
P.C. Shyamshankar
Johan Friis
Steven de Brouwer
Pietro Cerutti
Copyright:
Copyright 2006 - 2009, Paul Beckingham
Copyright 2009 Federico Hernandez
Copyright 2009 P.C. Shyamshankar
Copyright 2009 John Florian
License:

View File

@@ -1,2 +0,0 @@
scripts
i18n

View File

@@ -31,9 +31,8 @@ binary-arch: install
dh_installchangelogs
dh_installdocs
dh_installman
dh_installexamples
install -D -m644 scripts/bash/task_completion.sh $(CURDIR)/debian/task/etc/bash_completion.d/task
rm -rf $(CURDIR)/debian/task/usr/share/doc/task-1.8.1
install -D -m644 task_completion.sh $(CURDIR)/debian/task/etc/bash_completion.d/task
rm -rf $(CURDIR)/debian/task/usr/share/doc/task-1.7.1
dh_strip
dh_compress
dh_fixperms

View File

@@ -48,6 +48,10 @@
# http://taskwarrior.org
#
_task_get_projects() {
task _projects
}
_task_get_tags() {
task _tags
}
@@ -56,10 +60,6 @@ _task_get_config() {
task _config
}
_task_offer_projects() {
COMPREPLY=( $(compgen -W "$(task _projects)" -- ${cur/*:/}) )
}
_task()
{
local cur prev opts base
@@ -67,61 +67,34 @@ _task()
COMPREPLY=()
cur="${COMP_WORDS[COMP_CWORD]}"
prev="${COMP_WORDS[COMP_CWORD-1]}"
if [ ${#COMP_WORDS[*]} -gt 2 ]
then
prev2="${COMP_WORDS[COMP_CWORD-2]}"
else
prev2=""
fi
# echo -e "\ncur='$cur'"
# echo "prev='$prev'"
# echo "prev2='$prev2'"
opts="$(task _commands) $(task _ids)"
case "${prev}" in
:)
case "${prev2}" in
pro*)
_task_offer_projects
return 0
;;
esac
case "${cur}" in
pro*:*)
local projects=$(_task_get_projects)
local partial_project="${cur/*:/}"
COMPREPLY=( $(compgen -W "${projects}" -- ${partial_project}) )
return 0
;;
*)
case "${cur}" in
pro*:*)
_task_offer_projects
return 0
;;
:)
case "${prev}" in
pro*)
_task_offer_projects
return 0
;;
esac
;;
+*)
local tags=$(_task_get_tags | sed 's/^/+/')
COMPREPLY=( $(compgen -W "${tags}" -- ${cur}) )
return 0
;;
-*)
local tags=$(_task_get_tags | sed 's/^/-/')
COMPREPLY=( $(compgen -W "${tags}" -- ${cur}) )
return 0
;;
rc.*)
local config=$(_task_get_config | sed -e 's/^/rc\./' -e 's/$/:/')
COMPREPLY=( $(compgen -W "${config}" -- ${cur}) )
return 0
;;
esac
+*)
local tags=$(_task_get_tags | sed 's/^/+/')
COMPREPLY=( $(compgen -W "${tags}" -- ${cur}) )
return 0
;;
-*)
local tags=$(_task_get_tags | sed 's/^/-/')
COMPREPLY=( $(compgen -W "${tags}" -- ${cur}) )
return 0
;;
rc.*)
local config=$(_task_get_config | sed 's/^/rc\./')
COMPREPLY=( $(compgen -W "${config}" -- ${cur}) )
return 0
;;
esac
COMPREPLY=( $(compgen -W "${opts}" -- ${cur}) )
return 0
}
complete -o nospace -F _task task
complete -F _task task

View File

@@ -407,17 +407,6 @@ std::string Att::type (const std::string& name) const
return "text";
}
////////////////////////////////////////////////////////////////////////////////
// The type of an attribute is useful for modifier evaluation.
std::string Att::modType (const std::string& name) const
{
if (name == "hasnt" ||
name == "isnt")
return "negative";
return "positive";
}
////////////////////////////////////////////////////////////////////////////////
//
// start --> name --> . --> mod --> : --> " --> value --> " --> end
@@ -472,7 +461,7 @@ void Att::parse (Nibbler& n)
else
throw std::string ("Missing : after attribute name"); // TODO i18n
/* TODO This might be too slow to include. Test this assumption.
/* TODO This might be too slow to include. Test.
validNameValue (mName, mMod, mValue);
*/
}
@@ -722,11 +711,8 @@ void Att::encode (std::string& value) const
while ((i = value.find ('\t')) != std::string::npos)
value.replace (i, 1, "&tab;"); // no i18n
while ((i = value.find ('\'')) != std::string::npos)
value.replace (i, 1, "&squot;"); // no i18n
while ((i = value.find ('"')) != std::string::npos)
value.replace (i, 1, "&dquot;"); // no i18n
value.replace (i, 1, "&quot;"); // no i18n
while ((i = value.find (',')) != std::string::npos)
value.replace (i, 1, "&comma;"); // no i18n
@@ -744,8 +730,7 @@ void Att::encode (std::string& value) const
////////////////////////////////////////////////////////////////////////////////
// Decode values after parse.
// \t <- &tab;
// " <- &quot; or &dquot;
// ' <- &squot;
// " <- &quot;
// , <- &comma;
// [ <- &open;
// ] <- &close;
@@ -757,12 +742,6 @@ void Att::decode (std::string& value) const
while ((i = value.find ("&tab;")) != std::string::npos) // no i18n
value.replace (i, 5, "\t");
while ((i = value.find ("&dquot;")) != std::string::npos) // no i18n
value.replace (i, 7, "\"");
while ((i = value.find ("&squot;")) != std::string::npos) // no i18n
value.replace (i, 7, "'");
while ((i = value.find ("&quot;")) != std::string::npos) // no i18n
value.replace (i, 6, "\"");

View File

@@ -50,7 +50,6 @@ public:
static bool validNameValue (std::string&, std::string&, std::string&);
static bool validMod (const std::string&);
std::string type (const std::string&) const;
std::string modType (const std::string&) const;
void parse (const std::string&);
void parse (Nibbler&);
bool match (const Att&) const;

View File

@@ -100,7 +100,7 @@ void Config::createDefaultRC (const std::string& rc, const std::string& data)
// Create a sample .taskrc file.
std::stringstream contents;
contents << "# Task program configuration file.\n"
<< "# For more documentation, see http://taskwarrior.org or try 'man task' and 'man taskrc'\n"
<< "# For more documentation, see http://taskwarrior.org\n"
<< "\n"
<< "# Files\n"
<< "data.location=" << data << "\n"
@@ -150,8 +150,8 @@ void Config::createDefaultRC (const std::string& rc, const std::string& data)
<< "#default.priority=M # Unless otherwise specified\n"
<< "default.command=list # Unless otherwise specified\n"
<< "\n"
<< "# Fields: id,uuid,project,priority,entry,start,due,recur,recurrence_indicator,age,\n"
<< "# age_compact,active,tags,tag_indicator,description,description_only\n"
<< "# Fields: id,uuid,project,priority,entry,start,due,recur,recur_ind,age,\n"
<< "# age_compact,active,tags,description,description_only\n"
<< "# Description: This report is ...\n"
<< "# Sort: due+,priority-,project+\n"
<< "# Filter: pro:x pri:H +bug limit:10\n"

View File

@@ -30,7 +30,6 @@
#include <pwd.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include "Context.h"
#include "Timer.h"
#include "text.h"
@@ -50,8 +49,6 @@ Context::Context ()
, tdb ()
, stringtable ()
, program ("")
, file_override ("")
, var_overrides ("")
, cmd ()
, inShadow (false)
{
@@ -67,7 +64,6 @@ void Context::initialize (int argc, char** argv)
{
// Capture the args.
for (int i = 0; i < argc; ++i)
{
if (i == 0)
{
program = argv[i];
@@ -78,7 +74,6 @@ void Context::initialize (int argc, char** argv)
}
else
args.push_back (argv[i]);
}
initialize ();
}
@@ -131,110 +126,98 @@ void Context::initialize ()
////////////////////////////////////////////////////////////////////////////////
int Context::run ()
{
int rc;
Timer t ("Context::run");
std::string output;
try
{
parse (); // Parse command line.
rc = dispatch (output); // Dispatch to command handlers.
parse (); // Parse command line.
output = dispatch (); // Dispatch to command handlers.
}
catch (const std::string& error)
{
footnote (error);
rc = 2;
}
catch (...)
{
footnote (stringtable.get (100, "Unknown error."));
rc = 3;
}
// Dump all debug messages.
if (config.get (std::string ("debug"), false))
foreach (d, debugMessages)
if (config.get ("color", true) || config.get (std::string ("_forcecolor"), false))
std::cout << colorizeDebug (*d) << std::endl;
else
std::cout << *d << std::endl;
std::cout << colorizeDebug (*d) << std::endl;
// Dump all headers.
foreach (h, headers)
if (config.get ("color", true) || config.get (std::string ("_forcecolor"), false))
std::cout << colorizeHeader (*h) << std::endl;
else
std::cout << *h << std::endl;
std::cout << colorizeHeader (*h) << std::endl;
// Dump the report output.
std::cout << output;
// Dump all footnotes.
foreach (f, footnotes)
if (config.get ("color", true) || config.get (std::string ("_forcecolor"), false))
std::cout << colorizeFootnote (*f) << std::endl;
else
std::cout << *f << std::endl;
std::cout << colorizeFootnote (*f) << std::endl;
return rc;
return 0;
}
////////////////////////////////////////////////////////////////////////////////
int Context::dispatch (std::string &out)
std::string Context::dispatch ()
{
int rc = 0;
Timer t ("Context::dispatch");
// TODO Just look at this thing. It cries out for a dispatch table.
if (cmd.command == "projects") { rc = handleProjects (out); }
else if (cmd.command == "tags") { rc = handleTags (out); }
else if (cmd.command == "colors") { rc = handleColor (out); }
else if (cmd.command == "version") { rc = handleVersion (out); }
else if (cmd.command == "help") { rc = longUsage (out); }
else if (cmd.command == "stats") { rc = handleReportStats (out); }
else if (cmd.command == "info") { rc = handleInfo (out); }
else if (cmd.command == "history") { rc = handleReportHistory (out); }
else if (cmd.command == "ghistory") { rc = handleReportGHistory (out); }
else if (cmd.command == "summary") { rc = handleReportSummary (out); }
else if (cmd.command == "calendar") { rc = handleReportCalendar (out); }
else if (cmd.command == "timesheet") { rc = handleReportTimesheet (out); }
else if (cmd.command == "add") { rc = handleAdd (out); }
else if (cmd.command == "append") { rc = handleAppend (out); }
else if (cmd.command == "annotate") { rc = handleAnnotate (out); }
else if (cmd.command == "done") { rc = handleDone (out); }
else if (cmd.command == "delete") { rc = handleDelete (out); }
else if (cmd.command == "start") { rc = handleStart (out); }
else if (cmd.command == "stop") { rc = handleStop (out); }
else if (cmd.command == "export") { rc = handleExport (out); }
else if (cmd.command == "import") { rc = handleImport (out); }
else if (cmd.command == "duplicate") { rc = handleDuplicate (out); }
else if (cmd.command == "edit") { rc = handleEdit (out); }
std::string out;
if (cmd.command == "projects") { out = handleProjects (); }
else if (cmd.command == "tags") { out = handleTags (); }
else if (cmd.command == "colors") { out = handleColor (); }
else if (cmd.command == "version") { out = handleVersion (); }
else if (cmd.command == "help") { out = longUsage (); }
else if (cmd.command == "stats") { out = handleReportStats (); }
else if (cmd.command == "info") { out = handleInfo (); }
else if (cmd.command == "history") { out = handleReportHistory (); }
else if (cmd.command == "ghistory") { out = handleReportGHistory (); }
else if (cmd.command == "summary") { out = handleReportSummary (); }
else if (cmd.command == "calendar") { out = handleReportCalendar (); }
else if (cmd.command == "timesheet") { out = handleReportTimesheet (); }
else if (cmd.command == "add") { out = handleAdd (); }
else if (cmd.command == "append") { out = handleAppend (); }
else if (cmd.command == "annotate") { out = handleAnnotate (); }
else if (cmd.command == "done") { out = handleDone (); }
else if (cmd.command == "delete") { out = handleDelete (); }
else if (cmd.command == "start") { out = handleStart (); }
else if (cmd.command == "stop") { out = handleStop (); }
else if (cmd.command == "export") { out = handleExport (); }
else if (cmd.command == "import") { out = handleImport (); }
else if (cmd.command == "duplicate") { out = handleDuplicate (); }
else if (cmd.command == "edit") { out = handleEdit (); }
#ifdef FEATURE_SHELL
else if (cmd.command == "shell") { handleShell ( ); }
else if (cmd.command == "shell") { handleShell (); }
#endif
else if (cmd.command == "undo") { handleUndo ( ); }
else if (cmd.command == "_projects") { rc = handleCompletionProjects (out); }
else if (cmd.command == "_tags") { rc = handleCompletionTags (out); }
else if (cmd.command == "_commands") { rc = handleCompletionCommands (out); }
else if (cmd.command == "_ids") { rc = handleCompletionIDs (out); }
else if (cmd.command == "_config") { rc = handleCompletionConfig (out); }
else if (cmd.command == "undo") { handleUndo (); }
else if (cmd.command == "_projects") { out = handleCompletionProjects (); }
else if (cmd.command == "_tags") { out = handleCompletionTags (); }
else if (cmd.command == "_commands") { out = handleCompletionCommands (); }
else if (cmd.command == "_ids") { out = handleCompletionIDs (); }
else if (cmd.command == "_config") { out = handleCompletionConfig (); }
else if (cmd.command == "" &&
sequence.size ()) { rc = handleModify (out); }
sequence.size ()) { out = handleModify (); }
// Command that display IDs and therefore need TDB::gc first.
else if (cmd.command == "next") { if (!inShadow) tdb.gc (); rc = handleReportNext (out); }
else if (cmd.validCustom (cmd.command)) { if (!inShadow) tdb.gc (); rc = handleCustomReport (cmd.command, out); }
else if (cmd.command == "next") { if (!inShadow) tdb.gc (); out = handleReportNext (); }
else if (cmd.validCustom (cmd.command)) { if (!inShadow) tdb.gc (); out = handleCustomReport (cmd.command); }
// If the command is not recognized, display usage.
else { rc = shortUsage (out); }
else { out = shortUsage (); }
// Only update the shadow file if such an update was not suppressed (shadow),
if (cmd.isWriteCommand () && !inShadow)
shadow ();
return rc;
return out;
}
////////////////////////////////////////////////////////////////////////////////
@@ -260,6 +243,8 @@ void Context::shadow ()
std::string oldCurses = config.get ("curses");
std::string oldColor = config.get ("color");
config.set ("curses", "off");
config.set ("color", "off");
clear ();
@@ -270,12 +255,8 @@ void Context::shadow ()
split (args, command, ' ');
initialize ();
config.set ("curses", "off");
config.set ("color", "off");
parse ();
std::string result;
(void)dispatch (result);
std::string result = dispatch ();
std::ofstream out (shadowFile.c_str ());
if (out.good ())
{
@@ -326,18 +307,6 @@ std::string Context::canonicalize (const std::string& input) const
return canonical;
}
////////////////////////////////////////////////////////////////////////////////
void Context::disallowModification () const
{
if (task.size () ||
subst.mFrom != "" ||
tagAdditions.size () ||
tagRemovals.size ())
throw std::string ("The '")
+ cmd.command
+ "' command does not allow further modification of a task.";
}
////////////////////////////////////////////////////////////////////////////////
void Context::loadCorrectConfigFile ()
{
@@ -353,23 +322,14 @@ void Context::loadCorrectConfigFile ()
std::string rc = home + "/.taskrc";
std::string data = home + "/.task";
// Is there an file_override for rc:?
// Is there an override for rc?
foreach (arg, args)
{
if (*arg == "--")
break;
else if (arg->substr (0, 3) == "rc:")
{
file_override = *arg;
rc = arg->substr (3, std::string::npos);
home = rc;
std::string::size_type last_slash = rc.rfind ("/");
if (last_slash != std::string::npos)
home = rc.substr (0, last_slash);
else
home = ".";
args.erase (arg);
header ("Using alternate .taskrc file " + rc); // TODO i18n
break;
@@ -384,7 +344,7 @@ void Context::loadCorrectConfigFile ()
if (config.get ("data.location") != "")
data = config.get ("data.location");
// Are there any var_overrides for data.location?
// Is there an override for data?
foreach (arg, args)
{
if (*arg == "--")
@@ -398,19 +358,13 @@ void Context::loadCorrectConfigFile ()
}
// Do we need to create a default rc?
if (access (rc.c_str (), F_OK))
if (access (rc.c_str (), F_OK) &&
confirm ("A configuration file could not be found in " // TODO i18n
+ home
+ "\n\n"
+ "Would you like a sample .taskrc created, so task can proceed?"))
{
if (confirm ("A configuration file could not be found in " // TODO i18n
+ home
+ "\n\n"
+ "Would you like a sample "
+ rc
+ " created, so task can proceed?"))
{
config.createDefaultRC (rc, data);
}
else
throw std::string ("Cannot proceed without rc file.");
config.createDefaultRC (rc, data);
}
// Create data location, if necessary.
@@ -444,7 +398,6 @@ void Context::loadCorrectConfigFile ()
n.getUntilEOS (value))
{
config.set (name, value);
var_overrides += " " + *arg;
footnote (std::string ("Configuration override ") + // TODO i18n
arg->substr (3, std::string::npos));
}
@@ -575,12 +528,7 @@ void Context::parse (
attribute.mod (mod);
attribute.value (value);
// Preserve modifier in the key, to allow multiple modifiers on the
// same attribute. Bug #252.
if (name != "" && mod != "")
parseTask[name + "." + mod] = attribute;
else
parseTask[name] = attribute;
parseTask[attribute.name ()] = attribute;
}
// *arg has the appearance of an attribute (foo:bar), but isn't
@@ -661,22 +609,15 @@ void Context::parse (
// then invoke the default command.
if (parseCmd.command == "" && parseArgs.size () == 0)
{
// Apply overrides, if any.
std::string defaultCommand = config.get ("default.command");
if (defaultCommand != "")
{
// Add on the overrides.
defaultCommand += " " + file_override + " " + var_overrides;
// Stuff the command line.
args.clear ();
split (args, defaultCommand, ' ');
parseArgs.clear ();
split (parseArgs, defaultCommand, ' ');
header ("[task " + defaultCommand + "]");
// Reinitialize the context and recurse.
file_override = "";
var_overrides = "";
footnotes.clear ();
initialize ();
parse (args, cmd, task, sequence, subst, filter);
}
@@ -701,8 +642,6 @@ void Context::clear ()
// stringtable.clear ();
program = "";
args.clear ();
file_override = "";
var_overrides = "";
cmd.command = "";
tagAdditions.clear ();
tagRemovals.clear ();
@@ -718,46 +657,46 @@ void Context::autoFilter (Task& t, Filter& f)
foreach (att, t)
{
// Words are found in the description using the .has modifier.
if (att->second.name () == "description" && att->second.mod () == "")
if (att->first == "description" && att->second.mod () == "")
{
std::vector <std::string> words;
split (words, att->second.value (), ' ');
foreach (word, words)
{
f.push_back (Att ("description", "has", *word));
debug ("auto filter: " + att->second.name () + ".has:" + *word);
debug ("auto filter: " + att->first + ".has:" + *word);
}
}
// Projects are matched left-most.
else if (att->second.name () == "project" && att->second.mod () == "")
else if (att->first == "project" && att->second.mod () == "")
{
if (att->second.value () != "")
{
f.push_back (Att ("project", "startswith", att->second.value ()));
debug ("auto filter: " + att->second.name () + ".startswith:" + att->second.value ());
debug ("auto filter: " + att->first + ".startswith:" + att->second.value ());
}
else
{
f.push_back (Att ("project", "is", att->second.value ()));
debug ("auto filter: " + att->second.name () + ".is:" + att->second.value ());
debug ("auto filter: " + att->first + ".is:" + att->second.value ());
}
}
// The limit attribute does not participate in filtering, and needs to be
// specifically handled in handleCustomReport.
else if (att->second.name () == "limit")
else if (att->first == "limit")
{
}
// Every task has a unique uuid by default, and it shouldn't be included,
// because it is guaranteed to not match.
else if (att->second.name () == "uuid")
else if (att->first == "uuid")
{
}
// The mechanism for filtering on tags is +/-<tag>.
else if (att->second.name () == "tags")
else if (att->first == "tags")
{
}
@@ -766,7 +705,7 @@ void Context::autoFilter (Task& t, Filter& f)
{
f.push_back (att->second);
debug ("auto filter: " +
att->second.name () +
att->first +
(att->second.mod () != "" ?
("." + att->second.mod () + ":") :
":") +

View File

@@ -50,7 +50,7 @@ public:
void initialize (); // for reinitializing
int run (); // task classic
int interactive (); // task interactive (not implemented)
int dispatch (std::string&); // command handler dispatch
std::string dispatch (); // command handler dispatch
void shadow (); // shadow file update
int getWidth (); // determine terminal width
@@ -65,7 +65,6 @@ public:
void clear ();
std::string canonicalize (const std::string&) const;
void disallowModification () const;
private:
void loadCorrectConfigFile ();
@@ -83,8 +82,6 @@ public:
StringTable stringtable;
std::string program;
std::vector <std::string> args;
std::string file_override;
std::string var_overrides;
Cmd cmd;
std::map <std::string, std::string> aliases;
std::vector <std::string> tagAdditions;

View File

@@ -29,7 +29,6 @@
#include <time.h>
#include <assert.h>
#include <stdlib.h>
#include <ctype.h>
#include "Date.h"
#include "text.h"
#include "util.h"
@@ -83,14 +82,14 @@ Date::Date (const std::string& mdy, const std::string& format /* = "m/d/Y" */)
// Single or double digit.
case 'm':
if (i >= mdy.length () ||
! isdigit (mdy[i]))
! ::isdigit (mdy[i]))
{
throw std::string ("\"") + mdy + "\" is not a valid date.";
}
if (i + 1 < mdy.length () &&
(mdy[i + 0] == '0' || mdy[i + 0] == '1') &&
isdigit (mdy[i + 1]))
::isdigit (mdy[i + 1]))
{
month = ::atoi (mdy.substr (i, 2).c_str ());
i += 2;
@@ -104,14 +103,14 @@ Date::Date (const std::string& mdy, const std::string& format /* = "m/d/Y" */)
case 'd':
if (i >= mdy.length () ||
! isdigit (mdy[i]))
! ::isdigit (mdy[i]))
{
throw std::string ("\"") + mdy + "\" is not a valid date.";
}
if (i + 1 < mdy.length () &&
(mdy[i + 0] == '0' || mdy[i + 0] == '1' || mdy[i + 0] == '2' || mdy[i + 0] == '3') &&
isdigit (mdy[i + 1]))
::isdigit (mdy[i + 1]))
{
day = ::atoi (mdy.substr (i, 2).c_str ());
i += 2;
@@ -126,8 +125,8 @@ Date::Date (const std::string& mdy, const std::string& format /* = "m/d/Y" */)
// Double digit.
case 'y':
if (i + 1 >= mdy.length () ||
! isdigit (mdy[i + 0]) ||
! isdigit (mdy[i + 1]))
! ::isdigit (mdy[i + 0]) ||
! ::isdigit (mdy[i + 1]))
{
throw std::string ("\"") + mdy + "\" is not a valid date.";
}
@@ -138,8 +137,8 @@ Date::Date (const std::string& mdy, const std::string& format /* = "m/d/Y" */)
case 'M':
if (i + 1 >= mdy.length () ||
! isdigit (mdy[i + 0]) ||
! isdigit (mdy[i + 1]))
! ::isdigit (mdy[i + 0]) ||
! ::isdigit (mdy[i + 1]))
{
throw std::string ("\"") + mdy + "\" is not a valid date.";
}
@@ -150,8 +149,8 @@ Date::Date (const std::string& mdy, const std::string& format /* = "m/d/Y" */)
case 'D':
if (i + 1 >= mdy.length () ||
! isdigit (mdy[i + 0]) ||
! isdigit (mdy[i + 1]))
! ::isdigit (mdy[i + 0]) ||
! ::isdigit (mdy[i + 1]))
{
throw std::string ("\"") + mdy + "\" is not a valid date.";
}
@@ -163,10 +162,10 @@ Date::Date (const std::string& mdy, const std::string& format /* = "m/d/Y" */)
// Quadruple digit.
case 'Y':
if (i + 3 >= mdy.length () ||
! isdigit (mdy[i + 0]) ||
! isdigit (mdy[i + 1]) ||
! isdigit (mdy[i + 2]) ||
! isdigit (mdy[i + 3]))
! ::isdigit (mdy[i + 0]) ||
! ::isdigit (mdy[i + 1]) ||
! ::isdigit (mdy[i + 2]) ||
! ::isdigit (mdy[i + 3]))
{
throw std::string ("\"") + mdy + "\" is not a valid date.";
}

View File

@@ -51,6 +51,12 @@ Duration::Duration (const std::string& input)
parse (input);
}
////////////////////////////////////////////////////////////////////////////////
Duration::operator int ()
{
return (int) mDays;
}
////////////////////////////////////////////////////////////////////////////////
Duration::operator time_t ()
{

View File

@@ -40,6 +40,7 @@ public:
bool operator> (const Duration&);
~Duration (); // Destructor
operator int ();
operator time_t ();
operator std::string ();

View File

@@ -40,51 +40,37 @@ bool Filter::pass (const Record& record) const
// First do description/annotation matches.
foreach (att, (*this))
{
// Descriptions have special handling such that they are linked to
// annotations, and filtering on description implies identical filtering
// on annotations, and that both filter matches must succeed for the filter
// to succeed overall.
// Descriptions have special handling.
if (att->name () == "description")
{
bool description_result = true;
int annotation_pass_count = 0;
int annotation_fail_count = 0;
if ((r = record.find (att->name ())) != record.end ())
{
description_result = att->match (r->second);
foreach (ra, record)
// A description match failure can be salvaged by an annotation match.
if (! att->match (r->second))
{
if (ra->first.length () > 11 &&
ra->first.substr (0, 11) == "annotation_")
bool annoMatch = false;
foreach (ra, record)
{
if (att->match (ra->second))
++annotation_pass_count;
else
++annotation_fail_count;
if (ra->first.length () > 11 &&
ra->first.substr (0, 11) == "annotation_")
{
if (att->match (ra->second))
{
annoMatch = true;
break;
}
}
}
if (!annoMatch)
return false;
}
}
else if (! att->match (Att ()))
return false;
// This innocuous little if-else took significantly more thinking and
// debugging than anything else in task. Only change this code if you
// are willing to invest a week understanding and testing it.
if (att->modType (att->mod ()) == "positive")
{
if (! (description_result || annotation_pass_count > 0))
return false;
}
else
{
if (!description_result || annotation_fail_count > 0)
return false;
}
}
// Annotations are skipped, because they are handled above.
// Annotations are skipped.
else if (att->name ().length () > 11 &&
att->name ().substr (0, 11) == "annotation_")
{

View File

@@ -243,7 +243,7 @@ bool Nibbler::getInt (int& result)
++i;
}
while (i < mInput.length () && isdigit (mInput[i]))
while (i < mInput.length () && ::isdigit (mInput[i]))
++i;
if (i > mCursor)
@@ -260,7 +260,7 @@ bool Nibbler::getInt (int& result)
bool Nibbler::getUnsignedInt (int& result)
{
std::string::size_type i = mCursor;
while (i < mInput.length () && isdigit (mInput[i]))
while (i < mInput.length () && ::isdigit (mInput[i]))
++i;
if (i > mCursor)

View File

@@ -37,7 +37,6 @@ extern Context context;
Permission::Permission ()
: needConfirmation (false)
, allConfirmed (false)
, quit (false)
{
// Turning confirmations off is the same as entering "all".
if (context.config.get ("confirmation", true) == false)
@@ -47,9 +46,6 @@ Permission::Permission ()
////////////////////////////////////////////////////////////////////////////////
bool Permission::confirmed (const Task& task, const std::string& question)
{
if (quit)
return false;
if (!needConfirmation)
return true;
@@ -61,25 +57,16 @@ bool Permission::confirmed (const Task& task, const std::string& question)
<< task.id
<< " \""
<< task.get ("description")
<< "\"";
<< "\""
<< std::endl;
if (task.getStatus () == Task::recurring ||
task.has ("parent"))
{
std::cout << " (Recurring)";
}
std::cout << std::endl;
int answer = confirm4 (question);
int answer = confirm3 (question);
if (answer == 2)
allConfirmed = true;
if (answer == 1 || answer == 2)
if (answer > 0)
return true;
if (answer == 3)
quit = true;
return false;
}

View File

@@ -44,7 +44,6 @@ public:
private:
bool needConfirmation;
bool allConfirmed;
bool quit;
};
#endif

View File

@@ -153,7 +153,7 @@ bool Sequence::validId (const std::string& input) const
return false;
for (size_t i = 0; i < input.length (); ++i)
if (!isdigit (input[i]))
if (!::isdigit (input[i]))
return false;
return true;

View File

@@ -876,7 +876,7 @@ void Table::sort (std::vector <int>& order)
if (gap > 1)
{
gap = (int) ((float)gap / 1.3);
if (gap == 10 || gap == 9)
if (gap == 10 or gap == 9)
gap = 11;
}

View File

@@ -67,8 +67,8 @@ bool Task::operator== (const Task& other)
return false;
foreach (att, *this)
if (att->second.name () != "uuid")
if (att->second.value () != other.get (att->second.name ()))
if (att->first != "uuid")
if (att->second.value () != other.get (att->first))
return false;
return true;
@@ -134,7 +134,7 @@ void Task::setEntry ()
}
////////////////////////////////////////////////////////////////////////////////
Task::status Task::getStatus () const
Task::status Task::getStatus ()
{
return textToStatus (get ("status")); // No i18n
}
@@ -363,12 +363,12 @@ std::string Task::composeCSV () const
out << get ("start") << ","; // No i18n
if (has ("due"))
out << get ("due") << ","; // No i18n
out << "'" << get ("due") << "',"; // No i18n
else
out << ","; // No i18n
if (has ("recur"))
out << get ("recur") << ","; // No i18n
out << "'" << get ("recur") << "',"; // No i18n
else
out << ","; // No i18n
@@ -441,14 +441,10 @@ void Task::addAnnotation (const std::string& description)
void Task::removeAnnotations ()
{
// Erase old annotations.
Record::iterator i = this->begin ();
while (i != this->end ())
{
Record::iterator i;
for (i = this->begin (); i != this->end (); ++i)
if (i->first.substr (0, 11) == "annotation_") // No i18n
this->erase (i++);
else
i++;
}
this->erase (i);
}
////////////////////////////////////////////////////////////////////////////////
@@ -527,7 +523,7 @@ void Task::validate () const
if (!has ("uuid") ||
!has ("entry") ||
!has ("description"))
throw std::string ("A task must have a description in order to be valid."); // TODO i18n
throw std::string ("A task must have a uuid, entry date and description in order to be valid."); // TODO i18n
if (get ("description") == "") // No i18n
throw std::string ("Cannot add a task that is blank, or contains <CR> or <LF> characters."); // TODO i18n

View File

@@ -57,7 +57,7 @@ public:
void setEntry ();
status getStatus () const;
status getStatus ();
void setStatus (status);
int getTagCount ();

View File

@@ -52,7 +52,7 @@ Timer::~Timer ()
<< mDescription
<< " "
<< std::setprecision (6)
// << std::fixed
<< std::fixed
<< ((end.tv_sec - mStart.tv_sec) + ((end.tv_usec - mStart.tv_usec )
/ 1000000.0))
<< " sec";

View File

@@ -49,7 +49,7 @@
extern Context context;
////////////////////////////////////////////////////////////////////////////////
int handleAdd (std::string &outs)
std::string handleAdd ()
{
std::stringstream out;
@@ -84,15 +84,6 @@ int handleAdd (std::string &outs)
foreach (tag, context.tagAdditions)
context.task.addTag (*tag);
// Perform some logical consistency checks.
if (context.task.has ("recur") &&
!context.task.has ("due"))
throw std::string ("You cannot specify a recurring task without a due date.");
if (context.task.has ("until") &&
!context.task.has ("recur"))
throw std::string ("You cannot specify an until date for a non-recurring task.");
// Only valid tasks can be added.
context.task.validate ();
@@ -110,20 +101,19 @@ int handleAdd (std::string &outs)
context.tdb.commit ();
context.tdb.unlock ();
outs = out.str ();
return 0;
return out.str ();
}
////////////////////////////////////////////////////////////////////////////////
int handleProjects (std::string &outs)
std::string handleProjects ()
{
int rc = 0;
std::stringstream out;
context.filter.push_back (Att ("status", "pending"));
std::vector <Task> tasks;
context.tdb.lock (context.config.get ("locking", true));
handleRecurrence ();
int quantity = context.tdb.loadPending (tasks, context.filter);
context.tdb.commit ();
context.tdb.unlock ();
@@ -197,21 +187,19 @@ int handleProjects (std::string &outs)
<< " (" << quantity << (quantity == 1 ? " task" : " tasks") << ")"
<< std::endl;
}
else {
else
out << "No projects."
<< std::endl;
rc = 1;
}
outs = out.str ();
return rc;
return out.str ();
}
////////////////////////////////////////////////////////////////////////////////
int handleCompletionProjects (std::string &outs)
std::string handleCompletionProjects ()
{
std::vector <Task> tasks;
context.tdb.lock (context.config.get ("locking", true));
handleRecurrence ();
Filter filter;
if (context.config.get (std::string ("complete.all.projects"), false))
@@ -233,20 +221,19 @@ int handleCompletionProjects (std::string &outs)
if (project->first.length ())
out << project->first << std::endl;
outs = out.str ();
return 0;
return out.str ();
}
////////////////////////////////////////////////////////////////////////////////
int handleTags (std::string &outs)
std::string handleTags ()
{
int rc = 0;
std::stringstream out;
context.filter.push_back (Att ("status", "pending"));
std::vector <Task> tasks;
context.tdb.lock (context.config.get ("locking", true));
handleRecurrence ();
int quantity = context.tdb.loadPending (tasks, context.filter);
context.tdb.commit ();
context.tdb.unlock ();
@@ -297,22 +284,19 @@ int handleTags (std::string &outs)
<< " (" << quantity << (quantity == 1 ? " task" : " tasks") << ")"
<< std::endl;
}
else {
else
out << "No tags."
<< std::endl;
rc = 1;
}
outs = out.str ();
return rc;
return out.str ();
}
////////////////////////////////////////////////////////////////////////////////
int handleCompletionTags (std::string &outs)
std::string handleCompletionTags ()
{
std::vector <Task> tasks;
context.tdb.lock (context.config.get ("locking", true));
handleRecurrence ();
Filter filter;
if (context.config.get (std::string ("complete.all.tags"), false))
@@ -339,12 +323,11 @@ int handleCompletionTags (std::string &outs)
foreach (tag, unique)
out << tag->first << std::endl;
outs = out.str ();
return 0;
return out.str ();
}
////////////////////////////////////////////////////////////////////////////////
int handleCompletionCommands (std::string &outs)
std::string handleCompletionCommands ()
{
std::vector <std::string> commands;
context.cmd.allCommands (commands);
@@ -354,12 +337,11 @@ int handleCompletionCommands (std::string &outs)
foreach (command, commands)
out << *command << std::endl;
outs = out.str ();
return 0;
return out.str ();
}
////////////////////////////////////////////////////////////////////////////////
int handleCompletionConfig (std::string &outs)
std::string handleCompletionConfig ()
{
std::vector <std::string> configs;
context.config.all (configs);
@@ -369,15 +351,15 @@ int handleCompletionConfig (std::string &outs)
foreach (config, configs)
out << *config << std::endl;
outs = out.str ();
return 0;
return out.str ();
}
////////////////////////////////////////////////////////////////////////////////
int handleCompletionIDs (std::string &outs)
std::string handleCompletionIDs ()
{
std::vector <Task> tasks;
context.tdb.lock (context.config.get ("locking", true));
handleRecurrence ();
Filter filter;
context.tdb.loadPending (tasks, filter);
context.tdb.commit ();
@@ -395,24 +377,20 @@ int handleCompletionIDs (std::string &outs)
foreach (id, ids)
out << *id << std::endl;
outs = out.str ();
return 0;
return out.str ();
}
////////////////////////////////////////////////////////////////////////////////
void handleUndo ()
{
context.disallowModification ();
context.tdb.lock (context.config.get ("locking", true));
context.tdb.undo ();
context.tdb.unlock ();
}
////////////////////////////////////////////////////////////////////////////////
int handleVersion (std::string &outs)
std::string handleVersion ()
{
int rc = 0;
std::stringstream out;
// Create a table for the disclaimer.
@@ -436,7 +414,7 @@ int handleVersion (std::string &outs)
link.addCell (link.addRow (), 0,
"See http://taskwarrior.org for the latest releases, online documentation "
"and lively discussion. New releases containing fixes and enhancements "
"are made frequently. Don't forget the man pages 'man task' and 'man taskrc'.");
"are made frequently.");
std::vector <std::string> all;
context.config.all (all);
@@ -499,8 +477,8 @@ int handleVersion (std::string &outs)
" blanklines bulk color color.active color.due color.overdue color.pri.H "
"color.pri.L color.pri.M color.pri.none color.recurring color.tagged "
"color.footnote color.header color.debug confirmation curses data.location "
"dateformat debug default.command default.priority default.project defaultwidth "
"due locale displayweeknumber echo.command locking monthsperline nag next project "
"dateformat debug default.command default.priority defaultwidth due locale "
"displayweeknumber echo.command locking monthsperline nag next project "
"shadow.command shadow.file shadow.notify weekstart editor import.synonym.id "
"import.synonym.uuid longversion complete.all.projects complete.all.tags "
#ifdef FEATURE_SHELL
@@ -540,7 +518,7 @@ int handleVersion (std::string &outs)
if (unrecognized.size ())
{
out << "Your .taskrc file contains these unrecognized variables:"
<< std::endl;
<< std::endl;
foreach (i, unrecognized)
out << " " << *i << std::endl;
@@ -551,11 +529,9 @@ int handleVersion (std::string &outs)
// Verify installation. This is mentioned in the documentation as the way to
// ensure everything is properly installed.
if (all.size () == 0) {
if (all.size () == 0)
out << "Configuration error: .taskrc contains no entries"
<< std::endl;
rc = 1;
}
else
{
if (context.config.get ("data.location") == "")
@@ -569,20 +545,17 @@ int handleVersion (std::string &outs)
<< std::endl;
}
outs = out.str ();
return rc;
return out.str ();
}
////////////////////////////////////////////////////////////////////////////////
int handleDelete (std::string &outs)
std::string handleDelete ()
{
int rc = 0;
std::stringstream out;
context.disallowModification ();
std::vector <Task> tasks;
context.tdb.lock (context.config.get ("locking", true));
handleRecurrence ();
Filter filter;
context.tdb.loadPending (tasks, filter);
@@ -665,29 +638,24 @@ int handleDelete (std::string &outs)
<< std::endl;
}
}
else {
else
out << "Task not deleted." << std::endl;
rc = 1;
}
}
context.tdb.commit ();
context.tdb.unlock ();
outs = out.str ();
return rc;
return out.str ();
}
////////////////////////////////////////////////////////////////////////////////
int handleStart (std::string &outs)
std::string handleStart ()
{
int rc = 0;
std::stringstream out;
context.disallowModification ();
std::vector <Task> tasks;
context.tdb.lock (context.config.get ("locking", true));
handleRecurrence ();
Filter filter;
context.tdb.loadPending (tasks, filter);
@@ -723,27 +691,23 @@ int handleStart (std::string &outs)
<< task->get ("description")
<< "' already started."
<< std::endl;
rc = 1;
}
}
context.tdb.commit ();
context.tdb.unlock ();
outs = out.str ();
return rc;
return out.str ();
}
////////////////////////////////////////////////////////////////////////////////
int handleStop (std::string &outs)
std::string handleStop ()
{
int rc = 0;
std::stringstream out;
context.disallowModification ();
std::vector <Task> tasks;
context.tdb.lock (context.config.get ("locking", true));
handleRecurrence ();
Filter filter;
context.tdb.loadPending (tasks, filter);
@@ -773,26 +737,24 @@ int handleStop (std::string &outs)
<< task->get ("description")
<< "' not started."
<< std::endl;
rc = 1;
}
}
context.tdb.commit ();
context.tdb.unlock ();
outs = out.str ();
return rc;
return out.str ();
}
////////////////////////////////////////////////////////////////////////////////
int handleDone (std::string &outs)
std::string handleDone ()
{
int rc = 0;
int count = 0;
std::stringstream out;
std::vector <Task> tasks;
context.tdb.lock (context.config.get ("locking", true));
handleRecurrence ();
Filter filter;
context.tdb.loadPending (tasks, filter);
@@ -829,7 +791,7 @@ int handleDone (std::string &outs)
if (taskDiff (before, *task))
{
if (permission.confirmed (before, taskDifferences (before, *task) + "Proceed with change?"))
if (permission.confirmed (before, taskDifferences (before, *task) + "Are you sure?"))
{
context.tdb.update (*task);
@@ -856,7 +818,6 @@ int handleDone (std::string &outs)
<< task->get ("description")
<< "' is not pending"
<< std::endl;
rc = 1;
}
context.tdb.commit ();
@@ -870,12 +831,11 @@ int handleDone (std::string &outs)
<< " as done"
<< std::endl;
outs = out.str ();
return rc;
return out.str ();
}
////////////////////////////////////////////////////////////////////////////////
int handleExport (std::string &outs)
std::string handleExport ()
{
std::stringstream out;
@@ -914,18 +874,18 @@ int handleExport (std::string &outs)
}
}
outs = out.str ();
return 0;
return out.str ();
}
////////////////////////////////////////////////////////////////////////////////
int handleModify (std::string &outs)
std::string handleModify ()
{
int count = 0;
std::stringstream out;
std::vector <Task> tasks;
context.tdb.lock (context.config.get ("locking", true));
handleRecurrence ();
Filter filter;
context.tdb.loadPending (tasks, filter);
@@ -950,15 +910,6 @@ int handleModify (std::string &outs)
!task->has ("recur"))
throw std::string ("You cannot specify an until date for a non-recurring task.");
if (task->has ("due") &&
!context.task.has ("due") &&
context.task.has ("recur"))
throw std::string ("You cannot remove the due date from a recurring task.");
if (task->has ("recur") &&
!context.task.has ("recur"))
throw std::string ("You cannot remove the recurrence from a recurring task.");
// Make all changes.
foreach (other, all)
{
@@ -967,13 +918,6 @@ int handleModify (std::string &outs)
task->get ("parent") == other->get ("parent")) || // Sibling
other->get ("uuid") == task->get ("parent")) // Parent
{
if (task->has ("parent"))
std::cout << "Task "
<< task->id
<< " is a recurring task, and all other instances of this"
<< " task may be modified."
<< std::endl;
Task before (*other);
// A non-zero value forces a file write.
@@ -992,7 +936,7 @@ int handleModify (std::string &outs)
if (taskDiff (before, *other))
{
if (changes && permission.confirmed (before, taskDifferences (before, *other) + "Proceed with change?"))
if (changes && permission.confirmed (before, taskDifferences (before, *other) + "Are you sure?"))
{
context.tdb.update (*other);
++count;
@@ -1008,18 +952,18 @@ int handleModify (std::string &outs)
if (context.config.get ("echo.command", true))
out << "Modified " << count << " task" << (count == 1 ? "" : "s") << std::endl;
outs = out.str ();
return 0;
return out.str ();
}
////////////////////////////////////////////////////////////////////////////////
int handleAppend (std::string &outs)
std::string handleAppend ()
{
int count = 0;
std::stringstream out;
std::vector <Task> tasks;
context.tdb.lock (context.config.get ("locking", true));
handleRecurrence ();
Filter filter;
context.tdb.loadPending (tasks, filter);
@@ -1052,7 +996,7 @@ int handleAppend (std::string &outs)
if (taskDiff (before, *other))
{
if (changes && permission.confirmed (before, taskDifferences (before, *other) + "Proceed with change?"))
if (changes && permission.confirmed (before, taskDifferences (before, *other) + "Are you sure?"))
{
context.tdb.update (*other);
@@ -1076,12 +1020,11 @@ int handleAppend (std::string &outs)
if (context.config.get ("echo.command", true))
out << "Appended " << count << " task" << (count == 1 ? "" : "s") << std::endl;
outs = out.str ();
return 0;
return out.str ();
}
////////////////////////////////////////////////////////////////////////////////
int handleDuplicate (std::string &outs)
std::string handleDuplicate ()
{
std::stringstream out;
int count = 0;
@@ -1140,23 +1083,13 @@ int handleDuplicate (std::string &outs)
++count;
}
if (context.config.get ("echo.command", true))
{
out << "Duplicated " << count << " task" << (count == 1 ? "" : "s") << std::endl;
#ifdef FEATURE_NEW_ID
// All this, just for an id number.
std::vector <Task> all;
Filter none;
context.tdb.loadPending (all, none);
out << "Created task " << context.tdb.nextId () << std::endl;
#endif
}
context.tdb.commit ();
context.tdb.unlock ();
outs = out.str ();
return 0;
if (context.config.get ("echo.command", true))
out << "Duplicated " << count << " task" << (count == 1 ? "" : "s") << std::endl;
return out.str ();
}
////////////////////////////////////////////////////////////////////////////////
@@ -1178,9 +1111,13 @@ void handleShell ()
<< std::endl
<< std::endl;
// Make a copy because context.clear will delete them.
std::string permanentOverrides = " " + context.file_override
+ " " + context.var_overrides;
// Preserve any special override arguments, and reapply them for each
// shell command.
std::vector <std::string> special;
foreach (arg, context.args)
if (arg->substr (0, 3) == "rc." ||
arg->substr (0, 3) == "rc:")
special.push_back (*arg);
std::string quit = "quit"; // TODO i18n
std::string command;
@@ -1192,13 +1129,11 @@ void handleShell ()
command = "";
std::getline (std::cin, command);
std::string decoratedCommand = trim (command + permanentOverrides);
command = lowerCase (trim (command));
// When looking for the 'quit' command, use 'command', not
// 'decoratedCommand'.
if (command.length () > 0 &&
command.length () <= quit.length () &&
lowerCase (command) == quit.substr (0, command.length ()))
if (command.length () > 0 &&
command.length () <= quit.length () &&
command == quit.substr (0, command.length ()))
{
keepGoing = false;
}
@@ -1209,7 +1144,8 @@ void handleShell ()
context.clear ();
std::vector <std::string> args;
split (args, decoratedCommand, ' ');
split (args, command, ' ');
foreach (arg, special) context.args.push_back (*arg);
foreach (arg, args) context.args.push_back (*arg);
context.initialize ();
@@ -1228,16 +1164,12 @@ void handleShell ()
}
}
while (keepGoing && !std::cin.eof ());
// No need to repeat any overrides after the shell quits.
context.clearMessages ();
}
#endif
////////////////////////////////////////////////////////////////////////////////
int handleColor (std::string &outs)
std::string handleColor ()
{
int rc = 0;
std::stringstream out;
if (context.config.get ("color", true) || context.config.get (std::string ("_forcecolor"), false))
{
@@ -1319,15 +1251,13 @@ int handleColor (std::string &outs)
out << "Color is currently turned off in your .taskrc file. "
"To enable color, create the entry 'color=on'."
<< std::endl;
rc = 1;
}
outs = out.str ();
return rc;
return out.str ();
}
////////////////////////////////////////////////////////////////////////////////
int handleAnnotate (std::string &outs)
std::string handleAnnotate ()
{
if (!context.task.has ("description"))
throw std::string ("Cannot apply a blank annotation.");
@@ -1353,7 +1283,7 @@ int handleAnnotate (std::string &outs)
if (taskDiff (before, *task))
{
if (permission.confirmed (before, taskDifferences (before, *task) + "Proceed with change?"))
if (permission.confirmed (before, taskDifferences (before, *task) + "Are you sure?"))
{
context.tdb.update (*task);
@@ -1371,8 +1301,7 @@ int handleAnnotate (std::string &outs)
context.tdb.commit ();
context.tdb.unlock ();
outs = out.str ();
return 0;
return out.str ();
}
////////////////////////////////////////////////////////////////////////////////
@@ -1430,12 +1359,12 @@ int deltaAttributes (Task& task)
foreach (att, context.task)
{
if (att->second.name () != "uuid" &&
att->second.name () != "description" &&
att->second.name () != "tags")
if (att->first != "uuid" &&
att->first != "description" &&
att->first != "tags")
{
// Modifying "wait" changes status.
if (att->second.name () == "wait")
if (att->first == "wait")
{
if (att->second.value () == "")
task.setStatus (Task::pending);
@@ -1444,9 +1373,8 @@ int deltaAttributes (Task& task)
}
if (att->second.value () == "")
task.remove (att->second.name ());
task.remove (att->first);
else
// One of the few places where the compound attribute name is used.
task.set (att->first, att->second.value ());
++changes;

View File

@@ -52,7 +52,7 @@ static std::vector <std::string> customReports;
////////////////////////////////////////////////////////////////////////////////
// This report will eventually become the one report that many others morph into
// via the .taskrc file.
int handleCustomReport (const std::string& report, std::string &outs)
std::string handleCustomReport (const std::string& report)
{
// Load report configuration.
std::string columnList = context.config.get ("report." + report + ".columns");
@@ -94,24 +94,21 @@ int handleCustomReport (const std::string& report, std::string &outs)
labelList,
sortList,
filterList,
tasks,
outs);
tasks);
}
////////////////////////////////////////////////////////////////////////////////
// This report will eventually become the one report that many others morph into
// via the .taskrc file.
int runCustomReport (
std::string runCustomReport (
const std::string& report,
const std::string& columnList,
const std::string& labelList,
const std::string& sortList,
const std::string& filterList,
std::vector <Task>& tasks,
std::string &outs)
std::vector <Task>& tasks)
{
int rc = 0;
// Load report configuration.
std::vector <std::string> columns;
split (columns, columnList, ',');
@@ -461,7 +458,6 @@ int runCustomReport (
std::string column = sortColumn->substr (0, sortColumn->length () - 1);
char direction = (*sortColumn)[sortColumn->length () - 1];
// TODO This code should really be using Att::type.
if (column == "id")
table.sortOn (columnIndex[column],
(direction == '+' ?
@@ -475,7 +471,7 @@ int runCustomReport (
Table::descendingPriority));
else if (column == "entry" || column == "start" || column == "due" ||
column == "wait" || column == "until" || column == "end")
column == "wait")
table.sortOn (columnIndex[column],
(direction == '+' ?
Table::ascendingDate :
@@ -551,14 +547,11 @@ int runCustomReport (
<< table.rowCount ()
<< (table.rowCount () == 1 ? " task" : " tasks")
<< std::endl;
else {
else
out << "No matches."
<< std::endl;
rc = 1;
}
outs = out.str ();
return rc;
return out.str ();
}
////////////////////////////////////////////////////////////////////////////////

View File

@@ -150,7 +150,7 @@ static std::string formatTask (Task task)
<< " Due: " << formatDate (task, "due") << std::endl
<< " Until: " << formatDate (task, "until") << std::endl
<< " Recur: " << task.get ("recur") << std::endl
<< " Wait until: " << formatDate (task, "wait") << std::endl
<< " Wait until: " << task.get ("wait") << std::endl
<< " Parent: " << task.get ("parent") << std::endl
<< " Foreground color: " << task.get ("fg") << std::endl
<< " Background color: " << task.get ("bg") << std::endl
@@ -499,13 +499,7 @@ static void parseTask (Task& task, const std::string& after)
std::string::size_type gap = value.find (" ");
if (gap != std::string::npos)
{
Date when (value.substr (0, gap), context.config.get ("dateformat", "m/d/Y"));
// This guarantees that if more than one annotation has the same date,
// that the seconds will be different, thus unique, thus not squashed.
// Bug #249
when += (const int) annotations.size ();
Date when (value.substr (0, gap));
std::stringstream name;
name << "annotation_" << when.toEpoch ();
std::string text = trim (value.substr (gap, std::string::npos), "\t ");
@@ -543,7 +537,7 @@ void editFile (Task& task)
// Complete the command line.
editor += " ";
editor += "\"" + file.str () + "\"";
editor += file.str ();
ARE_THESE_REALLY_HARMFUL:
// Launch the editor.
@@ -599,7 +593,7 @@ ARE_THESE_REALLY_HARMFUL:
// Introducing the Silver Bullet. This feature is the catch-all fixative for
// various other ills. This is like opening up the hood and going in with a
// wrench. To be used sparingly.
int handleEdit (std::string &outs)
std::string handleEdit ()
{
std::stringstream out;
@@ -643,8 +637,7 @@ int handleEdit (std::string &outs)
context.tdb.commit ();
context.tdb.unlock ();
outs = out.str ();
return 0;
return out.str ();
}
////////////////////////////////////////////////////////////////////////////////

View File

@@ -106,16 +106,16 @@ static fileType determineFileType (const std::vector <std::string>& lines)
{
if ( lines[i][0] == 'x' &&
lines[i][1] == ' ' &&
isdigit (lines[i][2]) &&
isdigit (lines[i][3]) &&
isdigit (lines[i][4]) &&
isdigit (lines[i][5]) &&
::isdigit (lines[i][2]) &&
::isdigit (lines[i][3]) &&
::isdigit (lines[i][4]) &&
::isdigit (lines[i][5]) &&
lines[i][6] == '-' &&
isdigit (lines[i][7]) &&
isdigit (lines[i][8]) &&
::isdigit (lines[i][7]) &&
::isdigit (lines[i][8]) &&
lines[i][9] == '-' &&
isdigit (lines[i][10]) &&
isdigit (lines[i][11]))
::isdigit (lines[i][10]) &&
::isdigit (lines[i][11]))
return todo_sh_2_0;
}
@@ -126,13 +126,13 @@ static fileType determineFileType (const std::vector <std::string>& lines)
// +project
if (words[w].length () > 1 &&
words[w][0] == '+' &&
isalnum (words[w][1]))
::isalnum (words[w][1]))
return todo_sh_2_0;
// @context
if (words[w].length () > 1 &&
words[w][0] == '@' &&
isalnum (words[w][1]))
::isalnum (words[w][1]))
return todo_sh_2_0;
}
}
@@ -666,7 +666,6 @@ static std::string importTask_1_6_0 (const std::vector <std::string>& lines)
static std::string importTaskCmdLine (const std::vector <std::string>& lines)
{
std::vector <std::string> failed;
std::string unused;
std::vector <std::string>::const_iterator it;
for (it = lines.begin (); it != lines.end (); ++it)
@@ -681,7 +680,7 @@ static std::string importTaskCmdLine (const std::vector <std::string>& lines)
context.task.clear ();
context.cmd.command = "";
context.parse ();
(void)handleAdd (unused);
handleAdd ();
context.clearMessages ();
}
@@ -790,8 +789,6 @@ static std::string importTodoSh_2_0 (const std::vector <std::string>& lines)
context.parse ();
decorateTask (context.task);
context.task.set ("uuid", uuid ());
if (isPending)
{
context.task.setStatus (Task::pending);
@@ -1147,7 +1144,7 @@ static std::string importCSV (const std::vector <std::string>& lines)
}
////////////////////////////////////////////////////////////////////////////////
int handleImport (std::string &outs)
std::string handleImport ()
{
std::stringstream out;
@@ -1215,8 +1212,7 @@ int handleImport (std::string &outs)
else
throw std::string ("You must specify a file to import.");
outs = out.str ();
return 0;
return out.str ();
}
////////////////////////////////////////////////////////////////////////////////

View File

@@ -34,7 +34,7 @@
#include "Context.h"
//#include "text.h"
//#include "util.h"
#include "main.h"
//#include "main.h"
#include "i18n.h"
#include "../auto.h"

View File

@@ -55,25 +55,25 @@ int getDueState (const std::string&);
bool nag (Task&);
// command.cpp
int handleAdd (std::string &);
int handleAppend (std::string &);
int handleExport (std::string &);
int handleDone (std::string &);
int handleModify (std::string &);
int handleProjects (std::string &);
int handleCompletionProjects (std::string &);
int handleTags (std::string &);
int handleCompletionTags (std::string &);
int handleCompletionCommands (std::string &);
int handleCompletionIDs (std::string &);
int handleCompletionConfig (std::string &);
int handleVersion (std::string &);
int handleDelete (std::string &);
int handleStart (std::string &);
int handleStop (std::string &);
int handleColor (std::string &);
int handleAnnotate (std::string &);
int handleDuplicate (std::string &);
std::string handleAdd ();
std::string handleAppend ();
std::string handleExport ();
std::string handleDone ();
std::string handleModify ();
std::string handleProjects ();
std::string handleCompletionProjects ();
std::string handleTags ();
std::string handleCompletionTags ();
std::string handleCompletionCommands ();
std::string handleCompletionIDs ();
std::string handleCompletionConfig ();
std::string handleVersion ();
std::string handleDelete ();
std::string handleStart ();
std::string handleStop ();
std::string handleColor ();
std::string handleAnnotate ();
std::string handleDuplicate ();
void handleUndo ();
#ifdef FEATURE_SHELL
void handleShell ();
@@ -85,28 +85,27 @@ int deltaAttributes (Task&);
int deltaSubstitutions (Task&);
// edit.cpp
int handleEdit (std::string &);
std::string handleEdit ();
// report.cpp
int shortUsage (std::string &);
int longUsage (std::string &);
int handleInfo (std::string &);
int handleReportSummary (std::string &);
int handleReportNext (std::string &);
int handleReportHistory (std::string &);
int handleReportGHistory (std::string &);
int handleReportCalendar (std::string &);
int handleReportStats (std::string &);
int handleReportTimesheet (std::string &);
std::string shortUsage ();
std::string longUsage ();
std::string handleInfo ();
std::string handleReportSummary ();
std::string handleReportNext ();
std::string handleReportHistory ();
std::string handleReportGHistory ();
std::string handleReportCalendar ();
std::string handleReportStats ();
std::string handleReportTimesheet ();
std::string getFullDescription (Task&);
std::string getDueDate (Task&);
// custom.cpp
int handleCustomReport (const std::string&, std::string &);
int runCustomReport (const std::string&, const std::string&,
const std::string&, const std::string&,
const std::string&, std::vector <Task>&,
std::string&);
std::string handleCustomReport (const std::string&);
std::string runCustomReport (const std::string&, const std::string&,
const std::string&, const std::string&,
const std::string&, std::vector <Task>&);
void validReportColumns (const std::vector <std::string>&);
void validSortColumns (const std::vector <std::string>&, const std::vector <std::string>&);
@@ -119,7 +118,7 @@ std::string colorizeFootnote (const std::string&);
std::string colorizeDebug (const std::string&);
// import.cpp
int handleImport (std::string&);
std::string handleImport ();
// list template
///////////////////////////////////////////////////////////////////////////////

View File

@@ -50,7 +50,7 @@
extern Context context;
////////////////////////////////////////////////////////////////////////////////
int shortUsage (std::string &outs)
std::string shortUsage ()
{
Table table;
@@ -209,19 +209,14 @@ int shortUsage (std::string &outs)
<< std::endl
<< std::endl;
outs = out.str ();
return 0;
return out.str ();
}
////////////////////////////////////////////////////////////////////////////////
int longUsage (std::string &outs)
std::string longUsage ()
{
std::string shortUsageString;
std::stringstream out;
(void)shortUsage(shortUsageString);
out << shortUsageString
out << shortUsage ()
<< "ID is the numeric identifier displayed by the 'task list' command. "
<< "You can specify multiple IDs for task commands, and multiple tasks "
<< "will be affected. To specify multiple IDs make sure you use one "
@@ -281,15 +276,13 @@ int longUsage (std::string &outs)
<< " $ ! ' \" ( ) ; \\ ` * ? { } [ ] < > | & % # ~" << "\n"
<< std::endl;
outs = out.str();
return 0;
return out.str ();
}
////////////////////////////////////////////////////////////////////////////////
// Display all information for the given task.
int handleInfo (std::string &outs)
std::string handleInfo ()
{
int rc = 0;
// Get all the tasks.
std::vector <Task> tasks;
context.tdb.lock (context.config.get ("locking", true));
@@ -504,22 +497,18 @@ int handleInfo (std::string &outs)
<< std::endl;
}
if (! tasks.size ()) {
if (! tasks.size ())
out << "No matches." << std::endl;
rc = 1;
}
outs = out.str ();
return rc;
return out.str ();
}
////////////////////////////////////////////////////////////////////////////////
// Project Remaining Avg Age Complete 0% 100%
// A 12 13d 55% XXXXXXXXXXXXX-----------
// B 109 3d 12h 10% XXX---------------------
int handleReportSummary (std::string &outs)
std::string handleReportSummary ()
{
int rc = 0;
// Scan the pending tasks.
std::vector <Task> tasks;
context.tdb.lock (context.config.get ("locking", true));
@@ -659,13 +648,10 @@ int handleReportSummary (std::string &outs)
<< table.rowCount ()
<< (table.rowCount () == 1 ? " project" : " projects")
<< std::endl;
else {
else
out << "No projects." << std::endl;
rc = 1;
}
outs = out.str ();
return rc;
return out.str ();
}
////////////////////////////////////////////////////////////////////////////////
@@ -687,7 +673,7 @@ int handleReportSummary (std::string &outs)
//
// Make the "three" tasks a configurable number
//
int handleReportNext (std::string &outs)
std::string handleReportNext ()
{
// Load report configuration.
std::string columnList = context.config.get ("report.next.columns");
@@ -732,8 +718,7 @@ int handleReportNext (std::string &outs)
labelList,
sortList,
filterList,
tasks,
outs);
tasks);
}
////////////////////////////////////////////////////////////////////////////////
@@ -759,9 +744,8 @@ time_t monthlyEpoch (const std::string& date)
return 0;
}
int handleReportHistory (std::string &outs)
std::string handleReportHistory ()
{
int rc = 0;
std::map <time_t, int> groups; // Represents any month with data
std::map <time_t, int> addedGroup; // Additions by month
std::map <time_t, int> completedGroup; // Completions by month
@@ -907,19 +891,15 @@ int handleReportHistory (std::string &outs)
out << optionalBlankLine ()
<< table.render ()
<< std::endl;
else {
else
out << "No tasks." << std::endl;
rc = 1;
}
outs = out.str ();
return rc;
return out.str ();
}
////////////////////////////////////////////////////////////////////////////////
int handleReportGHistory (std::string &outs)
std::string handleReportGHistory ()
{
int rc = 0;
std::map <time_t, int> groups; // Represents any month with data
std::map <time_t, int> addedGroup; // Additions by month
std::map <time_t, int> completedGroup; // Completions by month
@@ -1107,17 +1087,14 @@ int handleReportGHistory (std::string &outs)
else
out << "Legend: + added, X completed, - deleted" << std::endl;
}
else {
else
out << "No tasks." << std::endl;
rc = 1;
}
outs = out.str ();
return rc;
return out.str ();
}
////////////////////////////////////////////////////////////////////////////////
int handleReportTimesheet (std::string &outs)
std::string handleReportTimesheet ()
{
// Scan the pending tasks.
std::vector <Task> tasks;
@@ -1287,8 +1264,7 @@ int handleReportTimesheet (std::string &outs)
end -= 7 * 86400;
}
outs = out.str ();
return 0;
return out.str ();
}
////////////////////////////////////////////////////////////////////////////////
@@ -1400,9 +1376,9 @@ std::string renderMonths (
row = 0;
// Loop through days in month and add to table.
for (int d = 1; d <= daysInMonth[mpl]; ++d)
for (int d = 1; d <= daysInMonth.at (mpl); ++d)
{
Date temp (months[mpl], d, years[mpl]);
Date temp (months.at (mpl), d, years.at (mpl));
int dow = temp.dayOfWeek ();
int woy = temp.weekOfYear (weekStart);
@@ -1420,9 +1396,9 @@ std::string renderMonths (
table.addCell (row, thisCol, d);
if ((context.config.get ("color", true) || context.config.get (std::string ("_forcecolor"), false)) &&
today.day () == d &&
today.month () == months[mpl] &&
today.year () == years[mpl])
today.day () == d &&
today.month () == months.at (mpl) &&
today.year () == years.at (mpl))
table.setCellFg (row, thisCol, Text::cyan);
foreach (task, all)
@@ -1434,8 +1410,8 @@ std::string renderMonths (
if ((context.config.get ("color", true) || context.config.get (std::string ("_forcecolor"), false)) &&
due.day () == d &&
due.month () == months[mpl] &&
due.year () == years[mpl])
due.month () == months.at (mpl) &&
due.year () == years.at (mpl))
{
table.setCellFg (row, thisCol, Text::black);
table.setCellBg (row, thisCol, due < today ? Text::on_red : Text::on_yellow);
@@ -1447,7 +1423,7 @@ std::string renderMonths (
int eow = 6;
if (weekStart == 1)
eow = 0;
if (dow == eow && d < daysInMonth[mpl])
if (dow == eow && d < daysInMonth.at (mpl))
row++;
}
}
@@ -1456,7 +1432,7 @@ std::string renderMonths (
}
////////////////////////////////////////////////////////////////////////////////
int handleReportCalendar (std::string &outs)
std::string handleReportCalendar ()
{
// Each month requires 28 text columns width. See how many will actually
// fit. But if a preference is specified, and it fits, use it.
@@ -1628,12 +1604,11 @@ int handleReportCalendar (std::string &outs)
<< optionalBlankLine ()
<< std::endl;
outs = out.str ();
return 0;
return out.str ();
}
////////////////////////////////////////////////////////////////////////////////
int handleReportStats (std::string &outs)
std::string handleReportStats ()
{
std::stringstream out;
@@ -1861,8 +1836,7 @@ int handleReportStats (std::string &outs)
<< table.render ()
<< optionalBlankLine ();
outs = out.str ();
return 0;
return out.str ();
}
////////////////////////////////////////////////////////////////////////////////

View File

@@ -91,8 +91,6 @@ void autoColorize (
// Note: fg, bg already contain colors specifically assigned via command.
// Note: These rules form a hierarchy - the last rule is King.
Task::status status = task.getStatus ();
// Colorization of the tagged.
if (gsFg["color.tagged"] != Text::nocolor ||
gsBg["color.tagged"] != Text::nocolor)
@@ -148,11 +146,9 @@ void autoColorize (
}
}
// Colorization of the active, if not completed/deleted.
if ((gsFg["color.active"] != Text::nocolor ||
gsBg["color.active"] != Text::nocolor) &&
status != Task::completed &&
status != Task::deleted)
// Colorization of the active.
if (gsFg["color.active"] != Text::nocolor ||
gsBg["color.active"] != Text::nocolor)
{
if (task.has ("start"))
{
@@ -206,9 +202,7 @@ void autoColorize (
}
// Colorization of the due and overdue.
if (task.has ("due") &&
status != Task::completed &&
status != Task::deleted)
if (task.has ("due"))
{
std::string due = task.get ("due");
switch (getDueState (due))

View File

@@ -75,9 +75,9 @@ int main (int argc, char** argv)
Att a5 ("name", "value");
t.is (a5.composeF4 (), "name:\"value\"", "Att::composeF4 simple");
a5.value ("\"");
t.is (a5.composeF4 (), "name:\"&dquot;\"", "Att::composeF4 encoded \"");
t.is (a5.composeF4 (), "name:\"&quot;\"", "Att::composeF4 encoded \"");
a5.value ("\t\",[]:");
t.is (a5.composeF4 (), "name:\"&tab;&dquot;&comma;&open;&close;&colon;\"", "Att::composeF4 fully encoded \\t\",[]:");
t.is (a5.composeF4 (), "name:\"&tab;&quot;&comma;&open;&close;&colon;\"", "Att::composeF4 fully encoded \\t\",[]:");
Att a6 ("name", 6);
t.is (a6.value_int (), 6, "Att::value_int get");
@@ -174,12 +174,12 @@ int main (int argc, char** argv)
n = Nibbler ("name:\"&quot;\"");
a7.parse (n);
t.is (a7.composeF4 (), "name:\"&dquot;\"",
t.is (a7.composeF4 (), "name:\"&quot;\"",
"Att::parse (name:\"&quot;\")");
n = Nibbler ("name:\"&tab;&quot;&comma;&open;&close;&colon;\"");
a7.parse (n);
t.is (a7.composeF4 (), "name:\"&tab;&dquot;&comma;&open;&close;&colon;\"",
t.is (a7.composeF4 (), "name:\"&tab;&quot;&comma;&open;&close;&colon;\"",
"Att::parse (name:\"&tab;&quot;&comma;&open;&close;&colon;\")");
n = Nibbler ("total gibberish");
@@ -216,19 +216,19 @@ int main (int argc, char** argv)
good = true;
try {a7.parse (n);} catch (...) {good = false;}
t.ok (good, "Att::parse (name:\"value)");
t.is (a7.composeF4 (), "name:\"&dquot;value\"", "Att::composeF4 -> name:\"&dquot;value\"");
t.is (a7.composeF4 (), "name:\"&quot;value\"", "Att::composeF4 -> name:\"&quot;value\"");
n = Nibbler ("name:value\"");
good = true;
try {a7.parse (n);} catch (...) {good = false;}
t.ok (good, "Att::parse (name:value\")");
t.is (a7.composeF4 (), "name:\"value&dquot;\"", "Att::composeF4 -> name:\"value&dquot;\"");
t.is (a7.composeF4 (), "name:\"value&quot;\"", "Att::composeF4 -> name:\"value&quot;\"");
n = Nibbler ("name:val\"ue");
good = true;
try {a7.parse (n);} catch (...) {good = false;}
t.ok (good, "Att::parse (name:val\"ue)");
t.is (a7.composeF4 (), "name:\"val&dquot;ue\"", "Att::composeF4 -> name:\"val&dquot;ue\"");
t.is (a7.composeF4 (), "name:\"val&quot;ue\"", "Att::composeF4 -> name:\"val&quot;ue\"");
n = Nibbler ("name\"");
good = true;

View File

@@ -40,7 +40,7 @@ if (open my $fh, '>', 'basic.rc')
# Test the usage command.
my $output = qx{../task rc:basic.rc};
like ($output, qr/You must specify a command, or a task ID to modify/m, 'missing command and ID');
like ($output, qr/You must specify a command, or a task ID to modify/, 'missing command and ID');
# Test the version command.
$output = qx{../task rc:basic.rc version};

View File

@@ -1,66 +0,0 @@
#! /usr/bin/perl
################################################################################
## task - a command line task list manager.
##
## Copyright 2006 - 2009, Paul Beckingham.
## All rights reserved.
##
## This program is free software; you can redistribute it and/or modify it under
## the terms of the GNU General Public License as published by the Free Software
## Foundation; either version 2 of the License, or (at your option) any later
## version.
##
## This program is distributed in the hope that it will be useful, but WITHOUT
## ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
## FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
## details.
##
## You should have received a copy of the GNU General Public License along with
## this program; if not, write to the
##
## Free Software Foundation, Inc.,
## 51 Franklin Street, Fifth Floor,
## Boston, MA
## 02110-1301
## USA
##
################################################################################
use strict;
use warnings;
use Test::More tests => 6;
# Create the rc file.
if (open my $fh, '>', 'bug.rc')
{
print $fh "data.location=.\n",
"confirmation=no\n";
close $fh;
ok (-r 'bug.rc', 'Created bug.rc');
}
# Setup: Add a recurring task then remove the due date.
qx{../task rc:bug.rc add foo recur:yearly due:eoy};
qx{../task rc:bug.rc li};
qx{../task rc:bug.rc 2 due:};
# Result: Somehow the due date is incremented and wraps around to 12/31/1969,
# then keeps going back to today.
my $output = qx{../task rc:bug.rc li};
like ($output, qr/^1 task$/ms, 'Should only be one task');
# Cleanup.
unlink 'pending.data';
ok (!-r 'pending.data', 'Removed pending.data');
unlink 'completed.data';
ok (!-r 'completed.data', 'Removed completed.data');
unlink 'undo.data';
ok (!-r 'undo.data', 'Removed undo.data');
unlink 'bug.rc';
ok (!-r 'bug.rc', 'Removed bug.rc');
exit 0;

View File

@@ -28,7 +28,7 @@
use strict;
use warnings;
use Test::More tests => 15;
use Test::More tests => 14;
# Create the rc file.
if (open my $fh, '>', 'bulk.rc')
@@ -49,13 +49,13 @@ qx{../task rc:bulk.rc add t4 due:thursday};
qx{../task rc:bulk.rc add t5 due:friday};
qx{../task rc:bulk.rc add t6 due:saturday};
my $output = qx{echo "quit"|../task rc:bulk.rc pro:p1 pri:M 4 5 6};
like ($output, qr/Modified 0 tasks/, '"quit" prevents any further modifications');
my $output = qx{echo "all"|../task rc:bulk.rc pro:p1 pri:M 4 5 6};
my $output = qx{yes|../task rc:bulk.rc pro:p1 pri:M 4 5 6};
unlike ($output, qr/Task 4 "t4"\n - No changes were made/, 'Task 4 modified');
unlike ($output, qr/Task 5 "t5"\n - No changes were made/, 'Task 5 modified');
unlike ($output, qr/Task 6 "t6"\n - No changes were made/, 'Task 6 modified');
#diag ("---");
#diag ($output);
#diag ("---");
$output = qx{../task rc:bulk.rc info 4};
like ($output, qr/Project\s+p1/, 'project applied to 4');

View File

@@ -1,106 +0,0 @@
#! /usr/bin/perl
################################################################################
## task - a command line task list manager.
##
## Copyright 2006 - 2009, Paul Beckingham.
## All rights reserved.
##
## This program is free software; you can redistribute it and/or modify it under
## the terms of the GNU General Public License as published by the Free Software
## Foundation; either version 2 of the License, or (at your option) any later
## version.
##
## This program is distributed in the hope that it will be useful, but WITHOUT
## ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
## FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
## details.
##
## You should have received a copy of the GNU General Public License along with
## this program; if not, write to the
##
## Free Software Foundation, Inc.,
## 51 Franklin Street, Fifth Floor,
## Boston, MA
## 02110-1301
## USA
##
################################################################################
use strict;
use warnings;
use Test::More tests => 19;
# Create the rc file.
if (open my $fh, '>', 'hasnt.rc')
{
print $fh "data.location=.\n",
"confirmation=no\n";
close $fh;
ok (-r 'hasnt.rc', 'Created hasnt.rc');
}
# 1
qx{../task rc:hasnt.rc add foo};
# 2
qx{../task rc:hasnt.rc add foo};
qx{../task rc:hasnt.rc 2 annotate bar};
# 3
qx{../task rc:hasnt.rc add foo};
qx{../task rc:hasnt.rc 3 annotate bar};
sleep 2;
qx{../task rc:hasnt.rc 3 annotate baz};
# 4
qx{../task rc:hasnt.rc add bar};
# 5
qx{../task rc:hasnt.rc add bar};
qx{../task rc:hasnt.rc 5 annotate foo};
# 6
qx{../task rc:hasnt.rc add bar};
qx{../task rc:hasnt.rc 6 annotate foo};
sleep 2;
qx{../task rc:hasnt.rc 6 annotate baz};
#7
qx{../task rc:hasnt.rc add one};
qx{../task rc:hasnt.rc 7 annotate two};
sleep 2;
qx{../task rc:hasnt.rc 7 annotate three};
my $output = qx{../task rc:hasnt.rc ls description.has:foo};
like ($output, qr/\n 1/, '1 has foo -> yes');
like ($output, qr/\n 2/, '2 has foo -> yes');
like ($output, qr/\n 3/, '3 has foo -> yes');
unlike ($output, qr/\n 4/, '4 has foo -> no');
like ($output, qr/\n 5/, '5 has foo -> yes');
like ($output, qr/\n 6/, '6 has foo -> yes');
unlike ($output, qr/\n 7/, '7 has foo -> no');
$output = qx{../task rc:hasnt.rc ls description.hasnt:foo};
unlike ($output, qr/\n 1/, '1 hasnt foo -> no');
unlike ($output, qr/\n 2/, '2 hasnt foo -> no');
unlike ($output, qr/\n 3/, '3 hasnt foo -> no');
like ($output, qr/\n 4/, '4 hasnt foo -> yes');
unlike ($output, qr/\n 5/, '5 hasnt foo -> no');
unlike ($output, qr/\n 6/, '6 hasnt foo -> no');
like ($output, qr/\n 7/, '7 hasnt foo -> yes');
# Cleanup.
unlink 'pending.data';
ok (!-r 'pending.data', 'Removed pending.data');
unlink 'completed.data';
ok (!-r 'completed.data', 'Removed completed.data');
unlink 'undo.data';
ok (!-r 'undo.data', 'Removed undo.data');
unlink 'hasnt.rc';
ok (!-r 'hasnt.rc', 'Removed hasnt.rc');
exit 0;

View File

@@ -1,65 +0,0 @@
#! /usr/bin/perl
################################################################################
## task - a command line task list manager.
##
## Copyright 2006 - 2009, Paul Beckingham.
## All rights reserved.
##
## This program is free software; you can redistribute it and/or modify it under
## the terms of the GNU General Public License as published by the Free Software
## Foundation; either version 2 of the License, or (at your option) any later
## version.
##
## This program is distributed in the hope that it will be useful, but WITHOUT
## ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
## FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
## details.
##
## You should have received a copy of the GNU General Public License along with
## this program; if not, write to the
##
## Free Software Foundation, Inc.,
## 51 Franklin Street, Fifth Floor,
## Boston, MA
## 02110-1301
## USA
##
################################################################################
use strict;
use warnings;
use Test::More tests => 8;
# Create the rc file.
if (open my $fh, '>', 'range.rc')
{
print $fh "data.location=.\n",
"confirmation=no\n";
close $fh;
ok (-r 'range.rc', 'Created range.rc');
}
# Add three tasks, and attempt to list the middle one within a range.
qx{../task rc:range.rc add one due:8/1/2009};
qx{../task rc:range.rc add two due:8/3/2009};
qx{../task rc:range.rc add three due:8/5/2009};
my $output = qx{../task rc:range.rc ls due.after:8/2/2009 due.before:8/4/2009};
unlike ($output, qr/one/, 'Missing prior to range');
like ($output, qr/two/, 'Found within range');
unlike ($output, qr/three/, 'Missing after range');
# Cleanup.
unlink 'pending.data';
ok (!-r 'pending.data', 'Removed pending.data');
unlink 'completed.data';
ok (!-r 'completed.data', 'Removed completed.data');
unlink 'undo.data';
ok (!-r 'undo.data', 'Removed undo.data');
unlink 'range.rc';
ok (!-r 'range.rc', 'Removed range.rc');
exit 0;

View File

@@ -1,61 +0,0 @@
#! /usr/bin/perl
################################################################################
## task - a command line task list manager.
##
## Copyright 2006 - 2009, Paul Beckingham.
## All rights reserved.
##
## This program is free software; you can redistribute it and/or modify it under
## the terms of the GNU General Public License as published by the Free Software
## Foundation; either version 2 of the License, or (at your option) any later
## version.
##
## This program is distributed in the hope that it will be useful, but WITHOUT
## ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
## FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
## details.
##
## You should have received a copy of the GNU General Public License along with
## this program; if not, write to the
##
## Free Software Foundation, Inc.,
## 51 Franklin Street, Fifth Floor,
## Boston, MA
## 02110-1301
## USA
##
################################################################################
use strict;
use warnings;
use Test::More tests => 6;
# Create the rc file.
if (open my $fh, '>', 'recur.rc')
{
print $fh "data.location=.\n",
"confirmation=no\n";
close $fh;
ok (-r 'recur.rc', 'Created recur.rc');
}
# Add a recurring task with no due date, look for expected error.
qx{../task rc:recur.rc add foo recur:daily};
my $output = qx{../task rc:recur.rc info 1};
unlike ($output, qr/Description\s+foo/, 'task not created - missing due date');
# Cleanup.
unlink 'pending.data';
ok (!-r 'pending.data', 'Removed pending.data');
unlink 'completed.data';
ok (!-r 'completed.data', 'Removed completed.data');
unlink 'undo.data';
ok (!-r 'undo.data', 'Removed undo.data');
unlink 'recur.rc';
ok (!-r 'recur.rc', 'Removed recur.rc');
exit 0;

View File

@@ -1,62 +0,0 @@
#! /usr/bin/perl
################################################################################
## task - a command line task list manager.
##
## Copyright 2006 - 2009, Paul Beckingham.
## All rights reserved.
##
## This program is free software; you can redistribute it and/or modify it under
## the terms of the GNU General Public License as published by the Free Software
## Foundation; either version 2 of the License, or (at your option) any later
## version.
##
## This program is distributed in the hope that it will be useful, but WITHOUT
## ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
## FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
## details.
##
## You should have received a copy of the GNU General Public License along with
## this program; if not, write to the
##
## Free Software Foundation, Inc.,
## 51 Franklin Street, Fifth Floor,
## Boston, MA
## 02110-1301
## USA
##
################################################################################
use strict;
use warnings;
use Test::More tests => 7;
# Create the rc file.
if (open my $fh, '>', 'extra.rc')
{
print $fh "data.location=.\n",
"confirmation=no\n";
close $fh;
ok (-r 'extra.rc', 'Created extra.rc');
}
qx{../task rc:extra.rc add foo};
my $output = qx{../task rc:extra.rc 1 start pri:L};
like ($output, qr/The 'start' command does not allow further modification of a task\./, 'no modifications allowed for start');
$output = qx{../task rc:extra.rc 1 stop pro:bar};
like ($output, qr/The 'stop' command does not allow further modification of a task\./, 'no modifications allowed for stop');
# Cleanup.
unlink 'pending.data';
ok (!-r 'pending.data', 'Removed pending.data');
unlink 'completed.data';
ok (!-r 'completed.data', 'Removed completed.data');
unlink 'undo.data';
ok (!-r 'undo.data', 'Removed undo.data');
unlink 'extra.rc';
ok (!-r 'extra.rc', 'Removed extra.rc');
exit 0;

View File

@@ -58,7 +58,7 @@ if ( $day <= 9)
# task cal and task cal y
my $output = qx{../task rc:cal.rc rc._forcecolor:on cal};
like ($output, qr/\[36m$day/, 'Current day is highlighted');
like ($output, qr/$month\w+?\s+?$year/, 'Current month and year are displayed');
like ($output, qr/$month.* $year/, 'Current month and year are displayed');
qx{../task rc:cal.rc add zero};
unlike ($output, qr/\[41m\d+/, 'No overdue tasks are present');
unlike ($output, qr/\[43m\d+/, 'No due tasks are present');
@@ -67,9 +67,9 @@ like ($output, qr/Su Mo Tu/, 'Week starts on Sunday');
$output = qx{../task rc:cal.rc rc.weekstart:Monday cal};
like ($output, qr/Fr Sa Su/, 'Week starts on Monday');
$output = qx{../task rc:cal.rc cal y};
like ($output, qr/$month\w+?\s+?$year/, 'Current month and year are displayed');
like ($output, qr/$prevmonth\w+?\s+?$nextyear/, 'Month and year one year ahead are displayed');
unlike ($output, qr/$month\w+?\s+?$nextyear/, 'Current month and year ahead are not displayed');
like ($output, qr/$month.* $year/, 'Current month and year are displayed');
like ($output, qr/$prevmonth.* $nextyear/, 'Month and year one year ahead are displayed');
unlike ($output, qr/$month.* $nextyear/, 'Current month and year ahead are not displayed');
# task cal due and task cal due y
qx{../task rc:cal.rc add due:20190515 one};

View File

@@ -49,10 +49,10 @@ if (open my $fh, '>', 'response.txt')
qx{../task rc:confirm.rc add foo} for 1 .. 10;
# Test the various forms of "Yes".
my $output = qx{echo "Yes" | ../task rc:confirm.rc del 1};
like ($output, qr/Permanently delete task 1 'foo'\? \(y\/n\)/, 'confirmation - Yes works');
unlike ($output, qr/Task not deleted\./, 'confirmation - Yes works');
# Test the various forms of "yes".
my $output = qx{echo "yes" | ../task rc:confirm.rc del 1};
like ($output, qr/Permanently delete task 1 'foo'\? \(y\/n\)/, 'confirmation - yes works');
unlike ($output, qr/Task not deleted\./, 'confirmation - yes works');
$output = qx{echo "ye" | ../task rc:confirm.rc del 2};
like ($output, qr/Permanently delete task 2 'foo'\? \(y\/n\)/, 'confirmation - ye works');

View File

@@ -42,7 +42,7 @@ if (open my $fh, '>', 'custom.rc')
ok (-r 'custom.rc', 'Created custom.rc');
}
# Add a recurring and non-recurring task, look for the indicator.
# Generate the usage screen, and locate the custom report on it.
qx{../task rc:custom.rc add foo due:tomorrow recur:weekly};
qx{../task rc:custom.rc add bar};
my $output = qx{../task rc:custom.rc foo 2>&1};

View File

@@ -34,7 +34,7 @@ use Test::More tests => 17;
if (open my $fh, '>', 'default.rc')
{
print $fh "data.location=.\n",
"default.command=list\n",
"default.command=rc:default.rc list\n",
"default.project=PROJECT\n",
"default.priority=M\n";
close $fh;

View File

@@ -28,7 +28,7 @@
use strict;
use warnings;
use Test::More tests => 15;
use Test::More tests => 12;
# Create the rc file.
if (open my $fh, '>', 'dup.rc')
@@ -55,12 +55,6 @@ like ($output, qr/Description\s+FOO/, 'duplicate modified description');
like ($output, qr/Priority\s+H/, 'duplicate added priority');
like ($output, qr/Tags\s+tag/, 'duplicate added tag');
# Test the output of the duplicate command - returning id of duplicated task
$output = qx{../task rc:dup.rc duplicate 1};
like ($output, qr/Duplicated\s+1\s+'foo'/, 'duplicate output task id and description');
like ($output, qr/Duplicated\s+1\s+task/, 'duplicate output number of tasks duplicated');
like ($output, qr/Created\s+task\s+4/, 'duplicate output of new task id');
# Cleanup.
unlink 'pending.data';
ok (!-r 'pending.data', 'Removed pending.data');

View File

@@ -1,62 +0,0 @@
#! /usr/bin/perl
################################################################################
## task - a command line task list manager.
##
## Copyright 2006 - 2009, Paul Beckingham.
## All rights reserved.
##
## This program is free software; you can redistribute it and/or modify it under
## the terms of the GNU General Public License as published by the Free Software
## Foundation; either version 2 of the License, or (at your option) any later
## version.
##
## This program is distributed in the hope that it will be useful, but WITHOUT
## ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
## FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
## details.
##
## You should have received a copy of the GNU General Public License along with
## this program; if not, write to the
##
## Free Software Foundation, Inc.,
## 51 Franklin Street, Fifth Floor,
## Boston, MA
## 02110-1301
## USA
##
################################################################################
use strict;
use warnings;
use Test::More tests => 7;
# Create the rc file.
if (open my $fh, '>', 'exit.rc')
{
print $fh "data.location=.\n",
"confirmation=no\n";
close $fh;
ok (-r 'exit.rc', 'Created exit.rc');
}
qx{../task rc:exit.rc add foo};
my $exit_good = system ('../task rc:exit.rc ls foo 2>&1 >>/dev/null');
is ($exit_good, 0, 'task returns 0 on success');
my $exit_bad = system ('../task rc:exit.rc ls bar 2>&1 >>/dev/null');
isnt ($exit_bad, 0, 'task returns non-zero on failure');
# Cleanup.
unlink 'pending.data';
ok (!-r 'pending.data', 'Removed pending.data');
unlink 'completed.data';
ok (!-r 'completed.data', 'Removed completed.data');
unlink 'undo.data';
ok (!-r 'undo.data', 'Removed undo.data');
unlink 'exit.rc';
ok (!-r 'exit.rc', 'Removed exit.rc');
exit 0;

View File

@@ -111,25 +111,52 @@ unlike ($output, qr/six/, 'g6');
unlike ($output, qr/seven/, 'g7');
$output = qx{../task rc:filter.rc list -tag};
unlike ($output, qr/one/, 'h1');
like ($output, qr/two/, 'h2');
like ($output, qr/three/, 'h3');
like ($output, qr/four/, 'h4');
unlike ($output, qr/five/, 'h5');
like ($output, qr/six/, 'h6');
like ($output, qr/seven/, 'h7');
unlike ($output, qr/one/, 'g1');
like ($output, qr/two/, 'g2');
like ($output, qr/three/, 'g3');
like ($output, qr/four/, 'g4');
unlike ($output, qr/five/, 'g5');
like ($output, qr/six/, 'g6');
like ($output, qr/seven/, 'g7');
$output = qx{../task rc:filter.rc list -missing};
like ($output, qr/one/, 'i1');
like ($output, qr/two/, 'i2');
like ($output, qr/three/, 'i3');
like ($output, qr/four/, 'i4');
like ($output, qr/five/, 'i5');
like ($output, qr/six/, 'i6');
like ($output, qr/seven/, 'i7');
like ($output, qr/one/, 'g1');
like ($output, qr/two/, 'g2');
like ($output, qr/three/, 'g3');
like ($output, qr/four/, 'g4');
like ($output, qr/five/, 'g5');
like ($output, qr/six/, 'g6');
like ($output, qr/seven/, 'g7');
$output = qx{../task rc:filter.rc list +tag -tag};
unlike ($output, qr/one/, 'j1');
unlike ($output, qr/one/, 'g1');
unlike ($output, qr/two/, 'g2');
unlike ($output, qr/three/, 'g3');
unlike ($output, qr/four/, 'g4');
unlike ($output, qr/five/, 'g5');
unlike ($output, qr/six/, 'g6');
unlike ($output, qr/seven/, 'g7');
$output = qx{../task rc:filter.rc list project:A priority:H};
like ($output, qr/one/, 'h1');
like ($output, qr/two/, 'h2');
unlike ($output, qr/three/, 'h3');
unlike ($output, qr/four/, 'h4');
unlike ($output, qr/five/, 'h5');
unlike ($output, qr/six/, 'h6');
unlike ($output, qr/seven/, 'h7');
$output = qx{../task rc:filter.rc list project:A priority:};
unlike ($output, qr/one/, 'i1');
unlike ($output, qr/two/, 'i2');
like ($output, qr/three/, 'i3');
unlike ($output, qr/four/, 'i4');
unlike ($output, qr/five/, 'i5');
unlike ($output, qr/six/, 'i6');
unlike ($output, qr/seven/, 'i7');
$output = qx{../task rc:filter.rc list project:A foo};
like ($output, qr/one/, 'j1');
unlike ($output, qr/two/, 'j2');
unlike ($output, qr/three/, 'j3');
unlike ($output, qr/four/, 'j4');
@@ -137,25 +164,25 @@ unlike ($output, qr/five/, 'j5');
unlike ($output, qr/six/, 'j6');
unlike ($output, qr/seven/, 'j7');
$output = qx{../task rc:filter.rc list project:A priority:H};
$output = qx{../task rc:filter.rc list project:A +tag};
like ($output, qr/one/, 'k1');
like ($output, qr/two/, 'k2');
unlike ($output, qr/two/, 'k2');
unlike ($output, qr/three/, 'k3');
unlike ($output, qr/four/, 'k4');
unlike ($output, qr/five/, 'k5');
unlike ($output, qr/six/, 'k6');
unlike ($output, qr/seven/, 'k7');
$output = qx{../task rc:filter.rc list project:A priority:};
unlike ($output, qr/one/, 'l1');
$output = qx{../task rc:filter.rc list project:A priority:H foo};
like ($output, qr/one/, 'l1');
unlike ($output, qr/two/, 'l2');
like ($output, qr/three/, 'l3');
unlike ($output, qr/three/, 'l3');
unlike ($output, qr/four/, 'l4');
unlike ($output, qr/five/, 'l5');
unlike ($output, qr/six/, 'l6');
unlike ($output, qr/seven/, 'l7');
$output = qx{../task rc:filter.rc list project:A foo};
$output = qx{../task rc:filter.rc list project:A priority:H +tag};
like ($output, qr/one/, 'm1');
unlike ($output, qr/two/, 'm2');
unlike ($output, qr/three/, 'm3');
@@ -164,7 +191,7 @@ unlike ($output, qr/five/, 'm5');
unlike ($output, qr/six/, 'm6');
unlike ($output, qr/seven/, 'm7');
$output = qx{../task rc:filter.rc list project:A +tag};
$output = qx{../task rc:filter.rc list project:A priority:H foo +tag};
like ($output, qr/one/, 'n1');
unlike ($output, qr/two/, 'n2');
unlike ($output, qr/three/, 'n3');
@@ -173,41 +200,14 @@ unlike ($output, qr/five/, 'n5');
unlike ($output, qr/six/, 'n6');
unlike ($output, qr/seven/, 'n7');
$output = qx{../task rc:filter.rc list project:A priority:H foo};
like ($output, qr/one/, 'o1');
unlike ($output, qr/two/, 'o2');
unlike ($output, qr/three/, 'o3');
unlike ($output, qr/four/, 'o4');
unlike ($output, qr/five/, 'o5');
unlike ($output, qr/six/, 'o6');
unlike ($output, qr/seven/, 'o7');
$output = qx{../task rc:filter.rc list project:A priority:H +tag};
like ($output, qr/one/, 'p1');
unlike ($output, qr/two/, 'p2');
unlike ($output, qr/three/, 'p3');
unlike ($output, qr/four/, 'p4');
unlike ($output, qr/five/, 'p5');
unlike ($output, qr/six/, 'p6');
unlike ($output, qr/seven/, 'p7');
$output = qx{../task rc:filter.rc list project:A priority:H foo +tag};
like ($output, qr/one/, 'q1');
unlike ($output, qr/two/, 'q2');
unlike ($output, qr/three/, 'q3');
unlike ($output, qr/four/, 'q4');
unlike ($output, qr/five/, 'q5');
unlike ($output, qr/six/, 'q6');
unlike ($output, qr/seven/, 'q7');
$output = qx{../task rc:filter.rc list project:A priority:H foo +tag baz};
unlike ($output, qr/one/, 'r1');
unlike ($output, qr/two/, 'r2');
unlike ($output, qr/three/, 'r3');
unlike ($output, qr/four/, 'r4');
unlike ($output, qr/five/, 'r5');
unlike ($output, qr/six/, 'r6');
unlike ($output, qr/seven/, 'r7');
unlike ($output, qr/one/, 'n1');
unlike ($output, qr/two/, 'n2');
unlike ($output, qr/three/, 'n3');
unlike ($output, qr/four/, 'n4');
unlike ($output, qr/five/, 'n5');
unlike ($output, qr/six/, 'n6');
unlike ($output, qr/seven/, 'n7');
# Cleanup.
unlink 'pending.data';

View File

@@ -1,4 +1,4 @@
#! /bin/sh
#! /bin/bash
date > all.log
@@ -14,7 +14,7 @@ END=`tail -1 all.log`
OS=`uname`
case $OS in
Darwin | FreeBSD)
Darwin)
STARTEPOCH=`date -j -f "%a %b %d %T %Z %Y" "${START}" "+%s"`
ENDEPOCH=`date -j -f "%a %b %d %T %Z %Y" "${END}" "+%s"`
;;

View File

@@ -34,7 +34,7 @@ Context context;
////////////////////////////////////////////////////////////////////////////////
int main (int argc, char** argv)
{
UnitTest t (117);
UnitTest t (109);
// void wrapText (std::vector <std::string>& lines, const std::string& text, const int width)
std::string text = "This is a test of the line wrapping code.";
@@ -104,19 +104,12 @@ int main (int argc, char** argv)
t.is (items.size (), (size_t) 1, "split 'a' '-' -> 1 item");
t.is (items[0], "a", "split 'a' '-' -> 'a'");
split (items, unsplit, '-');
t.is (items.size (), (size_t) 1, "split 'a' '-' -> 1 item");
t.is (items[0], "a", "split 'a' '-' -> 'a'");
unsplit = "-";
split (items, unsplit, '-');
t.is (items.size (), (size_t) 2, "split '-' '-' -> '' ''");
t.is (items[0], "", "split '-' '-' -> [0] ''");
t.is (items[1], "", "split '-' '-' -> [1] ''");
split_minimal (items, unsplit, '-');
t.is (items.size (), (size_t) 1, "split '-' '-' -> '-'");
unsplit = "-a-bc-def";
split (items, unsplit, '-');
t.is (items.size (), (size_t) 4, "split '-a-bc-def' '-' -> '' 'a' 'bc' 'def'");
@@ -125,20 +118,11 @@ int main (int argc, char** argv)
t.is (items[2], "bc", "split '-a-bc-def' '-' -> [2] 'bc'");
t.is (items[3], "def", "split '-a-bc-def' '-' -> [3] 'def'");
split_minimal (items, unsplit, '-');
t.is (items.size (), (size_t) 3, "split '-a-bc-def' '-' -> 'a' 'bc' 'def'");
t.is (items[0], "a", "split '-a-bc-def' '-' -> [1] 'a'");
t.is (items[1], "bc", "split '-a-bc-def' '-' -> [2] 'bc'");
t.is (items[2], "def", "split '-a-bc-def' '-' -> [3] 'def'");
// void split (std::vector<std::string>& results, const std::string& input, const std::string& delimiter)
unsplit = "";
split (items, unsplit, "--");
t.is (items.size (), (size_t) 0, "split '' '--' -> 0 items");
split_minimal (items, unsplit, "--");
t.is (items.size (), (size_t) 0, "split '' '--' -> 0");
unsplit = "a";
split (items, unsplit, "--");
t.is (items.size (), (size_t) 1, "split 'a' '--' -> 1 item");

View File

@@ -38,7 +38,6 @@ int main (int argc, char** argv)
// TODO bool confirm (const std::string&);
// TODO int confirm3 (const std::string&);
// TODO int confirm4 (const std::string&);
// TODO void delay (float);
// TODO std::string formatSeconds (time_t);
// TODO std::string formatSecondsCompact (time_t);
@@ -84,15 +83,15 @@ int main (int argc, char** argv)
Task rightAgain (right);
std::string output = taskDifferences (left, right);
t.ok (taskDiff (left, right), "Detected changes");
t.ok (output.find ("zero will be changed from '0' to '00'") != std::string::npos, "Detected change zero:0 -> zero:00");
t.ok (output.find ("one will be deleted") != std::string::npos, "Detected deletion one:1 ->");
t.ok (output.find ("two") == std::string::npos, "Detected no change two:2 -> two:2");
t.ok (output.find ("three will be set to '3'") != std::string::npos, "Detected addition -> three:3");
t.ok (taskDiff (left, right), "Detected changes");
t.ok (output.find ("zero was changed from '0' to '00'") != std::string::npos, "Detected change zero:0 -> zero:00");
t.ok (output.find ("one was deleted") != std::string::npos, "Detected deletion one:1 ->");
t.ok (output.find ("two") == std::string::npos, "Detected no change two:2 -> two:2");
t.ok (output.find ("three was set to '3'") != std::string::npos, "Detected addition -> three:3");
t.notok (taskDiff (right, rightAgain), "No changes detected");
t.notok (taskDiff (right, rightAgain), "No changes detected");
output = taskDifferences (right, rightAgain);
t.ok (output.find ("No changes will be made") != std::string::npos, "No changes detected");
t.ok (output.find ("No changes were made") != std::string::npos, "No changes detected");
return 0;
}

View File

@@ -72,26 +72,6 @@ void split (
results.push_back (input.substr (start, std::string::npos));
}
////////////////////////////////////////////////////////////////////////////////
void split_minimal (
std::vector<std::string>& results,
const std::string& input,
const char delimiter)
{
results.clear ();
std::string::size_type start = 0;
std::string::size_type i;
while ((i = input.find (delimiter, start)) != std::string::npos)
{
if (i != start)
results.push_back (input.substr (start, i - start));
start = i + 1;
}
if (input.length ())
results.push_back (input.substr (start, std::string::npos));
}
////////////////////////////////////////////////////////////////////////////////
void split (
std::vector<std::string>& results,
@@ -113,28 +93,6 @@ void split (
results.push_back (input.substr (start, std::string::npos));
}
////////////////////////////////////////////////////////////////////////////////
void split_minimal (
std::vector<std::string>& results,
const std::string& input,
const std::string& delimiter)
{
results.clear ();
std::string::size_type length = delimiter.length ();
std::string::size_type start = 0;
std::string::size_type i;
while ((i = input.find (delimiter, start)) != std::string::npos)
{
if (i != start)
results.push_back (input.substr (start, i - start));
start = i + length;
}
if (input.length ())
results.push_back (input.substr (start, std::string::npos));
}
////////////////////////////////////////////////////////////////////////////////
void join (
std::string& result,
@@ -251,7 +209,7 @@ std::string commify (const std::string& data)
int i;
for (int i = 0; i < (int) data.length (); ++i)
{
if (isdigit (data[i]))
if (::isdigit (data[i]))
end = i;
if (data[i] == '.')
@@ -269,11 +227,11 @@ std::string commify (const std::string& data)
int consecutiveDigits = 0;
for (; i >= 0; --i)
{
if (isdigit (data[i]))
if (::isdigit (data[i]))
{
result += data[i];
if (++consecutiveDigits == 3 && i && isdigit (data[i - 1]))
if (++consecutiveDigits == 3 && i && ::isdigit (data[i - 1]))
{
result += ',';
consecutiveDigits = 0;
@@ -293,11 +251,11 @@ std::string commify (const std::string& data)
int consecutiveDigits = 0;
for (; i >= 0; --i)
{
if (isdigit (data[i]))
if (::isdigit (data[i]))
{
result += data[i];
if (++consecutiveDigits == 3 && i && isdigit (data[i - 1]))
if (++consecutiveDigits == 3 && i && ::isdigit (data[i - 1]))
{
result += ',';
consecutiveDigits = 0;
@@ -321,8 +279,8 @@ 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]);
if (::isupper (input[i]))
output[i] = ::tolower (input[i]);
return output;
}
@@ -332,8 +290,8 @@ std::string upperCase (const std::string& input)
{
std::string output = input;
for (int i = 0; i < (int) input.length (); ++i)
if (islower (input[i]))
output[i] = toupper (input[i]);
if (::islower (input[i]))
output[i] = ::toupper (input[i]);
return output;
}
@@ -344,7 +302,7 @@ std::string ucFirst (const std::string& input)
std::string output = input;
if (output.length () > 0)
output[0] = toupper (output[0]);
output[0] = ::toupper (output[0]);
return output;
}
@@ -394,7 +352,7 @@ void guess (
bool digitsOnly (const std::string& input)
{
for (size_t i = 0; i < input.length (); ++i)
if (!isdigit (input[i]))
if (!::isdigit (input[i]))
return false;
return true;
@@ -404,7 +362,7 @@ bool digitsOnly (const std::string& input)
bool noSpaces (const std::string& input)
{
for (size_t i = 0; i < input.length (); ++i)
if (isspace (input[i]))
if (::isspace (input[i]))
return false;
return true;

View File

@@ -40,8 +40,6 @@ std::string unquoteText (const 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 split_minimal (std::vector<std::string>&, const std::string&, const char);
void split_minimal (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&);

View File

@@ -64,7 +64,7 @@ bool confirm (const std::string& question)
<< " ";
std::getline (std::cin, answer);
answer = std::cin.eof() ? "no" : lowerCase (trim (answer));
answer = lowerCase (trim (answer));
}
while (answer != "y" && // TODO i18n
answer != "ye" && // TODO i18n
@@ -82,7 +82,7 @@ bool confirm (const std::string& question)
int confirm3 (const std::string& question)
{
std::vector <std::string> options;
options.push_back ("Yes");
options.push_back ("yes");
options.push_back ("no");
options.push_back ("all");
@@ -104,49 +104,11 @@ int confirm3 (const std::string& question)
}
while (matches.size () != 1);
if (matches[0] == "Yes") return 1;
if (matches[0] == "yes") return 1;
else if (matches[0] == "all") return 2;
else return 0;
}
////////////////////////////////////////////////////////////////////////////////
// 0 = no
// 1 = yes
// 2 = all
// 3 = quit
int confirm4 (const std::string& question)
{
std::vector <std::string> options;
options.push_back ("Yes");
options.push_back ("no");
options.push_back ("all");
options.push_back ("quit");
std::string answer;
std::vector <std::string> matches;
do
{
std::cout << question
<< " ("
<< options[0] << "/"
<< options[1] << "/"
<< options[2] << "/"
<< options[3]
<< ") ";
std::getline (std::cin, answer);
answer = trim (answer);
autoComplete (answer, options, matches);
}
while (matches.size () != 1);
if (matches[0] == "Yes") return 1;
else if (matches[0] == "all") return 2;
else if (matches[0] == "quit") return 3;
else return 0;
}
////////////////////////////////////////////////////////////////////////////////
void delay (float f)
{
@@ -538,21 +500,22 @@ std::string taskDifferences (const Task& before, const Task& after)
foreach (name, beforeOnly)
out << " - "
<< *name
<< " will be deleted\n";
<< " was deleted\n";
foreach (name, afterOnly)
out << " - "
<< *name
<< " will be set to '"
<< " was set to '"
<< renderAttribute (*name, after.get (*name))
<< "'\n";
foreach (name, beforeAtts)
if (*name != "uuid" &&
after.get (*name) != "" &&
before.get (*name) != after.get (*name))
out << " - "
<< *name
<< " will be changed from '"
<< " was changed from '"
<< renderAttribute (*name, before.get (*name))
<< "' to '"
<< renderAttribute (*name, after.get (*name))
@@ -560,7 +523,7 @@ std::string taskDifferences (const Task& before, const Task& after)
// Shouldn't just say nothing.
if (out.str ().length () == 0)
out << " - No changes will be made\n";
out << " - No changes were made\n";
return out.str ();
}

View File

@@ -53,7 +53,6 @@ for (typeof (c) *foreach_p = & (c); \
// util.cpp
bool confirm (const std::string&);
int confirm3 (const std::string&);
int confirm4 (const std::string&);
void delay (float);
std::string formatSeconds (time_t);
std::string formatSecondsCompact (time_t);