Compare commits
175 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
499044b9b6 | ||
|
|
f66c706370 | ||
|
|
e3e72e32f1 | ||
|
|
39fb45447b | ||
|
|
3cbb2bb20f | ||
|
|
c6dbdf87a4 | ||
|
|
fe8d235a6b | ||
|
|
1371b6595e | ||
|
|
21407e0ca2 | ||
|
|
c0efa0f4d7 | ||
|
|
236e7898b9 | ||
|
|
33738af3e4 | ||
|
|
f684917c3c | ||
|
|
876a7d29b9 | ||
|
|
119c19b519 | ||
|
|
935b2993f3 | ||
|
|
afec6d451f | ||
|
|
fd17a68930 | ||
|
|
09d86eb165 | ||
|
|
8d5a77f490 | ||
|
|
e9b54ea74f | ||
|
|
3a035a7d1d | ||
|
|
d405a5f3b5 | ||
|
|
0cba34268c | ||
|
|
61e1401073 | ||
|
|
a883c5ca41 | ||
|
|
d98b6e5c0b | ||
|
|
6b0d288da7 | ||
|
|
e8654c49b5 | ||
|
|
c28932ebbe | ||
|
|
826769bcd9 | ||
|
|
d31227d2e2 | ||
|
|
0a54d46589 | ||
|
|
3f457dc744 | ||
|
|
f9c99624b2 | ||
|
|
b19b0f47e5 | ||
|
|
fbf9a8be8d | ||
|
|
9476069b41 | ||
|
|
35b77f93c4 | ||
|
|
5da3416b79 | ||
|
|
79207a8e42 | ||
|
|
5af4579741 | ||
|
|
7a9d314016 | ||
|
|
07a18f4fae | ||
|
|
29a09707f3 | ||
|
|
743cb92958 | ||
|
|
370afa0d26 | ||
|
|
8c0f46309b | ||
|
|
fa7d4352cd | ||
|
|
f1ef53bea0 | ||
|
|
21dc2ec100 | ||
|
|
5b01abc27f | ||
|
|
c830b4b669 | ||
|
|
70d5f595c7 | ||
|
|
c1815b8277 | ||
|
|
2eea7805c6 | ||
|
|
5487414003 | ||
|
|
229078ffed | ||
|
|
04d0c52a43 | ||
|
|
5d4859c44d | ||
|
|
3f394fa164 | ||
|
|
df209b9b8b | ||
|
|
c27f5d23b6 | ||
|
|
df3f8ead11 | ||
|
|
bc335e8075 | ||
|
|
e0f3e6d328 | ||
|
|
eb35386d76 | ||
|
|
96c448ca1e | ||
|
|
71fea510bb | ||
|
|
1e411ed4b8 | ||
|
|
cfbdd4bc05 | ||
|
|
5af3f71ac5 | ||
|
|
8b863c9764 | ||
|
|
9630b76990 | ||
|
|
690d9493f0 | ||
|
|
73f4f55e0a | ||
|
|
267f054449 | ||
|
|
7a64c19641 | ||
|
|
b8105812fc | ||
|
|
f454a02224 | ||
|
|
1bbe709e38 | ||
|
|
a4b96a3191 | ||
|
|
ddb6014358 | ||
|
|
31a7a3343b | ||
|
|
3a0971f290 | ||
|
|
fee58b0eb6 | ||
|
|
9adf3fc0fa | ||
|
|
39d330631d | ||
|
|
b41d7c4582 | ||
|
|
12eca4b2cc | ||
|
|
f26f790e74 | ||
|
|
7ac0a919aa | ||
|
|
e9e91ce55e | ||
|
|
880fb5bcc6 | ||
|
|
84eb75c705 | ||
|
|
f697e4df73 | ||
|
|
0eaa061efe | ||
|
|
b02d518b02 | ||
|
|
0973e6566b | ||
|
|
d0a9e9a253 | ||
|
|
ff445c567e | ||
|
|
254b1eb49c | ||
|
|
15005afd1e | ||
|
|
9e6c6ecb93 | ||
|
|
20eaa312e6 | ||
|
|
fdb22ad341 | ||
|
|
d76d5c3587 | ||
|
|
526665d4ec | ||
|
|
834b4ddab6 | ||
|
|
357850177d | ||
|
|
d2e6c90446 | ||
|
|
96922231b8 | ||
|
|
55db1239bd | ||
|
|
4f75652ccb | ||
|
|
052a5c607a | ||
|
|
c306d458e0 | ||
|
|
7babc9c5b1 | ||
|
|
24a1cbefe9 | ||
|
|
289780c8cc | ||
|
|
f5af3368a9 | ||
|
|
a2ed996102 | ||
|
|
704eb1eab3 | ||
|
|
484979b4e0 | ||
|
|
928e94a6e1 | ||
|
|
e2c9752bc4 | ||
|
|
8386b702dd | ||
|
|
48e9c0518e | ||
|
|
11dab68fce | ||
|
|
29dff399bd | ||
|
|
a75c293286 | ||
|
|
dbf31bfce8 | ||
|
|
7826c7b988 | ||
|
|
d202691638 | ||
|
|
c9d61ff71b | ||
|
|
4118fe70ae | ||
|
|
e11b333a0b | ||
|
|
d1f7e44811 | ||
|
|
53e9bd0cbd | ||
|
|
234e4d7308 | ||
|
|
237d932ff9 | ||
|
|
2af470bb90 | ||
|
|
cefc129e9a | ||
|
|
7aa55a8a71 | ||
|
|
565987a177 | ||
|
|
309b607672 | ||
|
|
abe8819f2f | ||
|
|
3f2d377fef | ||
|
|
c849cc9bfe | ||
|
|
7e890c084f | ||
|
|
0f1a46e6d3 | ||
|
|
2811b9a571 | ||
|
|
9dad0c7eb6 | ||
|
|
e67c6c45cf | ||
|
|
8c6892fed6 | ||
|
|
0548fca88f | ||
|
|
26aff348d2 | ||
|
|
9f82926c65 | ||
|
|
8791c0a921 | ||
|
|
745aad0d27 | ||
|
|
e1c0d5b130 | ||
|
|
9898aa15b5 | ||
|
|
0cf18f3b16 | ||
|
|
2155bd3969 | ||
|
|
ae6024ef8b | ||
|
|
21553d9044 | ||
|
|
d6e3430e0d | ||
|
|
0d23511cee | ||
|
|
1128ad8259 | ||
|
|
66d5a8ba3d | ||
|
|
aab93b2cda | ||
|
|
be80bc4ea3 | ||
|
|
15bec27e03 | ||
|
|
6683cc7e83 | ||
|
|
044ca40bb7 | ||
|
|
d10ad5c7af |
4
AUTHORS
4
AUTHORS
@@ -115,6 +115,7 @@ The following submitted code, packages or analysis, and deserve special thanks:
|
||||
Łukasz Panek
|
||||
V.Krishn
|
||||
Jens Erat
|
||||
Peter Rochen
|
||||
|
||||
Thanks to the following, who submitted detailed bug reports and excellent
|
||||
suggestions:
|
||||
@@ -246,3 +247,6 @@ suggestions:
|
||||
Taisuke Hachimura
|
||||
Martin
|
||||
Alexandre de Verteuil
|
||||
Scott M
|
||||
Stefan Frühwirth
|
||||
Pierre Campet
|
||||
|
||||
@@ -10,7 +10,7 @@ include (CheckStructHasMember)
|
||||
set (HAVE_CMAKE true)
|
||||
|
||||
project (task)
|
||||
set (PROJECT_VERSION "2.4.2")
|
||||
set (PROJECT_VERSION "2.4.3")
|
||||
|
||||
OPTION(USE_GNUTLS "Build gnutls support." ON)
|
||||
|
||||
@@ -68,6 +68,8 @@ endif (${CMAKE_SYSTEM_NAME} MATCHES "Linux")
|
||||
|
||||
set (CMAKE_CXX_FLAGS "${_CXX11_FLAGS} ${CMAKE_CXX_FLAGS}")
|
||||
|
||||
set (CMAKE_CXX_FLAGS "-Wall -Wsign-compare -Wreturn-type ${CMAKE_CXX_FLAGS}")
|
||||
|
||||
if (NETBSD)
|
||||
# Since readline, etc likely to be in /usr/pkg/lib, not standard library
|
||||
# Otherwise will remove links during install
|
||||
|
||||
46
ChangeLog
46
ChangeLog
@@ -1,4 +1,46 @@
|
||||
2.4.2 (2015-03-15) -
|
||||
2.4.3 (2015-04-19) -
|
||||
|
||||
- TW-57 user defined attribute sort order (thanks to Max Muller).
|
||||
- TW-70 urgency.user.keyword.<keyword>.coefficient=...
|
||||
- TW-111 User-defined priorities.
|
||||
- TW-1279 Make default.* not apply to recurring tasks.
|
||||
- TW-1287 Make default.* not apply to synced tasks.
|
||||
- TW-1539 user-defined urgency coefficients for priority values.
|
||||
- TW-1541 Priority should be converted to UDA (in default taskrc) (thanks to
|
||||
Tomas Babej).
|
||||
- TW-1556 task hangs when modifying uda field with percent-encoded (url-encoded)
|
||||
value (thanks to Stefan Frühwirth).
|
||||
- TW-1578 Bash tab completion problems on first run
|
||||
(thanks to Renato Alves and Ptolemarch).
|
||||
- TW-1580 "modified" attribute no longer updated (thanks to David Patrick).
|
||||
- TW-1581 Tasks with dependencies show wrong urgency values for the first
|
||||
report run after a task in the dependency chain is completed/deleted (thanks
|
||||
to Ulf Eliasson).
|
||||
- TW-1583 Invalid ID displayed for first report after done/delete (thanks to
|
||||
Ulf Eliasson).
|
||||
- TW-1584 attr.{isnt,not} use partial matching.
|
||||
- TW-1587 Fix and improve example on-exit hook, adjust to new hooks API
|
||||
(thanks to Jochen Sprickerhof).
|
||||
- TW-1588 Most Export scripts cannot deal with new export format (thanks to
|
||||
Scott Carter).
|
||||
- TW-1590 syntax of rcfile not documented (whitespace, line continuation)
|
||||
(thanks to Scott M).
|
||||
- TW-1591 add an option to see non-pending project with command task summary
|
||||
(thanks to Pierre Campet).
|
||||
- TW-1595 info command doesn't print urgency details, if urgency is negative
|
||||
(thanks to Peter Rochen).
|
||||
- Setting 'bulk' to zero is interpreted as infinity, which means there is no
|
||||
amount of changes that is considered dangerous (thanks to Tomas Babej).
|
||||
- Disable hooks in bash completion script. Hooks were previously able to
|
||||
abort processing or output interfering data, breaking completion.
|
||||
- Fix "task add due:tomorrow+3days" failing to work without spaces.
|
||||
- Performance improvements:
|
||||
+ Stops after measuring a fixed-width column format.
|
||||
+ Reduced number of std::string copies.
|
||||
|
||||
------ current release ---------------------------
|
||||
|
||||
2.4.2 (2015-03-15) b9dc0813d9a8922b4cef9595033f133f9fbabf44
|
||||
|
||||
- TW-41 Tasks in subprojects are not counted in project completion (thanks
|
||||
to Renato Alves).
|
||||
@@ -27,8 +69,6 @@
|
||||
- 'task _version' now outputs "2.4.2 (git-ref)" when built from git. "2.4.2"
|
||||
when built from release tarballs (thanks to Renato Alves).
|
||||
|
||||
------ current release ---------------------------
|
||||
|
||||
2.4.1 (2015-02-16) 82e019a4a8b20de63d53b51d59b8d1c89d3c05b2
|
||||
|
||||
- TW-1457 Non-existent attributes are not properly handled (thanks to Tomas
|
||||
|
||||
@@ -10,7 +10,7 @@ How to Build Taskwarrior
|
||||
Obtain and build code:
|
||||
$ git clone https://git.tasktools.org/scm/tm/task.git task.git
|
||||
$ cd task.git
|
||||
$ git checkout 2.4.2 # Latest dev branch
|
||||
$ git checkout 2.4.3 # Latest dev branch
|
||||
$ cmake -DCMAKE_BUILD_TYPE=debug . # debug or release. Default: neither.
|
||||
$ make VERBOSE=1 # Shows details
|
||||
|
||||
@@ -189,11 +189,11 @@ Work in Progress
|
||||
Current Codebase Condition
|
||||
|
||||
'master' branch:
|
||||
- 2.4.1 Current release, locked.
|
||||
- 2.4.2 Current release, locked.
|
||||
|
||||
'2.4.2' branch:
|
||||
'2.4.3' branch:
|
||||
- Current development branch no plans yet.
|
||||
|
||||
---
|
||||
|
||||
2015-02-14 Updated for 2.4.1
|
||||
2015-03-15 Updated for 2.4.3
|
||||
|
||||
12
INSTALL
12
INSTALL
@@ -152,6 +152,18 @@ Darwin, 32bit
|
||||
http://stackoverflow.com/questions/6077414/cmake-how-to-set-the-ldflags-in-cmakelists-txt
|
||||
|
||||
|
||||
OpenBSD
|
||||
In order to build Taskwarrior 2.4.2+, you might need to install a newer GCC
|
||||
version from ports or packages.
|
||||
|
||||
Afterwards, run
|
||||
cmake -DCMAKE_CXX_COMPILER=eg++ .
|
||||
|
||||
and build normally.
|
||||
|
||||
See: https://bug.tasktools.org/browse/TW-1579
|
||||
|
||||
|
||||
Troubleshooting
|
||||
---------------
|
||||
|
||||
|
||||
41
NEWS
41
NEWS
@@ -1,39 +1,34 @@
|
||||
|
||||
New Features in taskwarrior 2.4.2
|
||||
New Features in taskwarrior 2.4.3
|
||||
|
||||
- Ability to set context, which serves as a permanent user-defined filter.
|
||||
- The 'info' command now shows virtual tags.
|
||||
- UDA string attributes with allowable values can now define their sort order.
|
||||
- The 'priority' attribute is now a UDA, configured by default.
|
||||
|
||||
New commands in taskwarrior 2.4.2
|
||||
New commands in taskwarrior 2.4.3
|
||||
|
||||
- The 'context' command has been added, along with it subcommands 'define',
|
||||
'delete', 'show', 'list' and 'none'.
|
||||
-
|
||||
|
||||
New configuration options in taskwarrior 2.4.2
|
||||
New configuration options in taskwarrior 2.4.3
|
||||
|
||||
- 'context' to store the current context applied.
|
||||
- 'context.<name>' to store the definition of context 'name'
|
||||
- Setting 'bulk' to zero is interpreted as infinity, which means there is no
|
||||
amount of changes that is considered dangerous.
|
||||
- The 'urgency.user.keyword.<keyword>.coefficient' setting allows tasks with
|
||||
specific words in the description to have adjusted urgency.
|
||||
- The 'summary.all.projects' setting shows all projects in the 'summary'
|
||||
reportş instead of just those with pending tasks.
|
||||
|
||||
Newly deprecated features in taskwarrior 2.4.2
|
||||
Newly deprecated features in taskwarrior 2.4.3
|
||||
|
||||
- None
|
||||
-
|
||||
|
||||
Removed features in 2.4.2
|
||||
Removed features in 2.4.3
|
||||
|
||||
- None
|
||||
- The 'priority.long' and 'priority.short' column formats are no longer
|
||||
supported.
|
||||
- The 'default.priority' setting is now 'uda.priority.default'.
|
||||
|
||||
Known Issues
|
||||
|
||||
- If you upgraded from Taskwarrior 2.3.0, you will need one of the following
|
||||
settings to allow continued syncing to a Taskserver:
|
||||
|
||||
$ task config taskd.trust strict
|
||||
$ task config taskd.trust 'ignore hostname'
|
||||
$ task config taskd.trust 'allow all'
|
||||
|
||||
These are presented in order of preference from most to least secure, and
|
||||
depend on how your certs were generated.
|
||||
|
||||
- https://bug.tasktools.org/
|
||||
|
||||
Taskwarrior has been built and tested on the following configurations:
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
.TH task-color 5 2015-03-15 "${PACKAGE_STRING}" "User Manuals"
|
||||
.TH task-color 5 2015-04-19 "${PACKAGE_STRING}" "User Manuals"
|
||||
|
||||
.SH NAME
|
||||
task-color \- A color tutorial for the taskwarrior command line todo manager.
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
.TH task-sync 5 2015-03-15 "${PACKAGE_STRING}" "User Manuals"
|
||||
.TH task-sync 5 2015-04-19 "${PACKAGE_STRING}" "User Manuals"
|
||||
|
||||
.SH NAME
|
||||
task-sync \- A discussion and tutorial for the various task(1) data
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
.TH task 1 2015-03-15 "${PACKAGE_STRING}" "User Manuals"
|
||||
.TH task 1 2015-04-19 "${PACKAGE_STRING}" "User Manuals"
|
||||
|
||||
.SH NAME
|
||||
task \- A command line todo manager.
|
||||
@@ -379,6 +379,22 @@ time from the specified task.
|
||||
Miscellaneous subcommands either accept no command line arguments, or accept
|
||||
non-standard arguments.
|
||||
|
||||
.TP
|
||||
.B task calc <expression>
|
||||
Evaluates an algebraic expression. Can be used to test how TaskWarrior
|
||||
parses and evaluates the expression given on the command line.
|
||||
|
||||
Examples:
|
||||
|
||||
task calc 1 + 1
|
||||
2
|
||||
|
||||
task calc now + 8d
|
||||
2015-03-26T18:06:57
|
||||
|
||||
task calc eom
|
||||
2015-03-31T23:59:59
|
||||
|
||||
.TP
|
||||
.B task config [name [value | '']]
|
||||
Add, modify and remove settings directly in the taskwarrior configuration.
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
.TH taskrc 5 2015-03-15 "${PACKAGE_STRING}" "User Manuals"
|
||||
.TH taskrc 5 2015-04-19 "${PACKAGE_STRING}" "User Manuals"
|
||||
|
||||
.SH NAME
|
||||
taskrc \- Configuration details for the task(1) command
|
||||
@@ -11,7 +11,7 @@ taskrc \- Configuration details for the task(1) command
|
||||
.B TASKRC=<directory-path>/.taskrc task ...
|
||||
|
||||
.SH DESCRIPTION
|
||||
.B taskwarrior
|
||||
.B Taskwarrior
|
||||
obtains its configuration data from a file called
|
||||
.I .taskrc
|
||||
\&. This file is normally located in the user's home directory:
|
||||
@@ -55,37 +55,50 @@ default, sample
|
||||
.I .taskrc
|
||||
file in the user's home directory.
|
||||
|
||||
The taskwarrior configuration file consists of a series of assignments in each
|
||||
line. The assignments have the syntax:
|
||||
The .taskrc file follows a very simply syntax defining name/value pairs:
|
||||
|
||||
.RS
|
||||
<name-of-configuration-variable>=<value-to-be-set>
|
||||
<name> = <value>
|
||||
.RE
|
||||
|
||||
where:
|
||||
.RS
|
||||
.TP
|
||||
<name-of-configuration-variable>
|
||||
is one of the variables described below
|
||||
|
||||
.TP
|
||||
<value-to-be-set>
|
||||
is the value the variable is to be set to.
|
||||
.RE
|
||||
|
||||
and set a configuration variable to a certain value. The equal sign ("=") is
|
||||
used to separate the variable name from the value to be set.
|
||||
|
||||
The hash mark, or pound sign ("#") is used as a comment character. It can be
|
||||
used to annotate the configuration file. All text after the character to the end
|
||||
of the line is ignored.
|
||||
|
||||
The configuration file supports UTF8 as well as JSON encoding, such as \\uNNNN.
|
||||
There may be whitespace around <name>, '=' and <value>, and it is ignored.
|
||||
Whitespace within the <value> is left intact.
|
||||
Whitespace is not permitted in comma-separated lists.
|
||||
The entry must be on a single line, no continuations.
|
||||
Values support UTF8 as well as JSON encoding, such as \\uNNNN.
|
||||
|
||||
Note that taskwarrior is flexible about the values used to represent Boolean
|
||||
items. You can use "on", "yes", "y", "1" and "true".
|
||||
Anything else means "off".
|
||||
|
||||
.RS
|
||||
include <file>
|
||||
.RE
|
||||
|
||||
There may be whitespace around 'include' and <file>. The file may be an
|
||||
absolute or relative path, and the special character '~' is expanded to mean
|
||||
$HOME.
|
||||
The entry must be on a single line, no continuations.
|
||||
|
||||
.RS
|
||||
# <comment>
|
||||
.RE
|
||||
|
||||
A comment consists of the character '#', and extends from the '#' to the end
|
||||
of the line. There is no way to comment a multi-line block. There may be
|
||||
blank lines.
|
||||
|
||||
Almost every value has a default setting, and an empty .taskrc file is one
|
||||
that makes use of every default. The contents of the .taskrc file therefore
|
||||
represent overrides of the default values. To remove a default value completely
|
||||
there must be an entry like this:
|
||||
|
||||
.RS
|
||||
<name> =
|
||||
.RE
|
||||
|
||||
This entry overrides the default value with a blank value.
|
||||
|
||||
.SH EDITING
|
||||
You can edit your .taskrc file by hand if you wish, or you can use the 'config'
|
||||
command. To permanently set a value in your .taskrc file, use this command:
|
||||
@@ -288,7 +301,7 @@ value is "yes". Consider leaving this setting as "yes", for safety.
|
||||
.TP
|
||||
.B allow.empty.filter=yes
|
||||
An empty filter combined with a write command is potentially a way to modify
|
||||
all tasks by mistkae, and when this is detected, confirmation is required.
|
||||
all tasks by mistake, and when this is detected, confirmation is required.
|
||||
Setting this to 'no' means that it is an error to use a write command with no
|
||||
filter.
|
||||
|
||||
@@ -314,23 +327,28 @@ Controls padding between columns of the report output. Default is "1".
|
||||
Is a number, defaulting to 3. When this number or greater of tasks are modified
|
||||
in a single command, confirmation will be required, regardless of the value of
|
||||
.B confirmation
|
||||
variable.
|
||||
variable. The special value bulk=0 is treated as an infinity.
|
||||
|
||||
This is useful for preventing large-scale unintended changes.
|
||||
|
||||
.TP
|
||||
.B nag=You have more urgent tasks.
|
||||
This may be a string of text, or blank. It is used as a prompt when a task is
|
||||
started or completed that is not considered high priority. Default value is:
|
||||
You have more urgent tasks. It is a gentle reminder that you are contradicting
|
||||
your own priority settings.
|
||||
This may be a string of text, or blank. It is used as a prompt when a task is
|
||||
started of completed, when there are other tasks with a higher urgency.
|
||||
Default value is: 'You have more urgent tasks'.
|
||||
It is a gentle reminder that you are contradicting your own urgency settings.
|
||||
|
||||
.TP
|
||||
.B list.all.projects=yes
|
||||
.B list.all.projects=no
|
||||
May be yes or no, and determines whether the 'projects' command lists all the project
|
||||
names you have used, or just the ones used in active tasks. The default value is
|
||||
"no".
|
||||
|
||||
.TP
|
||||
.B summary.all.projects=no
|
||||
If set to yes, shows all projects in the summary report, even if there are no
|
||||
pending tasks. The default value is "no".
|
||||
|
||||
.TP
|
||||
.B complete.all.tags=yes
|
||||
May be yes or no, and determines whether the tab completion scripts consider all
|
||||
@@ -828,18 +846,6 @@ Task has at least one tag.
|
||||
.B color.recurring
|
||||
Task is recurring.
|
||||
.br
|
||||
.B color.pri.H
|
||||
Task has priority H.
|
||||
.br
|
||||
.B color.pri.M
|
||||
Task has priority M.
|
||||
.br
|
||||
.B color.pri.L
|
||||
Task has priority L.
|
||||
.br
|
||||
.B color.pri.none
|
||||
Task has no priority.
|
||||
.br
|
||||
.B color.completed
|
||||
Task is completed.
|
||||
.br
|
||||
@@ -1058,10 +1064,6 @@ Urgency inherited from dependency chain
|
||||
.RS
|
||||
Urgency coefficient for due dates
|
||||
.RE
|
||||
.B urgency.priority.coefficient=6.0
|
||||
.RS
|
||||
Urgency coefficient for priorities
|
||||
.RE
|
||||
.B urgency.waiting.coefficient=-3.0
|
||||
.RS
|
||||
Urgency coefficient for waiting status
|
||||
@@ -1102,6 +1104,10 @@ Specific tag coefficient.
|
||||
.RS
|
||||
Specific project coefficient.
|
||||
.RE
|
||||
.B urgency.user.keyword.<keyword>.coefficient=...
|
||||
.RS
|
||||
Specific description keyword coefficient.
|
||||
.RE
|
||||
.B urgency.uda.<name>.coefficient=...
|
||||
.RS
|
||||
Presence/absence of UDA data.
|
||||
@@ -1124,13 +1130,6 @@ Provides a default project name for the
|
||||
.I task add
|
||||
command, if you don't specify one. The default is blank.
|
||||
|
||||
.TP
|
||||
.B
|
||||
default.priority=M
|
||||
Provides a default priority for the
|
||||
.I task add
|
||||
command, if you don't specify one. The default is blank.
|
||||
|
||||
.TP
|
||||
.B
|
||||
default.due=...
|
||||
@@ -1336,19 +1335,36 @@ Provides a default report label for the UDA called '<name>'.
|
||||
For type 'string' UDAs only, this provides a comma-separated list of acceptable
|
||||
values. In this example, the '<name>' UDA may only contain values 'A', 'B',
|
||||
or 'C', but may also contain no value.
|
||||
|
||||
Note that the order of the value is important, and denotes the sort order from
|
||||
highest ('A') to lowest ('C').
|
||||
|
||||
Note that a blank value is permitted.
|
||||
.RE
|
||||
|
||||
.TP
|
||||
.B uda.<name>.default=...
|
||||
.RS
|
||||
Provides a default value for the UDA called '<name>'.
|
||||
.RE
|
||||
|
||||
.TP
|
||||
.B Example 'estimate' UDA
|
||||
This example shows an 'estimate' UDA that stores specific values for the size
|
||||
of a task.
|
||||
of a task. Note the blank value after 'trivial'.
|
||||
|
||||
.RS
|
||||
.B uda.estimate.type=string
|
||||
.br
|
||||
.B uda.estimate.label=Size Estimate
|
||||
.br
|
||||
.B uda.estimate.values=trivial,small,medium,large,huge
|
||||
.B uda.estimate.values=huge,large,medium,small,trivial,
|
||||
.RE
|
||||
|
||||
.RS
|
||||
Note that the value are sorted
|
||||
|
||||
huge > large > medium > small > trivial > ''
|
||||
.RE
|
||||
|
||||
.SS CONTEXT
|
||||
|
||||
@@ -50,10 +50,9 @@ color.blocking=black on bright white
|
||||
color.project.none=
|
||||
|
||||
# Priority
|
||||
color.pri.H=bold white
|
||||
color.pri.M=white
|
||||
color.pri.L=
|
||||
color.pri.none=
|
||||
color.uda.priority.H=bold white
|
||||
color.uda.priority.M=white
|
||||
color.uda.priority.L=
|
||||
|
||||
# Tags
|
||||
color.tag.next=bold yellow
|
||||
|
||||
@@ -50,10 +50,9 @@ color.blocking=black on color15
|
||||
color.project.none=
|
||||
|
||||
# Priority
|
||||
color.pri.H=color255
|
||||
color.pri.L=color245
|
||||
color.pri.M=color250
|
||||
color.pri.none=
|
||||
color.uda.priority.H=color255
|
||||
color.uda.priority.L=color245
|
||||
color.uda.priority.M=color250
|
||||
|
||||
# Tags
|
||||
color.tag.next=rgb440
|
||||
|
||||
@@ -50,10 +50,9 @@ color.blocking=white on rgb002
|
||||
color.project.none=
|
||||
|
||||
# Priority
|
||||
color.pri.H=rgb035
|
||||
color.pri.L=rgb015
|
||||
color.pri.M=rgb025
|
||||
color.pri.none=
|
||||
color.uda.priority.H=rgb035
|
||||
color.uda.priority.L=rgb015
|
||||
color.uda.priority.M=rgb025
|
||||
|
||||
# Tags
|
||||
color.tag.next=rgb550
|
||||
|
||||
@@ -50,10 +50,9 @@ color.blocking=bold white
|
||||
color.project.none=
|
||||
|
||||
# Priority
|
||||
color.pri.H=gray21
|
||||
color.pri.M=gray18
|
||||
color.pri.L=gray12
|
||||
color.pri.none=gray18
|
||||
color.uda.priority.H=gray21
|
||||
color.uda.priority.M=gray18
|
||||
color.uda.priority.L=gray12
|
||||
|
||||
# Tags
|
||||
color.tag.next=bold white
|
||||
|
||||
@@ -50,10 +50,9 @@ color.blocking=gray18 on gray6
|
||||
color.project.none=
|
||||
|
||||
# Priority
|
||||
color.pri.H=
|
||||
color.pri.L=
|
||||
color.pri.M=
|
||||
color.pri.none=
|
||||
color.uda.priority.H=
|
||||
color.uda.priority.L=
|
||||
color.uda.priority.M=
|
||||
|
||||
# Tags
|
||||
color.tag.next=
|
||||
|
||||
@@ -50,10 +50,9 @@ color.blocking=white on rgb020
|
||||
color.project.none=
|
||||
|
||||
# Priority
|
||||
color.pri.H=rgb050
|
||||
color.pri.L=rgb010
|
||||
color.pri.M=rgb030
|
||||
color.pri.none=
|
||||
color.uda.priority.H=rgb050
|
||||
color.uda.priority.L=rgb010
|
||||
color.uda.priority.M=rgb030
|
||||
|
||||
# Tags
|
||||
color.tag.next=rgb440
|
||||
|
||||
@@ -50,10 +50,9 @@ color.blocking=white on rgb200
|
||||
color.project.none=
|
||||
|
||||
# Priority
|
||||
color.pri.H=rgb500
|
||||
color.pri.L=rgb300
|
||||
color.pri.M=rgb400
|
||||
color.pri.none=
|
||||
color.uda.priority.H=rgb500
|
||||
color.uda.priority.L=rgb300
|
||||
color.uda.priority.M=rgb400
|
||||
|
||||
# Tags
|
||||
color.tag.next=rgb511
|
||||
|
||||
@@ -50,10 +50,9 @@ color.blocking=white on rgb202
|
||||
color.project.none=
|
||||
|
||||
# Priority
|
||||
color.pri.H=rgb404
|
||||
color.pri.M=rgb304
|
||||
color.pri.L=rgb325
|
||||
color.pri.none=
|
||||
color.uda.priority.H=rgb404
|
||||
color.uda.priority.M=rgb304
|
||||
color.uda.priority.L=rgb325
|
||||
|
||||
# Tags
|
||||
color.tag.next=
|
||||
|
||||
@@ -50,10 +50,9 @@ color.blocking=white on rgb220
|
||||
color.project.none=
|
||||
|
||||
# Priority
|
||||
color.pri.H=rgb450
|
||||
color.pri.M=rgb030
|
||||
color.pri.L=rgb010
|
||||
color.pri.none=
|
||||
color.uda.priority.H=rgb450
|
||||
color.uda.priority.M=rgb030
|
||||
color.uda.priority.L=rgb010
|
||||
|
||||
# Tags
|
||||
color.tag.next=
|
||||
|
||||
@@ -50,10 +50,9 @@ color.blocked=blue
|
||||
color.project.none=
|
||||
|
||||
# Priority
|
||||
color.pri.H=
|
||||
color.pri.M=
|
||||
color.pri.L=bright black
|
||||
color.pri.none=
|
||||
color.uda.priority.H=
|
||||
color.uda.priority.M=
|
||||
color.uda.priority.L=bright black
|
||||
|
||||
# Tags
|
||||
color.tag.next=bold yellow on bright black
|
||||
|
||||
@@ -50,10 +50,9 @@ color.blocked=rgb003
|
||||
color.project.none=
|
||||
|
||||
# Priority
|
||||
color.pri.H=gray0
|
||||
color.pri.M=gray5
|
||||
color.pri.L=gray10
|
||||
color.pri.none=
|
||||
color.uda.priority.H=gray0
|
||||
color.uda.priority.M=gray5
|
||||
color.uda.priority.L=gray10
|
||||
|
||||
# Tags
|
||||
color.tag.next=rgb420
|
||||
|
||||
@@ -53,10 +53,9 @@ color.blocking=
|
||||
color.project.none=
|
||||
|
||||
# Priority
|
||||
color.pri.H=
|
||||
color.pri.L=
|
||||
color.pri.M=
|
||||
color.pri.none=
|
||||
color.uda.priority.H=
|
||||
color.uda.priority.L=
|
||||
color.uda.priority.M=
|
||||
|
||||
# Tags
|
||||
color.tag.next=
|
||||
|
||||
@@ -67,10 +67,9 @@ color.blocking=color15 on color10
|
||||
color.project.none=
|
||||
|
||||
# Priority
|
||||
color.pri.H=bold blue #color14
|
||||
color.pri.M=bold yellow #color12
|
||||
color.pri.L=bold green #color11
|
||||
color.pri.none=
|
||||
color.uda.priority.H=bold blue #color14
|
||||
color.uda.priority.M=bold yellow #color12
|
||||
color.uda.priority.L=bold green #color11
|
||||
|
||||
# Tags
|
||||
color.tag.next=
|
||||
|
||||
@@ -67,10 +67,9 @@ color.blocking=color15 on color0
|
||||
color.project.none=
|
||||
|
||||
# Priority
|
||||
color.pri.H=bold color0
|
||||
color.pri.M=bold color11
|
||||
color.pri.L=bold color14
|
||||
color.pri.none=
|
||||
color.uda.priority.H=bold color0
|
||||
color.uda.priority.M=bold color11
|
||||
color.uda.priority.L=bold color14
|
||||
|
||||
# Tags
|
||||
color.tag.next=
|
||||
|
||||
Binary file not shown.
Binary file not shown.
@@ -48,7 +48,7 @@ if ($command =~ /No matches/)
|
||||
print "'uuid','status','tags','entry','start','due','recur','end','project',",
|
||||
"'priority','fg','bg','description'\n";
|
||||
|
||||
for my $task (split /,$/ms, qx{$command})
|
||||
for my $task (split "\n", qx{$command})
|
||||
{
|
||||
my $data = from_json ($task);
|
||||
|
||||
|
||||
@@ -60,7 +60,7 @@ print "<html>\n",
|
||||
" <tbody>\n";
|
||||
|
||||
my $count = 0;
|
||||
for my $task (split /,$/ms, qx{$command})
|
||||
for my $task (split "\n", qx{$command})
|
||||
{
|
||||
++$count;
|
||||
my $data = from_json ($task);
|
||||
|
||||
@@ -49,7 +49,7 @@ print "BEGIN:VCALENDAR\n",
|
||||
"VERSION:2.0\n",
|
||||
"PRODID:=//GBF/taskwarrior 1.9.4//EN\n";
|
||||
|
||||
for my $task (split /,$/ms, qx{$command})
|
||||
for my $task (split "\n", qx{$command})
|
||||
{
|
||||
my $data = from_json ($task);
|
||||
|
||||
|
||||
@@ -140,10 +140,10 @@ def main():
|
||||
""" Return a list of SQL statements. """
|
||||
|
||||
# Use the taskwarrior 2.0+ export command to filter and return JSON
|
||||
command = "task rc.verbose=nothing rc.json.array=no export " + " ".join(sys.argv[1:])
|
||||
command = "task rc.verbose=nothing rc.json.array=yes " + " ".join(sys.argv[1:]) + " export"
|
||||
|
||||
# Load each task from json to a python dict
|
||||
tasks = map(json.loads, commands.getoutput(command).split(",\n"))
|
||||
tasks = json.loads(commands.getoutput(command))
|
||||
|
||||
# Mangle datetime strings into python datetime objects
|
||||
tasks = map(parse_datetime, tasks)
|
||||
|
||||
@@ -48,7 +48,7 @@ if ($command =~ /No matches/)
|
||||
print "uuid\tstatus\ttags\tentry\tstart\tdue\trecur\tend\tproject\t",
|
||||
"priority\tfg\tbg\tdescription\n";
|
||||
|
||||
for my $task (split /,$/ms, qx{$command})
|
||||
for my $task (split "\n", qx{$command})
|
||||
{
|
||||
my $data = from_json ($task);
|
||||
|
||||
|
||||
@@ -46,7 +46,7 @@ if ($command =~ /No matches/)
|
||||
|
||||
# Generate output.
|
||||
print "<tasks>\n";
|
||||
for my $task (split /,$/ms, qx{$command})
|
||||
for my $task (split "\n", qx{$command})
|
||||
{
|
||||
my $data = from_json ($task);
|
||||
|
||||
|
||||
@@ -48,7 +48,7 @@ if ($command =~ /No matches/)
|
||||
print "'uuid','status','tags','entry','start','due','recur','end','project',",
|
||||
"'priority','fg','bg','description'\n";
|
||||
|
||||
for my $task (split /,$/ms, qx{$command})
|
||||
for my $task (split "\n", qx{$command})
|
||||
{
|
||||
my $data = from_json ($task);
|
||||
|
||||
|
||||
@@ -50,7 +50,7 @@
|
||||
#
|
||||
################################################################################
|
||||
#the following variable is substituted for by ../../test/bash_completion.t
|
||||
taskcommand='task rc.verbose:nothing'
|
||||
taskcommand='task rc.verbose:nothing rc.confirmation:no rc.hooks:off'
|
||||
|
||||
_task_get_tags() {
|
||||
$taskcommand _tags
|
||||
|
||||
@@ -3,18 +3,18 @@
|
||||
# The on-exit event is triggered once, after all processing is complete.
|
||||
# This hooks script has no effect on processing.
|
||||
|
||||
# Input:
|
||||
# - Read-only line of JSON for each task added/modified
|
||||
while read modified_task
|
||||
do
|
||||
echo $modified_task
|
||||
done
|
||||
|
||||
# Output:
|
||||
# - Optional feedback/error.
|
||||
echo 'on-exit'
|
||||
|
||||
n=0
|
||||
while read modified_task
|
||||
do
|
||||
n=$(($n + 1))
|
||||
done
|
||||
|
||||
echo "on-exit: Counted $n added/modified tasks."
|
||||
|
||||
# Status:
|
||||
# - 0: JSON ignored, non-JSON is feedback.
|
||||
# - non-0: JSON ignored, non-JSON is error.
|
||||
# - 0: Non-JSON is feedback.
|
||||
# - non-0: Non-JSON is error.
|
||||
exit 0
|
||||
|
||||
@@ -72,10 +72,9 @@ syn match taskrcGoodKey '^\s*\Vcolor.history.add='he=e-1
|
||||
syn match taskrcGoodKey '^\s*\Vcolor.history.delete='he=e-1
|
||||
syn match taskrcGoodKey '^\s*\Vcolor.history.done='he=e-1
|
||||
syn match taskrcGoodKey '^\s*\Vcolor.overdue='he=e-1
|
||||
syn match taskrcGoodKey '^\s*\Vcolor.pri.H='he=e-1
|
||||
syn match taskrcGoodKey '^\s*\Vcolor.pri.L='he=e-1
|
||||
syn match taskrcGoodKey '^\s*\Vcolor.pri.M='he=e-1
|
||||
syn match taskrcGoodKey '^\s*\Vcolor.pri.none='he=e-1
|
||||
syn match taskrcGoodKey '^\s*\Vcolor.uda.priority.H='he=e-1
|
||||
syn match taskrcGoodKey '^\s*\Vcolor.uda.priority.L='he=e-1
|
||||
syn match taskrcGoodKey '^\s*\Vcolor.uda.priority.M='he=e-1
|
||||
syn match taskrcGoodKey '^\s*\Vcolor.recurring='he=e-1
|
||||
syn match taskrcGoodKey '^\s*\Vcolor.scheduled='he=e-1
|
||||
syn match taskrcGoodKey '^\s*\Vcolor.summary.background='he=e-1
|
||||
@@ -154,7 +153,9 @@ syn match taskrcGoodKey '^\s*\Vurgency.blocking.coefficient='he=e-1
|
||||
syn match taskrcGoodKey '^\s*\Vurgency.due.coefficient='he=e-1
|
||||
syn match taskrcGoodKey '^\s*\Vurgency.inherit.coefficient='he=e-1
|
||||
syn match taskrcGoodKey '^\s*\Vurgency.next.coefficient='he=e-1
|
||||
syn match taskrcGoodKey '^\s*\Vurgency.priority.coefficient='he=e-1
|
||||
syn match taskrcGoodKey '^\s*\Vurgency.uda.priority.H.coefficient='he=e-1
|
||||
syn match taskrcGoodKey '^\s*\Vurgency.uda.priority.M.coefficient='he=e-1
|
||||
syn match taskrcGoodKey '^\s*\Vurgency.uda.priority.L.coefficient='he=e-1
|
||||
syn match taskrcGoodKey '^\s*\Vurgency.project.coefficient='he=e-1
|
||||
syn match taskrcGoodKey '^\s*\Vurgency.scheduled.coefficient='he=e-1
|
||||
syn match taskrcGoodKey '^\s*\Vurgency.tags.coefficient='he=e-1
|
||||
|
||||
1
src/.gitignore
vendored
1
src/.gitignore
vendored
@@ -3,3 +3,4 @@ Makefile.in
|
||||
tw-*
|
||||
args
|
||||
calc
|
||||
lex
|
||||
|
||||
87
src/CLI.cpp
87
src/CLI.cpp
@@ -220,16 +220,14 @@ const std::string A::dump () const
|
||||
// Static method.
|
||||
void CLI::getOverride (int argc, const char** argv, std::string& home, File& rc)
|
||||
{
|
||||
bool terminated = false;
|
||||
for (int i = 0; i < argc; ++i)
|
||||
{
|
||||
std::string raw = argv[i];
|
||||
|
||||
if (raw == "--")
|
||||
terminated = true;
|
||||
return;
|
||||
|
||||
if (! terminated &&
|
||||
raw.length () > 3 &&
|
||||
if (raw.length () > 3 &&
|
||||
raw.substr (0, 3) == "rc:")
|
||||
{
|
||||
rc = raw.substr (3);
|
||||
@@ -351,7 +349,6 @@ void CLI::initialize (int argc, const char** argv)
|
||||
_terminated = false;
|
||||
|
||||
_original_args.push_back (argv[0]);
|
||||
bool terminated = false;
|
||||
for (int i = 1; i < argc; ++i)
|
||||
{
|
||||
if (isTerminator (argv[i]))
|
||||
@@ -379,10 +376,9 @@ void CLI::addContextFilter ()
|
||||
{
|
||||
// Detect if any context is set, and bail out if not
|
||||
std::string contextName = context.config.get ("context");
|
||||
|
||||
if (contextName == "")
|
||||
{
|
||||
context.debug("No context applied.");
|
||||
context.debug ("No context applied.");
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -392,35 +388,35 @@ void CLI::addContextFilter ()
|
||||
std::vector <A>::const_iterator a;
|
||||
for (a = _args.begin (); a != _args.end (); ++a)
|
||||
{
|
||||
// TODO This looks wrong.
|
||||
if (a->hasTag ("FILTER") &&
|
||||
a->hasTag ("ATTRIBUTE") &&
|
||||
! a->hasTag ("TERMINATED") &&
|
||||
! a->hasTag ("WORD") &&
|
||||
(a->attribute ("raw") == "id" || a->attribute ("raw") == "uuid"))
|
||||
{
|
||||
context.debug(format("UUID/ID lexeme found '{1}', not applying context.", a->attribute ("raw")));
|
||||
context.debug (format ("UUID/ID lexeme found '{1}', not applying context.", a->attribute ("raw")));
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Apply context
|
||||
context.debug("Applying context: " + contextName);
|
||||
context.debug ("Applying context: " + contextName);
|
||||
std::string contextFilter = context.config.get ("context." + contextName);
|
||||
|
||||
if (contextFilter == "")
|
||||
context.debug("Context '" + contextName + "' not defined!");
|
||||
context.debug ("Context '" + contextName + "' not defined.");
|
||||
else
|
||||
{
|
||||
addRawFilter("( " + contextFilter + " )");
|
||||
addRawFilter ("( " + contextFilter + " )");
|
||||
if (context.verbose ("context"))
|
||||
context.footnote (format("Context '{1}' set. Use 'task context none' to remove.", contextName));
|
||||
context.footnote (format ("Context '{1}' set. Use 'task context none' to remove.", contextName));
|
||||
}
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
// Process raw string into parsed filter.
|
||||
//
|
||||
void CLI::addRawFilter (const std::string& arg)
|
||||
{
|
||||
std::string lexeme;
|
||||
@@ -446,7 +442,7 @@ void CLI::analyze (bool parse /* = true */, bool strict /* = false */)
|
||||
// For propagation.
|
||||
_strict = strict;
|
||||
|
||||
for (int i = 0; i < _original_args.size (); ++i)
|
||||
for (unsigned int i = 0; i < _original_args.size (); ++i)
|
||||
{
|
||||
std::string raw = _original_args[i];
|
||||
A a ("arg", raw);
|
||||
@@ -692,7 +688,7 @@ const std::string CLI::dump (const std::string& title /* = "CLI Parser" */) cons
|
||||
// be lexed from those that need to be left alone.
|
||||
//
|
||||
// Either the arg is appended to _original_args intact, or the lexemes are.
|
||||
void CLI::addArg (const std::string& arg)
|
||||
void CLI::addArg (const std::string& arg, Lexer::Type type /* = Lexer::Type::word */)
|
||||
{
|
||||
std::string raw = trim (arg);
|
||||
|
||||
@@ -718,8 +714,8 @@ void CLI::addArg (const std::string& arg)
|
||||
_original_args.push_back (raw);
|
||||
}
|
||||
|
||||
// The argument may require lexing. Lex anyway, and analyze before comitting
|
||||
// that.
|
||||
// The argument may require lexing. Lex anyway, and analyze before comitting
|
||||
// to that.
|
||||
else
|
||||
{
|
||||
// Lex each remaining argument. The apply a series of disqualifying tests
|
||||
@@ -730,7 +726,7 @@ void CLI::addArg (const std::string& arg)
|
||||
Lexer lex (raw);
|
||||
lex.ambiguity (false);
|
||||
|
||||
std::vector <std::pair <std::string, Lexer::Type> > lexemes;
|
||||
std::vector <std::pair <std::string, Lexer::Type>> lexemes;
|
||||
while (lex.token (lexeme, type))
|
||||
lexemes.push_back (std::pair <std::string, Lexer::Type> (lexeme, type));
|
||||
|
||||
@@ -746,7 +742,7 @@ void CLI::addArg (const std::string& arg)
|
||||
{
|
||||
// How often have I said to you that when you have eliminated the
|
||||
// impossible, whatever remains, however improbable, must be the truth?
|
||||
std::vector <std::pair <std::string, Lexer::Type> >::iterator l;
|
||||
std::vector <std::pair <std::string, Lexer::Type>>::iterator l;
|
||||
for (l = lexemes.begin (); l != lexemes.end (); ++l)
|
||||
_original_args.push_back (l->first);
|
||||
}
|
||||
@@ -778,9 +774,7 @@ void CLI::aliasExpansion ()
|
||||
{
|
||||
if (_aliases.find (raw) != _aliases.end ())
|
||||
{
|
||||
std::vector <std::string> lexed;
|
||||
Lexer::token_split (lexed, _aliases[raw]);
|
||||
|
||||
std::vector <std::string> lexed = Lexer::split (_aliases[raw]);
|
||||
std::vector <std::string>::iterator l;
|
||||
for (l = lexed.begin (); l != lexed.end (); ++l)
|
||||
{
|
||||
@@ -916,7 +910,7 @@ void CLI::categorize ()
|
||||
a->tag ("MODIFICATION");
|
||||
|
||||
// If the argument contains a space, it was quoted. Record that.
|
||||
if (! noSpaces (raw))
|
||||
if (! Lexer::isOneWord (raw))
|
||||
a->tag ("QUOTED");
|
||||
|
||||
changes = true;
|
||||
@@ -926,7 +920,7 @@ void CLI::categorize ()
|
||||
a->tag ("FILTER");
|
||||
|
||||
// If the argument contains a space, it was quoted. Record that.
|
||||
if (! noSpaces (raw))
|
||||
if (! Lexer::isOneWord (raw))
|
||||
a->tag ("QUOTED");
|
||||
|
||||
changes = true;
|
||||
@@ -1240,7 +1234,7 @@ void CLI::desugarFilterAttributeModifiers ()
|
||||
}
|
||||
else if (modifier == "isnt" || modifier == "not")
|
||||
{
|
||||
op.attribute ("raw", "!=");
|
||||
op.attribute ("raw", "!==");
|
||||
rhs.attribute ("raw", "'" + value + "'");
|
||||
rhs.tag ("LITERAL");
|
||||
}
|
||||
@@ -1389,14 +1383,12 @@ void CLI::findIDs ()
|
||||
{
|
||||
if (a->hasTag ("FILTER"))
|
||||
{
|
||||
bool found = false;
|
||||
|
||||
// IDs have a limited character set.
|
||||
std::string raw = a->attribute ("raw");
|
||||
if (raw.find_first_not_of ("0123456789,-") == std::string::npos)
|
||||
{
|
||||
// Container for min/max ID ranges.
|
||||
std::vector <std::pair <int, int> > ranges;
|
||||
std::vector <std::pair <int, int>> ranges;
|
||||
|
||||
// Split the ID list into elements.
|
||||
std::vector <std::string> elements;
|
||||
@@ -1412,7 +1404,7 @@ void CLI::findIDs ()
|
||||
|
||||
if (terms.size () == 1)
|
||||
{
|
||||
if (! digitsOnly (terms[0]))
|
||||
if (! Lexer::isAllDigits (terms[0]))
|
||||
{
|
||||
is_an_id = false;
|
||||
break;
|
||||
@@ -1433,8 +1425,8 @@ void CLI::findIDs ()
|
||||
}
|
||||
else if (terms.size () == 2)
|
||||
{
|
||||
if (! digitsOnly (terms[0]) ||
|
||||
! digitsOnly (terms[1]))
|
||||
if (! Lexer::isAllDigits (terms[0]) ||
|
||||
! Lexer::isAllDigits (terms[1]))
|
||||
{
|
||||
is_an_id = false;
|
||||
break;
|
||||
@@ -1475,7 +1467,7 @@ void CLI::findIDs ()
|
||||
a->tag ("ID");
|
||||
|
||||
// Save the ranges.
|
||||
std::vector <std::pair <int, int> >::iterator r;
|
||||
std::vector <std::pair <int, int>>::iterator r;
|
||||
for (r = ranges.begin (); r != ranges.end (); ++r)
|
||||
_id_ranges.push_back (*r);
|
||||
}
|
||||
@@ -1584,7 +1576,7 @@ void CLI::insertIDExpr ()
|
||||
reconstructed.push_back (openParen);
|
||||
|
||||
// Add all ID ranges.
|
||||
std::vector <std::pair <int, int> >::iterator r;
|
||||
std::vector <std::pair <int, int>>::iterator r;
|
||||
for (r = _id_ranges.begin (); r != _id_ranges.end (); ++r)
|
||||
{
|
||||
if (r != _id_ranges.begin ())
|
||||
@@ -1879,8 +1871,7 @@ void CLI::injectDefaults ()
|
||||
if (defaultCommand != "")
|
||||
{
|
||||
// Split the defaultCommand into separate args.
|
||||
std::vector <std::string> tokens;
|
||||
Lexer::token_split (tokens, defaultCommand);
|
||||
std::vector <std::string> tokens = Lexer::split (defaultCommand);
|
||||
|
||||
// Modify _args to be: <args0> [<def0> ...] <args1> [...]
|
||||
std::vector <A> reconstructed;
|
||||
@@ -2274,7 +2265,7 @@ bool CLI::isIDSequence (const std::string& raw) const
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
bool CLI::isID (const std::string& raw) const
|
||||
{
|
||||
return digitsOnly (raw);
|
||||
return Lexer::isAllDigits (raw);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
@@ -2368,11 +2359,11 @@ bool CLI::isName (const std::string& raw) const
|
||||
{
|
||||
if (raw != "")
|
||||
{
|
||||
for (int i = 0; i < raw.length (); ++i)
|
||||
for (unsigned int i = 0; i < raw.length (); ++i)
|
||||
{
|
||||
if (i == 0 && ! Lexer::is_ident_start (raw[i]))
|
||||
if (i == 0 && ! Lexer::isIdentifierStart (raw[i]))
|
||||
return false;
|
||||
else if (! Lexer::is_ident (raw[i]))
|
||||
else if (! Lexer::isIdentifierNext (raw[i]))
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -2384,19 +2375,19 @@ bool CLI::isName (const std::string& raw) const
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
bool CLI::disqualifyInsufficientTerms (
|
||||
const std::vector <std::pair <std::string, Lexer::Type> >& lexemes) const
|
||||
const std::vector <std::pair <std::string, Lexer::Type>>& lexemes) const
|
||||
{
|
||||
return lexemes.size () < 3 ? true : false;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
bool CLI::disqualifyNoOps (
|
||||
const std::vector <std::pair <std::string, Lexer::Type> >& lexemes) const
|
||||
const std::vector <std::pair <std::string, Lexer::Type>>& lexemes) const
|
||||
{
|
||||
bool foundOP = false;
|
||||
std::vector <std::pair <std::string, Lexer::Type> >::const_iterator l;
|
||||
std::vector <std::pair <std::string, Lexer::Type>>::const_iterator l;
|
||||
for (l = lexemes.begin (); l != lexemes.end (); ++l)
|
||||
if (l->second == Lexer::typeOperator)
|
||||
if (l->second == Lexer::Type::op)
|
||||
foundOP = true;
|
||||
|
||||
return ! foundOP;
|
||||
@@ -2404,16 +2395,16 @@ bool CLI::disqualifyNoOps (
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
bool CLI::disqualifyOnlyParenOps (
|
||||
const std::vector <std::pair <std::string, Lexer::Type> >& lexemes) const
|
||||
const std::vector <std::pair <std::string, Lexer::Type>>& lexemes) const
|
||||
{
|
||||
int opCount = 0;
|
||||
int opSugarCount = 0;
|
||||
int opParenCount = 0;
|
||||
|
||||
std::vector <std::pair <std::string, Lexer::Type> >::const_iterator l;
|
||||
std::vector <std::pair <std::string, Lexer::Type>>::const_iterator l;
|
||||
for (l = lexemes.begin (); l != lexemes.end (); ++l)
|
||||
{
|
||||
if (l->second == Lexer::typeOperator)
|
||||
if (l->second == Lexer::Type::op)
|
||||
{
|
||||
++opCount;
|
||||
|
||||
@@ -2440,7 +2431,7 @@ bool CLI::disqualifyOnlyParenOps (
|
||||
// as there are no operators in between, which includes syntactic sugar that
|
||||
// hides operators.
|
||||
bool CLI::disqualifyFirstLastBinary (
|
||||
const std::vector <std::pair <std::string, Lexer::Type> >& lexemes) const
|
||||
const std::vector <std::pair <std::string, Lexer::Type>>& lexemes) const
|
||||
{
|
||||
bool firstBinary = false;
|
||||
bool lastBinary = false;
|
||||
@@ -2459,7 +2450,7 @@ bool CLI::disqualifyFirstLastBinary (
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
// Disqualify terms when there operators hidden by syntactic sugar.
|
||||
bool CLI::disqualifySugarFree (
|
||||
const std::vector <std::pair <std::string, Lexer::Type> >& lexemes) const
|
||||
const std::vector <std::pair <std::string, Lexer::Type>>& lexemes) const
|
||||
{
|
||||
bool sugared = true;
|
||||
for (unsigned int i = 1; i < lexemes.size () - 1; ++i)
|
||||
|
||||
14
src/CLI.h
14
src/CLI.h
@@ -90,7 +90,7 @@ public:
|
||||
const std::string dump (const std::string& title = "CLI Parser") const;
|
||||
|
||||
private:
|
||||
void addArg (const std::string&);
|
||||
void addArg (const std::string&, Lexer::Type type = Lexer::Type::word);
|
||||
void aliasExpansion ();
|
||||
void findOverrides ();
|
||||
void categorize ();
|
||||
@@ -128,11 +128,11 @@ private:
|
||||
bool isOperator (const std::string&) const;
|
||||
bool isName (const std::string&) const;
|
||||
|
||||
bool disqualifyInsufficientTerms (const std::vector <std::pair <std::string, Lexer::Type> >&) const;
|
||||
bool disqualifyNoOps (const std::vector <std::pair <std::string, Lexer::Type> >&) const;
|
||||
bool disqualifyOnlyParenOps (const std::vector <std::pair <std::string, Lexer::Type> >&) const;
|
||||
bool disqualifyFirstLastBinary (const std::vector <std::pair <std::string, Lexer::Type> >&) const;
|
||||
bool disqualifySugarFree (const std::vector <std::pair <std::string, Lexer::Type> >&) const;
|
||||
bool disqualifyInsufficientTerms (const std::vector <std::pair <std::string, Lexer::Type>>&) const;
|
||||
bool disqualifyNoOps (const std::vector <std::pair <std::string, Lexer::Type>>&) const;
|
||||
bool disqualifyOnlyParenOps (const std::vector <std::pair <std::string, Lexer::Type>>&) const;
|
||||
bool disqualifyFirstLastBinary (const std::vector <std::pair <std::string, Lexer::Type>>&) const;
|
||||
bool disqualifySugarFree (const std::vector <std::pair <std::string, Lexer::Type>>&) const;
|
||||
|
||||
public:
|
||||
std::multimap <std::string, std::string> _entities;
|
||||
@@ -140,7 +140,7 @@ public:
|
||||
std::vector <std::string> _original_args;
|
||||
std::vector <A> _args;
|
||||
|
||||
std::vector <std::pair <int, int> > _id_ranges;
|
||||
std::vector <std::pair <int, int>> _id_ranges;
|
||||
std::vector <std::string> _uuid_list;
|
||||
bool _strict;
|
||||
bool _terminated;
|
||||
|
||||
@@ -48,16 +48,19 @@ set (task_SRCS CLI.cpp CLI.h
|
||||
add_library (task STATIC ${task_SRCS})
|
||||
add_executable (task_executable main.cpp)
|
||||
add_executable (calc_executable calc.cpp)
|
||||
add_executable (lex_executable lex.cpp)
|
||||
|
||||
# Yes, 'task' is included twice, otherwise linking fails on assorted OSes.
|
||||
target_link_libraries (task_executable task commands columns task ${TASK_LIBRARIES})
|
||||
target_link_libraries (calc_executable task commands columns task ${TASK_LIBRARIES})
|
||||
target_link_libraries (lex_executable task commands columns task ${TASK_LIBRARIES})
|
||||
|
||||
set_property (TARGET task_executable PROPERTY OUTPUT_NAME "task")
|
||||
|
||||
install (TARGETS task_executable DESTINATION ${TASK_BINDIR})
|
||||
|
||||
set_property (TARGET calc_executable PROPERTY OUTPUT_NAME "calc")
|
||||
set_property (TARGET lex_executable PROPERTY OUTPUT_NAME "lex")
|
||||
|
||||
#SET(CMAKE_BUILD_TYPE gcov)
|
||||
#SET(CMAKE_CXX_FLAGS_GCOV "--coverage")
|
||||
|
||||
@@ -147,7 +147,6 @@ std::string Config::_defaults =
|
||||
"urgency.next.coefficient=15.0 # Urgency coefficient for 'next' special tag\n"
|
||||
"urgency.due.coefficient=12.0 # Urgency coefficient for due dates\n"
|
||||
"urgency.blocking.coefficient=8.0 # Urgency coefficient for blocking tasks\n"
|
||||
"urgency.priority.coefficient=6.0 # Urgency coefficient for priorities\n"
|
||||
"urgency.active.coefficient=4.0 # Urgency coefficient for active tasks\n"
|
||||
"urgency.scheduled.coefficient=5.0 # Urgency coefficient for scheduled tasks\n"
|
||||
"urgency.age.coefficient=2.0 # Urgency coefficient for age\n"
|
||||
@@ -192,11 +191,10 @@ std::string Config::_defaults =
|
||||
"# Project\n"
|
||||
"color.project.none=\n"
|
||||
"\n"
|
||||
"# Priority\n"
|
||||
"color.pri.H=color255\n"
|
||||
"color.pri.L=color245\n"
|
||||
"color.pri.M=color250\n"
|
||||
"color.pri.none=\n"
|
||||
"# Priority UDA\n"
|
||||
"color.uda.priority.H=color255\n"
|
||||
"color.uda.priority.L=color245\n"
|
||||
"color.uda.priority.M=color250\n"
|
||||
"\n"
|
||||
"# Tags\n"
|
||||
"color.tag.next=rgb440\n"
|
||||
@@ -267,11 +265,10 @@ std::string Config::_defaults =
|
||||
"# Project\n"
|
||||
"color.project.none=\n"
|
||||
"\n"
|
||||
"# Priority\n"
|
||||
"color.pri.H=bold white\n"
|
||||
"color.pri.M=white\n"
|
||||
"color.pri.L=\n"
|
||||
"color.pri.none=\n"
|
||||
"# Priority UDA\n"
|
||||
"color.uda.priority.H=bold white\n"
|
||||
"color.uda.priority.M=white\n"
|
||||
"color.uda.priority.L=\n"
|
||||
"\n"
|
||||
"# Tags\n"
|
||||
"color.tag.next=bold yellow\n"
|
||||
@@ -319,19 +316,29 @@ std::string Config::_defaults =
|
||||
"color.undo.before=red\n"
|
||||
"\n"
|
||||
#endif
|
||||
"# UDA priority\n"
|
||||
"uda.priority.type=string # UDA priority is a string type\n"
|
||||
"uda.priority.label=Priority # UDA priority has a display label'\n"
|
||||
"uda.priority.values=H,M,L, # UDA priority values are 'H', 'M', 'L' or ''\n"
|
||||
" # UDA priority sorting is 'H' > 'M' > 'L' > '' (highest to lowest)\n"
|
||||
"#uda.priority.default=M # UDA priority default value of 'M'\n"
|
||||
"urgency.uda.priority.H.coefficient=6.0 # UDA priority coefficient for value 'H'\n"
|
||||
"urgency.uda.priority.M.coefficient=3.9 # UDA priority coefficient for value 'M'\n"
|
||||
"urgency.uda.priority.L.coefficient=1.8 # UDA priority coefficient for value 'L'\n"
|
||||
"\n"
|
||||
"# Here is the rule precedence order, highest to lowest.\n"
|
||||
"# Note that these are just the color rule names, without the leading 'color.'\n"
|
||||
"# and any trailing '.value'.\n"
|
||||
"rule.precedence.color=deleted,completed,active,keyword.,tag.,uda.,project.,overdue,scheduled,due.today,due,blocked,blocking,recurring,tagged,pri.\n"
|
||||
"\n"
|
||||
"#default.project=foo # Default project for 'add' command\n"
|
||||
"#default.priority=M # Default priority for 'add' command\n"
|
||||
"#default.due=eom # Default due date for 'add' command\n"
|
||||
"default.command=next # When no arguments are specified\n"
|
||||
"\n"
|
||||
"_forcecolor=no # Forces color to be on, even for non TTY output\n"
|
||||
"complete.all.tags=no # Include old tag names in '_ags' command\n"
|
||||
"list.all.projects=no # Include old project names in 'projects' command\n"
|
||||
"summary.all.projects=no # Include old project names in 'summary' command\n"
|
||||
"list.all.tags=no # Include old tag names in 'tags' command\n"
|
||||
"print.empty.columns=no # Print columns which have no data for any task\n"
|
||||
"debug=no # Display diagnostics\n"
|
||||
@@ -385,7 +392,7 @@ std::string Config::_defaults =
|
||||
"report.newest.description=Newest tasks\n"
|
||||
"report.newest.labels=ID,Active,Created,Age,Mod,D,P,Project,Tags,R,Wait,Sch,Due,Until,Description\n"
|
||||
"report.newest.columns=id,start.age,entry,entry.age,modified.age,depends.indicator,priority,project,tags,recur.indicator,wait.remaining,scheduled.countdown,due,until.age,description\n"
|
||||
"report.newest.filter=(status:pending or status:waiting) and recur.none:\n"
|
||||
"report.newest.filter=(status:pending or status:waiting)\n"
|
||||
"report.newest.sort=entry-\n"
|
||||
"\n"
|
||||
"report.oldest.description=Oldest tasks\n"
|
||||
|
||||
@@ -65,33 +65,6 @@ static const char* modifierNames[] =
|
||||
|
||||
#define NUM_MODIFIER_NAMES (sizeof (modifierNames) / sizeof (modifierNames[0]))
|
||||
|
||||
static const char* attributeNames[] =
|
||||
{
|
||||
"depends",
|
||||
"description",
|
||||
"due",
|
||||
"end",
|
||||
"entry",
|
||||
"id",
|
||||
"imask",
|
||||
"mask",
|
||||
"modified",
|
||||
"parent",
|
||||
"priority",
|
||||
"project",
|
||||
"recur",
|
||||
"scheduled",
|
||||
"start",
|
||||
"status",
|
||||
"tags",
|
||||
"until",
|
||||
"urgency",
|
||||
"uuid",
|
||||
"wait"
|
||||
};
|
||||
|
||||
#define NUM_ATTRIBUTE_NAMES (sizeof (attributeNames) / sizeof (attributeNames[0]))
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
Context::Context ()
|
||||
: rc_file ("~/.taskrc")
|
||||
@@ -101,6 +74,7 @@ Context::Context ()
|
||||
, dom ()
|
||||
, determine_color_use (true)
|
||||
, use_color (true)
|
||||
, run_gc (true)
|
||||
, verbosity_legacy (false)
|
||||
, terminal_width (0)
|
||||
, terminal_height (0)
|
||||
@@ -478,7 +452,14 @@ int Context::dispatch (std::string &out)
|
||||
// GC is invoked prior to running any command that displays task IDs, if
|
||||
// possible.
|
||||
if (c->displays_id () && !tdb2.read_only ())
|
||||
{
|
||||
run_gc = true;
|
||||
tdb2.gc ();
|
||||
}
|
||||
else
|
||||
{
|
||||
run_gc = false;
|
||||
}
|
||||
|
||||
/*
|
||||
// Only read-only commands can be run when TDB2 is read-only.
|
||||
@@ -652,7 +633,6 @@ void Context::staticInitialization ()
|
||||
CLI::minimumMatchLength = config.getInteger ("abbreviation.minimum");
|
||||
|
||||
Task::defaultProject = config.get ("default.project");
|
||||
Task::defaultPriority = config.get ("default.priority");
|
||||
Task::defaultDue = config.get ("default.due");
|
||||
|
||||
Task::searchCaseSensitive = Variant::searchCaseSensitive = config.getBoolean ("search.case.sensitive");
|
||||
@@ -660,11 +640,25 @@ void Context::staticInitialization ()
|
||||
Lexer::dateFormat = Variant::dateFormat = config.get ("dateformat");
|
||||
Lexer::isoEnabled = Variant::isoEnabled = config.getBoolean ("date.iso");
|
||||
|
||||
Config::const_iterator rc;
|
||||
for (rc = config.begin (); rc != config.end (); ++rc)
|
||||
{
|
||||
if (rc->first.substr (0, 4) == "uda." &&
|
||||
rc->first.substr (rc->first.length () - 7, 7) == ".values")
|
||||
{
|
||||
std::string name = rc->first.substr (4, rc->first.length () - 7 - 4);
|
||||
std::vector <std::string> values;
|
||||
split (values, rc->second, ',');
|
||||
|
||||
for (auto r = values.rbegin(); r != values.rend (); ++r)
|
||||
Task::customOrder[name].push_back (*r);
|
||||
}
|
||||
}
|
||||
|
||||
std::map <std::string, Column*>::iterator i;
|
||||
for (i = columns.begin (); i != columns.end (); ++i)
|
||||
Task::attributes[i->first] = i->second->type ();
|
||||
|
||||
Task::urgencyPriorityCoefficient = config.getReal ("urgency.priority.coefficient");
|
||||
Task::urgencyProjectCoefficient = config.getReal ("urgency.project.coefficient");
|
||||
Task::urgencyActiveCoefficient = config.getReal ("urgency.active.coefficient");
|
||||
Task::urgencyScheduledCoefficient = config.getReal ("urgency.scheduled.coefficient");
|
||||
|
||||
@@ -94,6 +94,8 @@ public:
|
||||
bool determine_color_use;
|
||||
bool use_color;
|
||||
|
||||
bool run_gc;
|
||||
|
||||
bool verbosity_legacy;
|
||||
std::vector <std::string> verbosity;
|
||||
std::vector <std::string> headers;
|
||||
|
||||
52
src/DOM.cpp
52
src/DOM.cpp
@@ -116,16 +116,16 @@ bool DOM::get (const std::string& name, Variant& value)
|
||||
}
|
||||
else if (name == "context.width")
|
||||
{
|
||||
value = Variant (context.terminal_width
|
||||
? context.terminal_width
|
||||
: context.getWidth ());
|
||||
value = Variant (static_cast<int> (context.terminal_width
|
||||
? context.terminal_width
|
||||
: context.getWidth ()));
|
||||
return true;
|
||||
}
|
||||
else if (name == "context.height")
|
||||
{
|
||||
value = Variant (context.terminal_height
|
||||
? context.terminal_height
|
||||
: context.getHeight ());
|
||||
value = Variant (static_cast<int> (context.terminal_height
|
||||
? context.terminal_height
|
||||
: context.getHeight ()));
|
||||
return true;
|
||||
}
|
||||
else
|
||||
@@ -218,7 +218,7 @@ bool DOM::get (const std::string& name, const Task& task, Variant& value)
|
||||
// <attr>
|
||||
if (task.size () && name == "id")
|
||||
{
|
||||
value = Variant (task.id);
|
||||
value = Variant (static_cast<int> (task.id));
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -296,7 +296,7 @@ bool DOM::get (const std::string& name, const Task& task, Variant& value)
|
||||
{
|
||||
if (elements[1] == "id")
|
||||
{
|
||||
value = Variant (ref.id);
|
||||
value = Variant (static_cast<int> (ref.id));
|
||||
return true;
|
||||
}
|
||||
else if (elements[1] == "urgency")
|
||||
@@ -353,15 +353,15 @@ bool DOM::get (const std::string& name, const Task& task, Variant& value)
|
||||
// <date>.minute
|
||||
// <date>.second
|
||||
Date date (ref.get_date (canonical));
|
||||
if (elements[2] == "year") { value = Variant (date.year ()); return true; }
|
||||
else if (elements[2] == "month") { value = Variant (date.month ()); return true; }
|
||||
else if (elements[2] == "day") { value = Variant (date.day ()); return true; }
|
||||
else if (elements[2] == "week") { value = Variant (date.week ()); return true; }
|
||||
else if (elements[2] == "weekday") { value = Variant (date.dayOfWeek ()); return true; }
|
||||
else if (elements[2] == "julian") { value = Variant (date.dayOfYear ()); return true; }
|
||||
else if (elements[2] == "hour") { value = Variant (date.hour ()); return true; }
|
||||
else if (elements[2] == "minute") { value = Variant (date.minute ()); return true; }
|
||||
else if (elements[2] == "second") { value = Variant (date.second ()); return true; }
|
||||
if (elements[2] == "year") { value = Variant (static_cast<int> (date.year ())); return true; }
|
||||
else if (elements[2] == "month") { value = Variant (static_cast<int> (date.month ())); return true; }
|
||||
else if (elements[2] == "day") { value = Variant (static_cast<int> (date.day ())); return true; }
|
||||
else if (elements[2] == "week") { value = Variant (static_cast<int> (date.week ())); return true; }
|
||||
else if (elements[2] == "weekday") { value = Variant (static_cast<int> (date.dayOfWeek ())); return true; }
|
||||
else if (elements[2] == "julian") { value = Variant (static_cast<int> (date.dayOfYear ())); return true; }
|
||||
else if (elements[2] == "hour") { value = Variant (static_cast<int> (date.hour ())); return true; }
|
||||
else if (elements[2] == "minute") { value = Variant (static_cast<int> (date.minute ())); return true; }
|
||||
else if (elements[2] == "second") { value = Variant (static_cast<int> (date.second ())); return true; }
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -420,15 +420,15 @@ bool DOM::get (const std::string& name, const Task& task, Variant& value)
|
||||
// <annotations>.<N>.entry.minute
|
||||
// <annotations>.<N>.entry.second
|
||||
Date date (i->first.substr (11));
|
||||
if (elements[4] == "year") { value = Variant (date.year ()); return true; }
|
||||
else if (elements[4] == "month") { value = Variant (date.month ()); return true; }
|
||||
else if (elements[4] == "day") { value = Variant (date.day ()); return true; }
|
||||
else if (elements[4] == "week") { value = Variant (date.week ()); return true; }
|
||||
else if (elements[4] == "weekday") { value = Variant (date.dayOfWeek ()); return true; }
|
||||
else if (elements[4] == "julian") { value = Variant (date.dayOfYear ()); return true; }
|
||||
else if (elements[4] == "hour") { value = Variant (date.hour ()); return true; }
|
||||
else if (elements[4] == "minute") { value = Variant (date.minute ()); return true; }
|
||||
else if (elements[4] == "second") { value = Variant (date.second ()); return true; }
|
||||
if (elements[4] == "year") { value = Variant (static_cast<int> (date.year ())); return true; }
|
||||
else if (elements[4] == "month") { value = Variant (static_cast<int> (date.month ())); return true; }
|
||||
else if (elements[4] == "day") { value = Variant (static_cast<int> (date.day ())); return true; }
|
||||
else if (elements[4] == "week") { value = Variant (static_cast<int> (date.week ())); return true; }
|
||||
else if (elements[4] == "weekday") { value = Variant (static_cast<int> (date.dayOfWeek ())); return true; }
|
||||
else if (elements[4] == "julian") { value = Variant (static_cast<int> (date.dayOfYear ())); return true; }
|
||||
else if (elements[4] == "hour") { value = Variant (static_cast<int> (date.hour ())); return true; }
|
||||
else if (elements[4] == "minute") { value = Variant (static_cast<int> (date.minute ())); return true; }
|
||||
else if (elements[4] == "second") { value = Variant (static_cast<int> (date.second ())); return true; }
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -31,13 +31,13 @@
|
||||
#include <assert.h>
|
||||
#include <string.h>
|
||||
#include <stdlib.h>
|
||||
#include <ctype.h>
|
||||
#include <Nibbler.h>
|
||||
#include <Date.h>
|
||||
#include <Variant.h>
|
||||
#include <Dates.h>
|
||||
#include <text.h>
|
||||
#include <util.h>
|
||||
#include <utf8.h>
|
||||
#include <i18n.h>
|
||||
#include <Context.h>
|
||||
|
||||
@@ -823,7 +823,7 @@ void Date::operator++ (int)
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
bool Date::isEpoch (const std::string& input)
|
||||
{
|
||||
if (digitsOnly (input) &&
|
||||
if (Lexer::isAllDigits (input) &&
|
||||
input.length () <= 10 )
|
||||
{
|
||||
_t = (time_t) atoi (input.c_str ());
|
||||
|
||||
@@ -30,6 +30,7 @@
|
||||
#include <text.h>
|
||||
#include <Dates.h>
|
||||
#include <Date.h>
|
||||
#include <Lexer.h>
|
||||
#include <i18n.h>
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
@@ -354,7 +355,7 @@ bool namedDates (const std::string& name, Variant& value)
|
||||
// 4th
|
||||
else if ((
|
||||
name.length () == 3 &&
|
||||
isdigit (name[0]) &&
|
||||
Lexer::isDigit (name[0]) &&
|
||||
((name[1] == 's' && name[2] == 't') ||
|
||||
(name[1] == 'n' && name[2] == 'd') ||
|
||||
(name[1] == 'r' && name[2] == 'd') ||
|
||||
@@ -363,8 +364,8 @@ bool namedDates (const std::string& name, Variant& value)
|
||||
||
|
||||
(
|
||||
name.length () == 4 &&
|
||||
isdigit (name[0]) &&
|
||||
isdigit (name[1]) &&
|
||||
Lexer::isDigit (name[0]) &&
|
||||
Lexer::isDigit (name[1]) &&
|
||||
((name[2] == 's' && name[3] == 't') ||
|
||||
(name[2] == 'n' && name[3] == 'd') ||
|
||||
(name[2] == 'r' && name[3] == 'd') ||
|
||||
@@ -375,7 +376,7 @@ bool namedDates (const std::string& name, Variant& value)
|
||||
int number;
|
||||
std::string ordinal;
|
||||
|
||||
if (isdigit (name[1]))
|
||||
if (Lexer::isDigit (name[1]))
|
||||
{
|
||||
number = strtol (name.substr (0, 2).c_str (), NULL, 10);
|
||||
ordinal = lowerCase (name.substr (2));
|
||||
|
||||
@@ -34,7 +34,7 @@
|
||||
#include <stdlib.h>
|
||||
#include <Directory.h>
|
||||
|
||||
#if defined SOLARIS || defined NETBSD
|
||||
#if defined SOLARIS || defined NETBSD || defined FREEBSD
|
||||
#include <limits.h>
|
||||
#endif
|
||||
|
||||
|
||||
@@ -61,47 +61,48 @@ static struct
|
||||
{"fortnight", 14 * DAY, true},
|
||||
{"hours", 1 * HOUR, false},
|
||||
{"hour", 1 * HOUR, true},
|
||||
{"hrs", 1 * HOUR, true},
|
||||
{"hrs", 1 * HOUR, false},
|
||||
{"hr", 1 * HOUR, true},
|
||||
{"h", 1 * HOUR, false},
|
||||
{"minutes", 1 * MINUTE, false},
|
||||
{"minute", 1 * MINUTE, false},
|
||||
{"minute", 1 * MINUTE, true},
|
||||
{"mins", 1 * MINUTE, false},
|
||||
{"min", 1 * MINUTE, false},
|
||||
{"min", 1 * MINUTE, true},
|
||||
{"monthly", 30 * DAY, true},
|
||||
{"months", 30 * DAY, false},
|
||||
{"month", 30 * DAY, true},
|
||||
{"mnths", 30 * DAY, false},
|
||||
{"mths", 30 * DAY, false},
|
||||
{"mth", 30 * DAY, false},
|
||||
{"mth", 30 * DAY, true},
|
||||
{"mos", 30 * DAY, false},
|
||||
{"mo", 30 * DAY, false},
|
||||
{"mo", 30 * DAY, true},
|
||||
{"m", 30 * DAY, false},
|
||||
{"quarterly", 91 * DAY, true},
|
||||
{"quarters", 91 * DAY, false},
|
||||
{"quarter", 91 * DAY, true},
|
||||
{"qrtrs", 91 * DAY, false},
|
||||
{"qrtr", 91 * DAY, true},
|
||||
{"qtrs", 91 * DAY, false},
|
||||
{"qtr", 91 * DAY, false},
|
||||
{"qtr", 91 * DAY, true},
|
||||
{"q", 91 * DAY, false},
|
||||
{"semiannual", 183 * DAY, true},
|
||||
{"sennight", 14 * DAY, false},
|
||||
{"seconds", 1 * SECOND, false},
|
||||
{"second", 1 * SECOND, true},
|
||||
{"secs", 1 * SECOND, true},
|
||||
{"secs", 1 * SECOND, false},
|
||||
{"sec", 1 * SECOND, true},
|
||||
{"s", 1 * SECOND, false},
|
||||
{"weekdays", 1 * DAY, true},
|
||||
{"weekly", 7 * DAY, true},
|
||||
{"weeks", 7 * DAY, false},
|
||||
{"week", 7 * DAY, true},
|
||||
{"wks", 7 * DAY, true},
|
||||
{"wks", 7 * DAY, false},
|
||||
{"wk", 7 * DAY, true},
|
||||
{"w", 7 * DAY, false},
|
||||
{"yearly", 365 * DAY, true},
|
||||
{"years", 365 * DAY, false},
|
||||
{"year", 365 * DAY, true},
|
||||
{"yrs", 365 * DAY, true},
|
||||
{"yrs", 365 * DAY, false},
|
||||
{"yr", 365 * DAY, true},
|
||||
{"y", 365 * DAY, false},
|
||||
};
|
||||
@@ -124,7 +125,7 @@ Duration::Duration (time_t input)
|
||||
Duration::Duration (const std::string& input)
|
||||
: _secs (0)
|
||||
{
|
||||
if (digitsOnly (input))
|
||||
if (Lexer::isAllDigits (input))
|
||||
{
|
||||
time_t value = (time_t) strtol (input.c_str (), NULL, 10);
|
||||
if (value == 0 || value > 60)
|
||||
@@ -301,10 +302,11 @@ bool Duration::parse (const std::string& input, std::string::size_type& start)
|
||||
std::string::size_type original_start = start;
|
||||
Nibbler n (input.substr (start));
|
||||
|
||||
// TODO This can be made static, and so preserved between calls.
|
||||
std::vector <std::string> units;
|
||||
for (int i = 0; i < NUM_DURATIONS; i++)
|
||||
units.push_back (durations[i].unit);
|
||||
// Static and so preserved between calls.
|
||||
static std::vector <std::string> units;
|
||||
if (units.size () == 0)
|
||||
for (unsigned int i = 0; i < NUM_DURATIONS; i++)
|
||||
units.push_back (durations[i].unit);
|
||||
|
||||
std::string number;
|
||||
std::string unit;
|
||||
@@ -312,13 +314,12 @@ bool Duration::parse (const std::string& input, std::string::size_type& start)
|
||||
if (n.getOneOf (units, unit))
|
||||
{
|
||||
if (n.depleted () ||
|
||||
Lexer::is_ws (n.next ()))
|
||||
Lexer::isWhitespace (n.next ()))
|
||||
{
|
||||
start = original_start + n.cursor ();
|
||||
|
||||
// Linear lookup - should be logarithmic.
|
||||
double seconds = 1;
|
||||
for (int i = 0; i < NUM_DURATIONS; i++)
|
||||
for (unsigned int i = 0; i < NUM_DURATIONS; i++)
|
||||
{
|
||||
if (durations[i].unit == unit &&
|
||||
durations[i].standalone == true)
|
||||
@@ -336,14 +337,14 @@ bool Duration::parse (const std::string& input, std::string::size_type& start)
|
||||
if (n.getOneOf (units, unit))
|
||||
{
|
||||
if (n.depleted () ||
|
||||
Lexer::is_ws (n.next ()))
|
||||
Lexer::isWhitespace (n.next ()))
|
||||
{
|
||||
start = original_start + n.cursor ();
|
||||
double quantity = strtod (number.c_str (), NULL);
|
||||
|
||||
// Linear lookup - should be logarithmic.
|
||||
double seconds = 1;
|
||||
for (int i = 0; i < NUM_DURATIONS; i++)
|
||||
for (unsigned int i = 0; i < NUM_DURATIONS; i++)
|
||||
{
|
||||
if (durations[i].unit == unit)
|
||||
{
|
||||
|
||||
186
src/Eval.cpp
186
src/Eval.cpp
@@ -127,7 +127,7 @@ void Eval::evaluateInfixExpression (const std::string& e, Variant& v) const
|
||||
// Reduce e to a vector of tokens.
|
||||
Lexer l (e);
|
||||
l.ambiguity (_ambiguity);
|
||||
std::vector <std::pair <std::string, Lexer::Type> > tokens;
|
||||
std::vector <std::pair <std::string, Lexer::Type>> tokens;
|
||||
std::string token;
|
||||
Lexer::Type type;
|
||||
while (l.token (token, type))
|
||||
@@ -155,7 +155,7 @@ void Eval::evaluatePostfixExpression (const std::string& e, Variant& v) const
|
||||
// Reduce e to a vector of tokens.
|
||||
Lexer l (e);
|
||||
l.ambiguity (_ambiguity);
|
||||
std::vector <std::pair <std::string, Lexer::Type> > tokens;
|
||||
std::vector <std::pair <std::string, Lexer::Type>> tokens;
|
||||
std::string token;
|
||||
Lexer::Type type;
|
||||
while (l.token (token, type))
|
||||
@@ -179,7 +179,7 @@ void Eval::compileExpression (const std::string& e)
|
||||
while (l.token (token, type))
|
||||
{
|
||||
if (_debug)
|
||||
context.debug ("Lexer '" + token + "' " + Lexer::type_name (type));
|
||||
context.debug ("Lexer '" + token + "' " + Lexer::typeToString (type));
|
||||
_compiled.push_back (std::pair <std::string, Lexer::Type> (token, type));
|
||||
}
|
||||
|
||||
@@ -236,7 +236,7 @@ void Eval::getBinaryOperators (std::vector <std::string>& all)
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
void Eval::evaluatePostfixStack (
|
||||
const std::vector <std::pair <std::string, Lexer::Type> >& tokens,
|
||||
const std::vector <std::pair <std::string, Lexer::Type>>& tokens,
|
||||
Variant& result) const
|
||||
{
|
||||
if (tokens.size () == 0)
|
||||
@@ -245,11 +245,11 @@ void Eval::evaluatePostfixStack (
|
||||
// This is stack used by the postfix evaluator.
|
||||
std::vector <Variant> values;
|
||||
|
||||
std::vector <std::pair <std::string, Lexer::Type> >::const_iterator token;
|
||||
std::vector <std::pair <std::string, Lexer::Type>>::const_iterator token;
|
||||
for (token = tokens.begin (); token != tokens.end (); ++token)
|
||||
{
|
||||
// Unary operators.
|
||||
if (token->second == Lexer::typeOperator &&
|
||||
if (token->second == Lexer::Type::op &&
|
||||
token->first == "!")
|
||||
{
|
||||
if (values.size () < 1)
|
||||
@@ -262,7 +262,7 @@ void Eval::evaluatePostfixStack (
|
||||
if (_debug)
|
||||
context.debug (format ("Eval {1} ↓'{2}' → ↑'{3}'", token->first, (std::string) right, (std::string) result));
|
||||
}
|
||||
else if (token->second == Lexer::typeOperator &&
|
||||
else if (token->second == Lexer::Type::op &&
|
||||
token->first == "_neg_")
|
||||
{
|
||||
if (values.size () < 1)
|
||||
@@ -278,7 +278,7 @@ void Eval::evaluatePostfixStack (
|
||||
if (_debug)
|
||||
context.debug (format ("Eval {1} ↓'{2}' → ↑'{3}'", token->first, (std::string) right, (std::string) result));
|
||||
}
|
||||
else if (token->second == Lexer::typeOperator &&
|
||||
else if (token->second == Lexer::Type::op &&
|
||||
token->first == "_pos_")
|
||||
{
|
||||
// The _pos_ operator is a NOP.
|
||||
@@ -287,7 +287,7 @@ void Eval::evaluatePostfixStack (
|
||||
}
|
||||
|
||||
// Binary operators.
|
||||
else if (token->second == Lexer::typeOperator)
|
||||
else if (token->second == Lexer::Type::op)
|
||||
{
|
||||
if (values.size () < 2)
|
||||
throw std::string (STRING_EVAL_NO_EVAL);
|
||||
@@ -338,24 +338,28 @@ void Eval::evaluatePostfixStack (
|
||||
Variant v (token->first);
|
||||
switch (token->second)
|
||||
{
|
||||
case Lexer::typeNumber:
|
||||
case Lexer::typeHex:
|
||||
v.cast (Variant::type_integer);
|
||||
if (_debug)
|
||||
context.debug (format ("Eval literal number ↑'{1}'", (std::string) v));
|
||||
case Lexer::Type::number:
|
||||
if (Lexer::isAllDigits (token->first))
|
||||
{
|
||||
v.cast (Variant::type_integer);
|
||||
if (_debug)
|
||||
context.debug (format ("Eval literal number ↑'{1}'", (std::string) v));
|
||||
}
|
||||
else
|
||||
{
|
||||
v.cast (Variant::type_real);
|
||||
if (_debug)
|
||||
context.debug (format ("Eval literal decimal ↑'{1}'", (std::string) v));
|
||||
}
|
||||
break;
|
||||
|
||||
case Lexer::typeDecimal:
|
||||
v.cast (Variant::type_real);
|
||||
if (_debug)
|
||||
context.debug (format ("Eval literal decimal ↑'{1}'", (std::string) v));
|
||||
break;
|
||||
|
||||
case Lexer::typeOperator:
|
||||
case Lexer::Type::op:
|
||||
throw std::string (STRING_EVAL_OP_EXPECTED);
|
||||
break;
|
||||
|
||||
case Lexer::typeIdentifier:
|
||||
case Lexer::Type::dom:
|
||||
case Lexer::Type::identifier:
|
||||
{
|
||||
bool found = false;
|
||||
std::vector <bool (*)(const std::string&, Variant&)>::const_iterator source;
|
||||
@@ -380,20 +384,33 @@ void Eval::evaluatePostfixStack (
|
||||
}
|
||||
break;
|
||||
|
||||
case Lexer::typeDate:
|
||||
case Lexer::Type::date:
|
||||
v.cast (Variant::type_date);
|
||||
if (_debug)
|
||||
context.debug (format ("Eval literal date ↑'{1}'", (std::string) v));
|
||||
break;
|
||||
|
||||
case Lexer::typeDuration:
|
||||
case Lexer::Type::duration:
|
||||
v.cast (Variant::type_duration);
|
||||
if (_debug)
|
||||
context.debug (format ("Eval literal duration ↑'{1}'", (std::string) v));
|
||||
break;
|
||||
|
||||
// Nothing to do.
|
||||
case Lexer::typeString:
|
||||
/*
|
||||
case Lexer::Type::uuid:
|
||||
case Lexer::Type::hex:
|
||||
case Lexer::Type::list:
|
||||
case Lexer::Type::url:
|
||||
case Lexer::Type::pair:
|
||||
case Lexer::Type::separator:
|
||||
case Lexer::Type::tag:
|
||||
case Lexer::Type::path:
|
||||
case Lexer::Type::substitution:
|
||||
case Lexer::Type::pattern:
|
||||
case Lexer::Type::word:
|
||||
*/
|
||||
case Lexer::Type::string:
|
||||
default:
|
||||
if (_debug)
|
||||
context.debug (format ("Eval literal string ↑'{1}'", (std::string) v));
|
||||
@@ -427,26 +444,26 @@ void Eval::evaluatePostfixStack (
|
||||
// Primitive --> "(" Logical ")" | Variant
|
||||
//
|
||||
void Eval::infixParse (
|
||||
std::vector <std::pair <std::string, Lexer::Type> >& infix) const
|
||||
std::vector <std::pair <std::string, Lexer::Type>>& infix) const
|
||||
{
|
||||
int i = 0;
|
||||
unsigned int i = 0;
|
||||
parseLogical (infix, i);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
// Logical --> Regex {( "and" | "or" | "xor" ) Regex}
|
||||
bool Eval::parseLogical (
|
||||
std::vector <std::pair <std::string, Lexer::Type> >& infix,
|
||||
int &i) const
|
||||
std::vector <std::pair <std::string, Lexer::Type>>& infix,
|
||||
unsigned int &i) const
|
||||
{
|
||||
if (i < infix.size () &&
|
||||
parseRegex (infix, i))
|
||||
{
|
||||
while (i < infix.size () &&
|
||||
infix[i].second == Lexer::Type::op &&
|
||||
(infix[i].first == "and" ||
|
||||
infix[i].first == "or" ||
|
||||
infix[i].first == "xor") &&
|
||||
infix[i].second == Lexer::typeOperator)
|
||||
infix[i].first == "xor"))
|
||||
{
|
||||
++i;
|
||||
if (! parseRegex (infix, i))
|
||||
@@ -462,16 +479,16 @@ bool Eval::parseLogical (
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
// Regex --> Equality {( "~" | "!~" ) Equality}
|
||||
bool Eval::parseRegex (
|
||||
std::vector <std::pair <std::string, Lexer::Type> >& infix,
|
||||
int &i) const
|
||||
std::vector <std::pair <std::string, Lexer::Type>>& infix,
|
||||
unsigned int &i) const
|
||||
{
|
||||
if (i < infix.size () &&
|
||||
parseEquality (infix, i))
|
||||
{
|
||||
while (i < infix.size () &&
|
||||
infix[i].second == Lexer::Type::op &&
|
||||
(infix[i].first == "~" ||
|
||||
infix[i].first == "!~") &&
|
||||
infix[i].second == Lexer::typeOperator)
|
||||
infix[i].first == "!~"))
|
||||
{
|
||||
++i;
|
||||
if (! parseEquality (infix, i))
|
||||
@@ -487,18 +504,18 @@ bool Eval::parseRegex (
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
// Equality --> Comparative {( "==" | "=" | "!==" | "!=" ) Comparative}
|
||||
bool Eval::parseEquality (
|
||||
std::vector <std::pair <std::string, Lexer::Type> >& infix,
|
||||
int &i) const
|
||||
std::vector <std::pair <std::string, Lexer::Type>>& infix,
|
||||
unsigned int &i) const
|
||||
{
|
||||
if (i < infix.size () &&
|
||||
parseComparative (infix, i))
|
||||
{
|
||||
while (i < infix.size () &&
|
||||
infix[i].second == Lexer::Type::op &&
|
||||
(infix[i].first == "==" ||
|
||||
infix[i].first == "=" ||
|
||||
infix[i].first == "!==" ||
|
||||
infix[i].first == "!=") &&
|
||||
infix[i].second == Lexer::typeOperator)
|
||||
infix[i].first == "!="))
|
||||
{
|
||||
++i;
|
||||
if (! parseComparative (infix, i))
|
||||
@@ -514,18 +531,18 @@ bool Eval::parseEquality (
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
// Comparative --> Arithmetic {( "<=" | "<" | ">=" | ">" ) Arithmetic}
|
||||
bool Eval::parseComparative (
|
||||
std::vector <std::pair <std::string, Lexer::Type> >& infix,
|
||||
int &i) const
|
||||
std::vector <std::pair <std::string, Lexer::Type>>& infix,
|
||||
unsigned int &i) const
|
||||
{
|
||||
if (i < infix.size () &&
|
||||
parseArithmetic (infix, i))
|
||||
{
|
||||
while (i < infix.size () &&
|
||||
infix[i].second == Lexer::Type::op &&
|
||||
(infix[i].first == "<=" ||
|
||||
infix[i].first == "<" ||
|
||||
infix[i].first == ">=" ||
|
||||
infix[i].first == ">") &&
|
||||
infix[i].second == Lexer::typeOperator)
|
||||
infix[i].first == ">"))
|
||||
{
|
||||
++i;
|
||||
if (! parseArithmetic (infix, i))
|
||||
@@ -541,16 +558,16 @@ bool Eval::parseComparative (
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
// Arithmetic --> Geometric {( "+" | "-" ) Geometric}
|
||||
bool Eval::parseArithmetic (
|
||||
std::vector <std::pair <std::string, Lexer::Type> >& infix,
|
||||
int &i) const
|
||||
std::vector <std::pair <std::string, Lexer::Type>>& infix,
|
||||
unsigned int &i) const
|
||||
{
|
||||
if (i < infix.size () &&
|
||||
parseGeometric (infix, i))
|
||||
{
|
||||
while (i < infix.size () &&
|
||||
infix[i].second == Lexer::Type::op &&
|
||||
(infix[i].first == "+" ||
|
||||
infix[i].first == "-") &&
|
||||
infix[i].second == Lexer::typeOperator)
|
||||
infix[i].first == "-"))
|
||||
{
|
||||
++i;
|
||||
if (! parseGeometric (infix, i))
|
||||
@@ -566,17 +583,17 @@ bool Eval::parseArithmetic (
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
// Geometric --> Tag {( "*" | "/" | "%" ) Tag}
|
||||
bool Eval::parseGeometric (
|
||||
std::vector <std::pair <std::string, Lexer::Type> >& infix,
|
||||
int &i) const
|
||||
std::vector <std::pair <std::string, Lexer::Type>>& infix,
|
||||
unsigned int &i) const
|
||||
{
|
||||
if (i < infix.size () &&
|
||||
parseTag (infix, i))
|
||||
{
|
||||
while (i < infix.size () &&
|
||||
infix[i].second == Lexer::Type::op &&
|
||||
(infix[i].first == "*" ||
|
||||
infix[i].first == "/" ||
|
||||
infix[i].first == "%") &&
|
||||
infix[i].second == Lexer::typeOperator)
|
||||
infix[i].first == "%"))
|
||||
{
|
||||
++i;
|
||||
if (! parseTag (infix, i))
|
||||
@@ -592,16 +609,16 @@ bool Eval::parseGeometric (
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
// Tag --> Unary {( "_hastag_" | "_notag_" ) Unary}
|
||||
bool Eval::parseTag (
|
||||
std::vector <std::pair <std::string, Lexer::Type> >& infix,
|
||||
int &i) const
|
||||
std::vector <std::pair <std::string, Lexer::Type>>& infix,
|
||||
unsigned int &i) const
|
||||
{
|
||||
if (i < infix.size () &&
|
||||
parseUnary (infix, i))
|
||||
{
|
||||
while (i < infix.size () &&
|
||||
infix[i].second == Lexer::Type::op &&
|
||||
(infix[i].first == "_hastag_" ||
|
||||
infix[i].first == "_notag_") &&
|
||||
infix[i].second == Lexer::typeOperator)
|
||||
infix[i].first == "_notag_"))
|
||||
{
|
||||
++i;
|
||||
if (! parseUnary (infix, i))
|
||||
@@ -617,8 +634,8 @@ bool Eval::parseTag (
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
// Unary --> [( "-" | "+" | "!" )] Exponent
|
||||
bool Eval::parseUnary (
|
||||
std::vector <std::pair <std::string, Lexer::Type> >& infix,
|
||||
int &i) const
|
||||
std::vector <std::pair <std::string, Lexer::Type>>& infix,
|
||||
unsigned int &i) const
|
||||
{
|
||||
if (i < infix.size ())
|
||||
{
|
||||
@@ -644,15 +661,15 @@ bool Eval::parseUnary (
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
// Exponent --> Primitive ["^" Primitive]
|
||||
bool Eval::parseExponent (
|
||||
std::vector <std::pair <std::string, Lexer::Type> >& infix,
|
||||
int &i) const
|
||||
std::vector <std::pair <std::string, Lexer::Type>>& infix,
|
||||
unsigned int& i) const
|
||||
{
|
||||
if (i < infix.size () &&
|
||||
parsePrimitive (infix, i))
|
||||
{
|
||||
while (i < infix.size () &&
|
||||
infix[i].first == "^" &&
|
||||
infix[i].second == Lexer::typeOperator)
|
||||
infix[i].second == Lexer::Type::op &&
|
||||
infix[i].first == "^")
|
||||
{
|
||||
++i;
|
||||
if (! parsePrimitive (infix, i))
|
||||
@@ -668,8 +685,8 @@ bool Eval::parseExponent (
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
// Primitive --> "(" Logical ")" | Variant
|
||||
bool Eval::parsePrimitive (
|
||||
std::vector <std::pair <std::string, Lexer::Type> >& infix,
|
||||
int &i) const
|
||||
std::vector <std::pair <std::string, Lexer::Type>>& infix,
|
||||
unsigned int &i) const
|
||||
{
|
||||
if (i < infix.size ())
|
||||
{
|
||||
@@ -706,7 +723,7 @@ bool Eval::parsePrimitive (
|
||||
++i;
|
||||
return true;
|
||||
}
|
||||
else if (infix[i].second != Lexer::typeOperator)
|
||||
else if (infix[i].second != Lexer::Type::op)
|
||||
{
|
||||
++i;
|
||||
return true;
|
||||
@@ -750,32 +767,32 @@ bool Eval::parsePrimitive (
|
||||
// Exit.
|
||||
//
|
||||
void Eval::infixToPostfix (
|
||||
std::vector <std::pair <std::string, Lexer::Type> >& infix) const
|
||||
std::vector <std::pair <std::string, Lexer::Type>>& infix) const
|
||||
{
|
||||
// Short circuit.
|
||||
if (infix.size () == 1)
|
||||
return;
|
||||
|
||||
// Result.
|
||||
std::vector <std::pair <std::string, Lexer::Type> > postfix;
|
||||
std::vector <std::pair <std::string, Lexer::Type>> postfix;
|
||||
|
||||
// Shunting yard.
|
||||
std::vector <std::pair <std::string, Lexer::Type> > op_stack;
|
||||
std::vector <std::pair <std::string, Lexer::Type>> op_stack;
|
||||
|
||||
// Operator characteristics.
|
||||
char type;
|
||||
int precedence;
|
||||
unsigned int precedence;
|
||||
char associativity;
|
||||
|
||||
std::vector <std::pair <std::string, Lexer::Type> >::iterator token;
|
||||
std::vector <std::pair <std::string, Lexer::Type>>::iterator token;
|
||||
for (token = infix.begin (); token != infix.end (); ++token)
|
||||
{
|
||||
if (token->second == Lexer::typeOperator &&
|
||||
if (token->second == Lexer::Type::op &&
|
||||
token->first == "(")
|
||||
{
|
||||
op_stack.push_back (*token);
|
||||
}
|
||||
else if (token->second == Lexer::typeOperator &&
|
||||
else if (token->second == Lexer::Type::op &&
|
||||
token->first == ")")
|
||||
{
|
||||
while (op_stack.size () &&
|
||||
@@ -790,11 +807,11 @@ void Eval::infixToPostfix (
|
||||
else
|
||||
throw std::string ("Mismatched parentheses in expression");
|
||||
}
|
||||
else if (token->second == Lexer::typeOperator &&
|
||||
else if (token->second == Lexer::Type::op &&
|
||||
identifyOperator (token->first, type, precedence, associativity))
|
||||
{
|
||||
char type2;
|
||||
int precedence2;
|
||||
unsigned int precedence2;
|
||||
char associativity2;
|
||||
while (op_stack.size () > 0 &&
|
||||
identifyOperator (op_stack.back ().first, type2, precedence2, associativity2) &&
|
||||
@@ -830,7 +847,7 @@ void Eval::infixToPostfix (
|
||||
bool Eval::identifyOperator (
|
||||
const std::string& op,
|
||||
char& type,
|
||||
int& precedence,
|
||||
unsigned int& precedence,
|
||||
char& associativity) const
|
||||
{
|
||||
for (unsigned int i = 0; i < NUM_OPERATORS; ++i)
|
||||
@@ -849,22 +866,21 @@ bool Eval::identifyOperator (
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
std::string Eval::dump (
|
||||
std::vector <std::pair <std::string, Lexer::Type> >& tokens) const
|
||||
std::vector <std::pair <std::string, Lexer::Type>>& tokens) const
|
||||
{
|
||||
// Set up a color mapping.
|
||||
std::map <Lexer::Type, Color> color_map;
|
||||
color_map[Lexer::typeNone] = Color ("rgb000 on gray6");
|
||||
color_map[Lexer::typeOperator] = Color ("gray14 on gray6");
|
||||
color_map[Lexer::typeNumber] = Color ("rgb530 on gray6");
|
||||
color_map[Lexer::typeHex] = Color ("rgb303 on gray6");
|
||||
color_map[Lexer::typeDecimal] = Color ("rgb530 on gray6");
|
||||
color_map[Lexer::typeString] = Color ("rgb550 on gray6");
|
||||
color_map[Lexer::typeIdentifier] = Color ("rgb035 on gray6");
|
||||
color_map[Lexer::typeDate] = Color ("rgb150 on gray6");
|
||||
color_map[Lexer::typeDuration] = Color ("rgb531 on gray6");
|
||||
color_map[Lexer::Type::op] = Color ("gray14 on gray6");
|
||||
color_map[Lexer::Type::number] = Color ("rgb530 on gray6");
|
||||
color_map[Lexer::Type::hex] = Color ("rgb303 on gray6");
|
||||
color_map[Lexer::Type::string] = Color ("rgb550 on gray6");
|
||||
color_map[Lexer::Type::dom] = Color ("rgb045 on gray6");
|
||||
color_map[Lexer::Type::identifier] = Color ("rgb035 on gray6");
|
||||
color_map[Lexer::Type::date] = Color ("rgb150 on gray6");
|
||||
color_map[Lexer::Type::duration] = Color ("rgb531 on gray6");
|
||||
|
||||
std::string output;
|
||||
std::vector <std::pair <std::string, Lexer::Type> >::const_iterator i;
|
||||
std::vector <std::pair <std::string, Lexer::Type>>::const_iterator i;
|
||||
for (i = tokens.begin (); i != tokens.end (); ++i)
|
||||
{
|
||||
if (i != tokens.begin ())
|
||||
@@ -874,7 +890,7 @@ std::string Eval::dump (
|
||||
if (color_map[i->second].nontrivial ())
|
||||
c = color_map[i->second];
|
||||
else
|
||||
c = color_map[Lexer::typeNone];
|
||||
c = Color ("rgb000 on gray6");
|
||||
|
||||
output += c.colorize (i->first);
|
||||
}
|
||||
|
||||
32
src/Eval.h
32
src/Eval.h
@@ -53,28 +53,28 @@ public:
|
||||
static void getBinaryOperators (std::vector <std::string>&);
|
||||
|
||||
private:
|
||||
void evaluatePostfixStack (const std::vector <std::pair <std::string, Lexer::Type> >&, Variant&) const;
|
||||
void infixToPostfix (std::vector <std::pair <std::string, Lexer::Type> >&) const;
|
||||
void infixParse (std::vector <std::pair <std::string, Lexer::Type> >&) const;
|
||||
bool parseLogical (std::vector <std::pair <std::string, Lexer::Type> >&, int &) const;
|
||||
bool parseRegex (std::vector <std::pair <std::string, Lexer::Type> >&, int &) const;
|
||||
bool parseEquality (std::vector <std::pair <std::string, Lexer::Type> >&, int &) const;
|
||||
bool parseComparative (std::vector <std::pair <std::string, Lexer::Type> >&, int &) const;
|
||||
bool parseArithmetic (std::vector <std::pair <std::string, Lexer::Type> >&, int &) const;
|
||||
bool parseGeometric (std::vector <std::pair <std::string, Lexer::Type> >&, int &) const;
|
||||
bool parseTag (std::vector <std::pair <std::string, Lexer::Type> >&, int &) const;
|
||||
bool parseUnary (std::vector <std::pair <std::string, Lexer::Type> >&, int &) const;
|
||||
bool parseExponent (std::vector <std::pair <std::string, Lexer::Type> >&, int &) const;
|
||||
bool parsePrimitive (std::vector <std::pair <std::string, Lexer::Type> >&, int &) const;
|
||||
bool identifyOperator (const std::string&, char&, int&, char&) const;
|
||||
void evaluatePostfixStack (const std::vector <std::pair <std::string, Lexer::Type>>&, Variant&) const;
|
||||
void infixToPostfix (std::vector <std::pair <std::string, Lexer::Type>>&) const;
|
||||
void infixParse (std::vector <std::pair <std::string, Lexer::Type>>&) const;
|
||||
bool parseLogical (std::vector <std::pair <std::string, Lexer::Type>>&, unsigned int &) const;
|
||||
bool parseRegex (std::vector <std::pair <std::string, Lexer::Type>>&, unsigned int &) const;
|
||||
bool parseEquality (std::vector <std::pair <std::string, Lexer::Type>>&, unsigned int &) const;
|
||||
bool parseComparative (std::vector <std::pair <std::string, Lexer::Type>>&, unsigned int &) const;
|
||||
bool parseArithmetic (std::vector <std::pair <std::string, Lexer::Type>>&, unsigned int &) const;
|
||||
bool parseGeometric (std::vector <std::pair <std::string, Lexer::Type>>&, unsigned int &) const;
|
||||
bool parseTag (std::vector <std::pair <std::string, Lexer::Type>>&, unsigned int &) const;
|
||||
bool parseUnary (std::vector <std::pair <std::string, Lexer::Type>>&, unsigned int &) const;
|
||||
bool parseExponent (std::vector <std::pair <std::string, Lexer::Type>>&, unsigned int &) const;
|
||||
bool parsePrimitive (std::vector <std::pair <std::string, Lexer::Type>>&, unsigned int &) const;
|
||||
bool identifyOperator (const std::string&, char&, unsigned int&, char&) const;
|
||||
|
||||
std::string dump (std::vector <std::pair <std::string, Lexer::Type> >&) const;
|
||||
std::string dump (std::vector <std::pair <std::string, Lexer::Type>>&) const;
|
||||
|
||||
private:
|
||||
std::vector <bool (*)(const std::string&, Variant&)> _sources;
|
||||
bool _ambiguity;
|
||||
bool _debug;
|
||||
std::vector <std::pair <std::string, Lexer::Type> > _compiled;
|
||||
std::vector <std::pair <std::string, Lexer::Type>> _compiled;
|
||||
};
|
||||
|
||||
|
||||
|
||||
@@ -466,7 +466,7 @@ void Hooks::assertValidJSON (const std::vector <std::string>& input) const
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
void Hooks::assertNTasks (const std::vector <std::string>& input, int n) const
|
||||
void Hooks::assertNTasks (const std::vector <std::string>& input, unsigned int n) const
|
||||
{
|
||||
if (input.size () != n)
|
||||
{
|
||||
@@ -520,6 +520,33 @@ void Hooks::assertFeedback (const std::vector <std::string>& input) const
|
||||
}
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
std::vector <std::string>& Hooks::buildHookScriptArgs (std::vector <std::string>& args)
|
||||
{
|
||||
Variant v;
|
||||
|
||||
// Hooks API version.
|
||||
args.push_back ("api:2");
|
||||
|
||||
// Command line Taskwarrior was called with.
|
||||
context.dom.get ("context.args", v);
|
||||
args.push_back ("args:" + std::string (v));
|
||||
|
||||
// Command to be executed.
|
||||
args.push_back ("command:" + context.cli.getCommand ());
|
||||
|
||||
// rc file used after applying all overrides.
|
||||
args.push_back ("rc:" + context.rc_file._data);
|
||||
|
||||
// Directory containing *.data files.
|
||||
args.push_back ("data:" + context.data_dir._data);
|
||||
|
||||
// Taskwarrior version, same as returned by "task --version"
|
||||
args.push_back ("version:" + std::string(VERSION));
|
||||
|
||||
return args;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
int Hooks::callHookScript (
|
||||
const std::string& script,
|
||||
@@ -542,11 +569,18 @@ int Hooks::callHookScript (
|
||||
for (i = input.begin (); i != input.end (); ++i)
|
||||
inputStr += *i + "\n";
|
||||
|
||||
std::string outputStr;
|
||||
std::vector <std::string> args;
|
||||
int status;
|
||||
buildHookScriptArgs (args);
|
||||
if (_debug >= 2)
|
||||
{
|
||||
context.debug ("Hooks: args");
|
||||
for (auto arg: args)
|
||||
context.debug (" " + arg);
|
||||
}
|
||||
|
||||
// Measure time for each hook if running in debug
|
||||
int status;
|
||||
std::string outputStr;
|
||||
if (_debug >= 2)
|
||||
{
|
||||
Timer timer_per_hook("Hooks::execute (" + script + ")");
|
||||
|
||||
@@ -54,9 +54,10 @@ private:
|
||||
void separateOutput (const std::vector <std::string>&, std::vector <std::string>&, std::vector <std::string>&) const;
|
||||
bool isJSON (const std::string&) const;
|
||||
void assertValidJSON (const std::vector <std::string>&) const;
|
||||
void assertNTasks (const std::vector <std::string>&, int) const;
|
||||
void assertNTasks (const std::vector <std::string>&, unsigned int) const;
|
||||
void assertSameTask (const std::vector <std::string>&, const Task&) const;
|
||||
void assertFeedback (const std::vector <std::string>&) const;
|
||||
std::vector <std::string>& buildHookScriptArgs (std::vector <std::string>&);
|
||||
int callHookScript (const std::string&, const std::vector <std::string>&, std::vector <std::string>&);
|
||||
|
||||
private:
|
||||
|
||||
@@ -25,6 +25,7 @@
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#include <cmake.h>
|
||||
#include <Lexer.h>
|
||||
#include <ISO8601.h>
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
@@ -196,7 +197,7 @@ bool ISO8601d::parse_date_time_ext (Nibbler& n)
|
||||
else if (parse_off_ext (n))
|
||||
;
|
||||
|
||||
if (! isdigit (n.next ()))
|
||||
if (! Lexer::isDigit (n.next ()))
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -228,16 +229,16 @@ bool ISO8601d::parse_date_time (Nibbler& n)
|
||||
if (n.skip ('Z'))
|
||||
{
|
||||
_utc = true;
|
||||
if (!isdigit (n.next ()))
|
||||
if (!Lexer::isDigit (n.next ()))
|
||||
return true;
|
||||
}
|
||||
else if (parse_off (n))
|
||||
{
|
||||
if (!isdigit (n.next ()))
|
||||
if (!Lexer::isDigit (n.next ()))
|
||||
return true;
|
||||
}
|
||||
|
||||
if (!isdigit (n.next ()))
|
||||
if (!Lexer::isDigit (n.next ()))
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -277,13 +278,13 @@ bool ISO8601d::parse_date_ext (Nibbler& n)
|
||||
}
|
||||
|
||||
_year = year;
|
||||
if (!isdigit (n.next ()))
|
||||
if (!Lexer::isDigit (n.next ()))
|
||||
return true;
|
||||
}
|
||||
else if (n.getDigit3 (_julian))
|
||||
{
|
||||
_year = year;
|
||||
if (!isdigit (n.next ()))
|
||||
if (!Lexer::isDigit (n.next ()))
|
||||
return true;
|
||||
}
|
||||
else if (n.getDigit2 (month) &&
|
||||
@@ -293,7 +294,7 @@ bool ISO8601d::parse_date_ext (Nibbler& n)
|
||||
_year = year;
|
||||
_month = month;
|
||||
_day = day;
|
||||
if (!isdigit (n.next ()))
|
||||
if (!Lexer::isDigit (n.next ()))
|
||||
return true;
|
||||
}
|
||||
}
|
||||
@@ -327,7 +328,7 @@ bool ISO8601d::parse_date (Nibbler& n, bool ambiguous)
|
||||
_weekday = day;
|
||||
|
||||
_year = year;
|
||||
if (!isdigit (n.next ()))
|
||||
if (!Lexer::isDigit (n.next ()))
|
||||
return true;
|
||||
}
|
||||
}
|
||||
@@ -336,7 +337,7 @@ bool ISO8601d::parse_date (Nibbler& n, bool ambiguous)
|
||||
if (n.getDigit2 (_month))
|
||||
{
|
||||
_year = year;
|
||||
if (!isdigit (n.next ()))
|
||||
if (!Lexer::isDigit (n.next ()))
|
||||
return true;
|
||||
}
|
||||
}
|
||||
@@ -345,13 +346,13 @@ bool ISO8601d::parse_date (Nibbler& n, bool ambiguous)
|
||||
_year = year;
|
||||
_month = month / 100;
|
||||
_day = month % 100;
|
||||
if (!isdigit (n.next ()))
|
||||
if (!Lexer::isDigit (n.next ()))
|
||||
return true;
|
||||
}
|
||||
else if (ambiguous && n.getDigit3 (_julian))
|
||||
{
|
||||
_year = year;
|
||||
if (!isdigit (n.next ()))
|
||||
if (!Lexer::isDigit (n.next ()))
|
||||
return true;
|
||||
}
|
||||
}
|
||||
@@ -382,7 +383,7 @@ bool ISO8601d::parse_off_ext (Nibbler& n)
|
||||
offset += mm * 60;
|
||||
|
||||
_offset = (sign == "-") ? -offset : offset;
|
||||
if (!isdigit (n.next ()))
|
||||
if (!Lexer::isDigit (n.next ()))
|
||||
return true;
|
||||
}
|
||||
}
|
||||
@@ -412,7 +413,7 @@ bool ISO8601d::parse_off (Nibbler& n)
|
||||
offset += mm * 60;
|
||||
|
||||
_offset = (sign == "-") ? -offset : offset;
|
||||
if (!isdigit (n.next ()))
|
||||
if (!Lexer::isDigit (n.next ()))
|
||||
return true;
|
||||
}
|
||||
}
|
||||
@@ -453,7 +454,7 @@ bool ISO8601d::parse_time_ext (Nibbler& n)
|
||||
if (_ambiguity)
|
||||
{
|
||||
_seconds = seconds;
|
||||
if (!isdigit (n.next ()))
|
||||
if (!Lexer::isDigit (n.next ()))
|
||||
return true;
|
||||
}
|
||||
}
|
||||
@@ -487,7 +488,7 @@ bool ISO8601d::parse_time (Nibbler& n, bool ambiguous)
|
||||
}
|
||||
|
||||
_seconds = seconds;
|
||||
if (!isdigit (n.next ()))
|
||||
if (!Lexer::isDigit (n.next ()))
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -504,7 +505,7 @@ bool ISO8601d::parse_time_utc_ext (Nibbler& n)
|
||||
n.skip ('Z'))
|
||||
{
|
||||
_utc = true;
|
||||
if (!isdigit (n.next ()))
|
||||
if (!Lexer::isDigit (n.next ()))
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -521,7 +522,7 @@ bool ISO8601d::parse_time_utc (Nibbler& n)
|
||||
n.skip ('Z'))
|
||||
{
|
||||
_utc = true;
|
||||
if (!isdigit (n.next ()))
|
||||
if (!Lexer::isDigit (n.next ()))
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -537,7 +538,7 @@ bool ISO8601d::parse_time_off_ext (Nibbler& n)
|
||||
if (parse_time_ext (n) &&
|
||||
parse_off_ext (n))
|
||||
{
|
||||
if (!isdigit (n.next ()))
|
||||
if (!Lexer::isDigit (n.next ()))
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -553,7 +554,7 @@ bool ISO8601d::parse_time_off (Nibbler& n)
|
||||
if (parse_time (n, true) &&
|
||||
parse_off (n))
|
||||
{
|
||||
if (!isdigit (n.next ()))
|
||||
if (!Lexer::isDigit (n.next ()))
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
1648
src/Lexer.cpp
1648
src/Lexer.cpp
File diff suppressed because it is too large
Load Diff
134
src/Lexer.h
134
src/Lexer.h
@@ -27,92 +27,86 @@
|
||||
#ifndef INCLUDED_LEXER
|
||||
#define INCLUDED_LEXER
|
||||
|
||||
#include <vector>
|
||||
#include <string>
|
||||
#include <vector>
|
||||
#include <cstddef>
|
||||
|
||||
// Lexer: A UTF8 lexical analyzer for every construct used on the Taskwarrior
|
||||
// command line, with additional recognized types for disambiguation.
|
||||
|
||||
class Lexer
|
||||
{
|
||||
public:
|
||||
// These are overridable.
|
||||
static std::string dateFormat;
|
||||
static bool isoEnabled;
|
||||
|
||||
enum Type
|
||||
{
|
||||
typeNone = 0,
|
||||
typeString,
|
||||
typeIdentifier,
|
||||
typeIdentifierEscape, // Intermediate
|
||||
typeEscape, // Intermediate
|
||||
typeEscapeHex, // Intermediate
|
||||
typeEscapeUnicode, // Intermediate
|
||||
typeNumber,
|
||||
typeDecimal,
|
||||
typeExponentIndicator, // Intermediate
|
||||
typeExponent, // Intermediate
|
||||
typeHex,
|
||||
typeOperator,
|
||||
typeDate,
|
||||
typeDuration,
|
||||
typeTag,
|
||||
/*
|
||||
Recognizing more types means that Lexer::*_split and Lexer::token approach
|
||||
the ideal form, whereby the command line becomes just one string that is
|
||||
lexed into tokens. Those tokens are then simply dissected by type..
|
||||
|
||||
typeUUID,
|
||||
typePattern,
|
||||
typeSubstitution,
|
||||
typeNameValue,
|
||||
*/
|
||||
};
|
||||
enum class Type { uuid, number, hex,
|
||||
string,
|
||||
list, url, pair, separator,
|
||||
tag,
|
||||
path,
|
||||
substitution, pattern,
|
||||
op,
|
||||
dom, identifier, word,
|
||||
date, duration };
|
||||
|
||||
Lexer (const std::string&);
|
||||
virtual ~Lexer ();
|
||||
Lexer (const Lexer&); // Not implemented.
|
||||
Lexer& operator= (const Lexer&); // Not implemented.
|
||||
bool operator== (const Lexer&); // Not implemented.
|
||||
bool token (std::string&, Type&);
|
||||
bool word (std::string&, Type&);
|
||||
~Lexer ();
|
||||
void ambiguity (bool);
|
||||
bool token (std::string&, Lexer::Type&);
|
||||
static std::vector <std::pair <std::string, Lexer::Type>> tokens (const std::string&);
|
||||
static std::vector <std::string> split (const std::string&);
|
||||
static std::string typeToString (Lexer::Type);
|
||||
static bool isAllDigits (const std::string&);
|
||||
static bool isOneWord (const std::string&);
|
||||
|
||||
static const std::string type_name (const Type&);
|
||||
static bool is_ws (int);
|
||||
static bool is_ident_start (int);
|
||||
static bool is_ident (int);
|
||||
static bool is_single_op (int);
|
||||
static bool is_dec_digit (int);
|
||||
static bool boundary (int, int);
|
||||
static void word_split (std::vector <std::string>&, const std::string&);
|
||||
static void token_split (std::vector <std::string>&, const std::string&);
|
||||
static void token_split (std::vector <std::pair <std::string, Lexer::Type> >&, const std::string&);
|
||||
// Static helpers.
|
||||
static const std::string typeName (const Lexer::Type&);
|
||||
static bool isWhitespace (int);
|
||||
static bool isAlpha (int);
|
||||
static bool isDigit (int);
|
||||
static bool isHexDigit (int);
|
||||
static bool isIdentifierStart (int);
|
||||
static bool isIdentifierNext (int);
|
||||
static bool isSingleCharOperator (int);
|
||||
static bool isDoubleCharOperator (int, int, int);
|
||||
static bool isTripleCharOperator (int, int, int, int);
|
||||
static bool isBoundary (int, int);
|
||||
static bool isPunctuation (int);
|
||||
static void dequote (std::string&);
|
||||
|
||||
private:
|
||||
bool is_date (std::string&);
|
||||
bool is_duration (std::string&);
|
||||
bool is_punct (int) const;
|
||||
bool is_num (int) const;
|
||||
bool is_triple_op (int, int, int) const;
|
||||
bool is_double_op (int, int, int) const;
|
||||
bool is_hex_digit (int) const;
|
||||
int decode_escape (int) const;
|
||||
int hex_to_int (int) const;
|
||||
int hex_to_int (int, int) const;
|
||||
int hex_to_int (int, int, int, int) const;
|
||||
void shift ();
|
||||
// Helpers.
|
||||
bool isEOS () const;
|
||||
int hexToInt (int) const;
|
||||
int hexToInt (int, int) const;
|
||||
int hexToInt (int, int, int, int) const;
|
||||
|
||||
// Classifiers.
|
||||
bool isString (std::string&, Lexer::Type&, int quote);
|
||||
bool isDate (std::string&, Lexer::Type&);
|
||||
bool isDuration (std::string&, Lexer::Type&);
|
||||
bool isUUID (std::string&, Lexer::Type&);
|
||||
bool isNumber (std::string&, Lexer::Type&);
|
||||
bool isHexNumber (std::string&, Lexer::Type&);
|
||||
bool isSeparator (std::string&, Lexer::Type&);
|
||||
bool isList (std::string&, Lexer::Type&);
|
||||
bool isURL (std::string&, Lexer::Type&);
|
||||
bool isPair (std::string&, Lexer::Type&);
|
||||
bool isTag (std::string&, Lexer::Type&);
|
||||
bool isPath (std::string&, Lexer::Type&);
|
||||
bool isSubstitution (std::string&, Lexer::Type&);
|
||||
bool isPattern (std::string&, Lexer::Type&);
|
||||
bool isOperator (std::string&, Lexer::Type&);
|
||||
bool isDOM (std::string&, Lexer::Type&);
|
||||
bool isIdentifier (std::string&, Lexer::Type&);
|
||||
bool isWord (std::string&, Lexer::Type&);
|
||||
|
||||
private:
|
||||
const std::string _input;
|
||||
std::string::size_type _i;
|
||||
std::string::size_type _shift_counter;
|
||||
int _n0;
|
||||
int _n1;
|
||||
int _n2;
|
||||
int _n3;
|
||||
bool _boundary01;
|
||||
bool _boundary12;
|
||||
bool _boundary23;
|
||||
bool _ambiguity;
|
||||
std::string _text;
|
||||
std::size_t _cursor;
|
||||
std::size_t _eos;
|
||||
bool _ambiguity;
|
||||
};
|
||||
|
||||
#endif
|
||||
|
||||
127
src/Nibbler.cpp
127
src/Nibbler.cpp
@@ -27,9 +27,9 @@
|
||||
#include <cmake.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <ctype.h>
|
||||
#include <time.h>
|
||||
#include <inttypes.h>
|
||||
#include <Lexer.h>
|
||||
#include <Nibbler.h>
|
||||
#ifdef NIBBLER_FEATURE_DATE
|
||||
#include <Date.h>
|
||||
@@ -284,7 +284,7 @@ bool Nibbler::getQuoted (
|
||||
bool Nibbler::getDigit (int& result)
|
||||
{
|
||||
if (_cursor < _length &&
|
||||
isdigit (_input[_cursor]))
|
||||
Lexer::isDigit (_input[_cursor]))
|
||||
{
|
||||
result = _input[_cursor++] - '0';
|
||||
return true;
|
||||
@@ -300,12 +300,12 @@ bool Nibbler::getDigit6 (int& result)
|
||||
if (i < _length &&
|
||||
_length - i >= 6)
|
||||
{
|
||||
if (isdigit (_input[i + 0]) &&
|
||||
isdigit (_input[i + 1]) &&
|
||||
isdigit (_input[i + 2]) &&
|
||||
isdigit (_input[i + 3]) &&
|
||||
isdigit (_input[i + 4]) &&
|
||||
isdigit (_input[i + 5]))
|
||||
if (Lexer::isDigit (_input[i + 0]) &&
|
||||
Lexer::isDigit (_input[i + 1]) &&
|
||||
Lexer::isDigit (_input[i + 2]) &&
|
||||
Lexer::isDigit (_input[i + 3]) &&
|
||||
Lexer::isDigit (_input[i + 4]) &&
|
||||
Lexer::isDigit (_input[i + 5]))
|
||||
{
|
||||
result = strtoimax (_input.substr (_cursor, 6).c_str (), NULL, 10);
|
||||
_cursor += 6;
|
||||
@@ -323,10 +323,10 @@ bool Nibbler::getDigit4 (int& result)
|
||||
if (i < _length &&
|
||||
_length - i >= 4)
|
||||
{
|
||||
if (isdigit (_input[i + 0]) &&
|
||||
isdigit (_input[i + 1]) &&
|
||||
isdigit (_input[i + 2]) &&
|
||||
isdigit (_input[i + 3]))
|
||||
if (Lexer::isDigit (_input[i + 0]) &&
|
||||
Lexer::isDigit (_input[i + 1]) &&
|
||||
Lexer::isDigit (_input[i + 2]) &&
|
||||
Lexer::isDigit (_input[i + 3]))
|
||||
{
|
||||
result = strtoimax (_input.substr (_cursor, 4).c_str (), NULL, 10);
|
||||
_cursor += 4;
|
||||
@@ -344,9 +344,9 @@ bool Nibbler::getDigit3 (int& result)
|
||||
if (i < _length &&
|
||||
_length - i >= 3)
|
||||
{
|
||||
if (isdigit (_input[i + 0]) &&
|
||||
isdigit (_input[i + 1]) &&
|
||||
isdigit (_input[i + 2]))
|
||||
if (Lexer::isDigit (_input[i + 0]) &&
|
||||
Lexer::isDigit (_input[i + 1]) &&
|
||||
Lexer::isDigit (_input[i + 2]))
|
||||
{
|
||||
result = strtoimax (_input.substr (_cursor, 3).c_str (), NULL, 10);
|
||||
_cursor += 3;
|
||||
@@ -364,8 +364,8 @@ bool Nibbler::getDigit2 (int& result)
|
||||
if (i < _length &&
|
||||
_length - i >= 2)
|
||||
{
|
||||
if (isdigit (_input[i + 0]) &&
|
||||
isdigit (_input[i + 1]))
|
||||
if (Lexer::isDigit (_input[i + 0]) &&
|
||||
Lexer::isDigit (_input[i + 1]))
|
||||
{
|
||||
result = strtoimax (_input.substr (_cursor, 2).c_str (), NULL, 10);
|
||||
_cursor += 2;
|
||||
@@ -390,7 +390,7 @@ bool Nibbler::getInt (int& result)
|
||||
}
|
||||
|
||||
// TODO Potential for use of find_first_not_of
|
||||
while (i < _length && isdigit (_input[i]))
|
||||
while (i < _length && Lexer::isDigit (_input[i]))
|
||||
++i;
|
||||
|
||||
if (i > _cursor)
|
||||
@@ -408,7 +408,7 @@ bool Nibbler::getUnsignedInt (int& result)
|
||||
{
|
||||
std::string::size_type i = _cursor;
|
||||
// TODO Potential for use of find_first_not_of
|
||||
while (i < _length && isdigit (_input[i]))
|
||||
while (i < _length && Lexer::isDigit (_input[i]))
|
||||
++i;
|
||||
|
||||
if (i > _cursor)
|
||||
@@ -446,11 +446,11 @@ bool Nibbler::getNumber (std::string& result)
|
||||
++i;
|
||||
|
||||
// digit+
|
||||
if (i < _length && isdigit (_input[i]))
|
||||
if (i < _length && Lexer::isDigit (_input[i]))
|
||||
{
|
||||
++i;
|
||||
|
||||
while (i < _length && isdigit (_input[i]))
|
||||
while (i < _length && Lexer::isDigit (_input[i]))
|
||||
++i;
|
||||
|
||||
// ( . digit+ )?
|
||||
@@ -458,7 +458,7 @@ bool Nibbler::getNumber (std::string& result)
|
||||
{
|
||||
++i;
|
||||
|
||||
while (i < _length && isdigit (_input[i]))
|
||||
while (i < _length && Lexer::isDigit (_input[i]))
|
||||
++i;
|
||||
}
|
||||
|
||||
@@ -470,11 +470,11 @@ bool Nibbler::getNumber (std::string& result)
|
||||
if (i < _length && (_input[i] == '+' || _input[i] == '-'))
|
||||
++i;
|
||||
|
||||
if (i < _length && isdigit (_input[i]))
|
||||
if (i < _length && Lexer::isDigit (_input[i]))
|
||||
{
|
||||
++i;
|
||||
|
||||
while (i < _length && isdigit (_input[i]))
|
||||
while (i < _length && Lexer::isDigit (_input[i]))
|
||||
++i;
|
||||
|
||||
result = _input.substr (_cursor, i - _cursor);
|
||||
@@ -528,11 +528,11 @@ bool Nibbler::getUnsignedNumber (double& result)
|
||||
std::string::size_type i = _cursor;
|
||||
|
||||
// digit+
|
||||
if (i < _length && isdigit (_input[i]))
|
||||
if (i < _length && Lexer::isDigit (_input[i]))
|
||||
{
|
||||
++i;
|
||||
|
||||
while (i < _length && isdigit (_input[i]))
|
||||
while (i < _length && Lexer::isDigit (_input[i]))
|
||||
++i;
|
||||
|
||||
// ( . digit+ )?
|
||||
@@ -540,7 +540,7 @@ bool Nibbler::getUnsignedNumber (double& result)
|
||||
{
|
||||
++i;
|
||||
|
||||
while (i < _length && isdigit (_input[i]))
|
||||
while (i < _length && Lexer::isDigit (_input[i]))
|
||||
++i;
|
||||
}
|
||||
|
||||
@@ -552,11 +552,11 @@ bool Nibbler::getUnsignedNumber (double& result)
|
||||
if (i < _length && (_input[i] == '+' || _input[i] == '-'))
|
||||
++i;
|
||||
|
||||
if (i < _length && isdigit (_input[i]))
|
||||
if (i < _length && Lexer::isDigit (_input[i]))
|
||||
{
|
||||
++i;
|
||||
|
||||
while (i < _length && isdigit (_input[i]))
|
||||
while (i < _length && Lexer::isDigit (_input[i]))
|
||||
++i;
|
||||
|
||||
result = strtof (_input.substr (_cursor, i - _cursor).c_str (), NULL);
|
||||
@@ -710,21 +710,21 @@ bool Nibbler::getDateISO (time_t& t)
|
||||
if (i < _length &&
|
||||
_length - i >= 16)
|
||||
{
|
||||
if (isdigit (_input[i + 0]) &&
|
||||
isdigit (_input[i + 1]) &&
|
||||
isdigit (_input[i + 2]) &&
|
||||
isdigit (_input[i + 3]) &&
|
||||
isdigit (_input[i + 4]) &&
|
||||
isdigit (_input[i + 5]) &&
|
||||
isdigit (_input[i + 6]) &&
|
||||
isdigit (_input[i + 7]) &&
|
||||
if (Lexer::isDigit (_input[i + 0]) &&
|
||||
Lexer::isDigit (_input[i + 1]) &&
|
||||
Lexer::isDigit (_input[i + 2]) &&
|
||||
Lexer::isDigit (_input[i + 3]) &&
|
||||
Lexer::isDigit (_input[i + 4]) &&
|
||||
Lexer::isDigit (_input[i + 5]) &&
|
||||
Lexer::isDigit (_input[i + 6]) &&
|
||||
Lexer::isDigit (_input[i + 7]) &&
|
||||
_input[i + 8] == 'T' &&
|
||||
isdigit (_input[i + 9]) &&
|
||||
isdigit (_input[i + 10]) &&
|
||||
isdigit (_input[i + 11]) &&
|
||||
isdigit (_input[i + 12]) &&
|
||||
isdigit (_input[i + 13]) &&
|
||||
isdigit (_input[i + 14]) &&
|
||||
Lexer::isDigit (_input[i + 9]) &&
|
||||
Lexer::isDigit (_input[i + 10]) &&
|
||||
Lexer::isDigit (_input[i + 11]) &&
|
||||
Lexer::isDigit (_input[i + 12]) &&
|
||||
Lexer::isDigit (_input[i + 13]) &&
|
||||
Lexer::isDigit (_input[i + 14]) &&
|
||||
_input[i + 15] == 'Z')
|
||||
{
|
||||
_cursor += 16;
|
||||
@@ -790,7 +790,7 @@ bool Nibbler::parseDigits(std::string::size_type& i,
|
||||
// Check that 'f' of them are digits
|
||||
unsigned int g;
|
||||
for (g = 0; g < f; g++)
|
||||
if (! isdigit (_input[i + g]))
|
||||
if (! Lexer::isDigit (_input[i + g]))
|
||||
break;
|
||||
// Parse the integer when it is the case
|
||||
if (g == f)
|
||||
@@ -881,9 +881,9 @@ bool Nibbler::getDate (const std::string& format, time_t& t)
|
||||
case 'a':
|
||||
case 'A':
|
||||
if (i + 3 <= _length &&
|
||||
! isdigit (_input[i + 0]) &&
|
||||
! isdigit (_input[i + 1]) &&
|
||||
! isdigit (_input[i + 2]))
|
||||
! Lexer::isDigit (_input[i + 0]) &&
|
||||
! Lexer::isDigit (_input[i + 1]) &&
|
||||
! Lexer::isDigit (_input[i + 2]))
|
||||
{
|
||||
wday = Date::dayOfWeek (_input.substr (i, 3).c_str ());
|
||||
i += (format[f] == 'a') ? 3 : Date::dayName (wday).size ();
|
||||
@@ -895,9 +895,9 @@ bool Nibbler::getDate (const std::string& format, time_t& t)
|
||||
case 'b':
|
||||
case 'B':
|
||||
if (i + 3 <= _length &&
|
||||
! isdigit (_input[i + 0]) &&
|
||||
! isdigit (_input[i + 1]) &&
|
||||
! isdigit (_input[i + 2]))
|
||||
! Lexer::isDigit (_input[i + 0]) &&
|
||||
! Lexer::isDigit (_input[i + 1]) &&
|
||||
! Lexer::isDigit (_input[i + 2]))
|
||||
{
|
||||
if (month != -1)
|
||||
return false;
|
||||
@@ -1003,14 +1003,14 @@ bool Nibbler::getName (std::string& result)
|
||||
|
||||
if (i < _length)
|
||||
{
|
||||
if (! isdigit (_input[i]) &&
|
||||
if (! Lexer::isDigit (_input[i]) &&
|
||||
! ispunct (_input[i]) &&
|
||||
! Lexer::is_ws (_input[i]))
|
||||
! Lexer::isWhitespace (_input[i]))
|
||||
{
|
||||
++i;
|
||||
while (i < _length &&
|
||||
(_input[i] == '_' || ! ispunct (_input[i])) &&
|
||||
! Lexer::is_ws (_input[i]))
|
||||
! Lexer::isWhitespace (_input[i]))
|
||||
{
|
||||
++i;
|
||||
}
|
||||
@@ -1035,9 +1035,9 @@ bool Nibbler::getWord (std::string& result)
|
||||
|
||||
if (i < _length)
|
||||
{
|
||||
while (!isdigit (_input[i]) &&
|
||||
!isPunctuation (_input[i]) &&
|
||||
!Lexer::is_ws (_input[i]))
|
||||
while (!Lexer::isDigit (_input[i]) &&
|
||||
!Lexer::isPunctuation (_input[i]) &&
|
||||
!Lexer::isWhitespace (_input[i]))
|
||||
{
|
||||
++i;
|
||||
}
|
||||
@@ -1227,21 +1227,6 @@ bool Nibbler::depleted ()
|
||||
return false;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
// Override of ispunct, that considers #, $, _ and @ not to be punctuation.
|
||||
//
|
||||
// ispunct: ! " # $ % & ' ( ) * + , - . / : ; < = > ? @ [ \ ] ^ _ ` { | } ~
|
||||
// Punctuation: ! " % & ' ( ) * + , - . / : ; < = > ? [ \ ] ^ _ ` { | } ~
|
||||
// delta: # $ @
|
||||
//
|
||||
bool Nibbler::isPunctuation (char c)
|
||||
{
|
||||
if (c == '@' || c == '#' || c == '$' || c == '_')
|
||||
return false;
|
||||
|
||||
return ispunct (c);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
std::string Nibbler::dump ()
|
||||
{
|
||||
|
||||
@@ -110,7 +110,6 @@ public:
|
||||
|
||||
bool depleted ();
|
||||
|
||||
static bool isPunctuation (char);
|
||||
std::string dump ();
|
||||
|
||||
private:
|
||||
|
||||
37
src/TDB2.cpp
37
src/TDB2.cpp
@@ -102,7 +102,7 @@ bool TF2::get (int id, Task& task)
|
||||
// pending.data file, the task in question cannot appear earlier than line
|
||||
// (id - 1) in the file. It can, however, appear significantly later because
|
||||
// it is not known how recent a GC operation was run.
|
||||
for (int i = id - 1; i < _tasks.size (); ++i)
|
||||
for (unsigned int i = id - 1; i < _tasks.size (); ++i)
|
||||
{
|
||||
if (_tasks[i].id == id)
|
||||
{
|
||||
@@ -316,9 +316,15 @@ void TF2::load_tasks ()
|
||||
++line_number;
|
||||
Task task (*i);
|
||||
|
||||
// Some tasks gets an ID.
|
||||
// Some tasks get an ID.
|
||||
if (_has_ids)
|
||||
task.id = context.tdb2.next_id ();
|
||||
{
|
||||
Task::status status = task.getStatus ();
|
||||
// Completed / deleted tasks in pending.data get an ID if GC is off.
|
||||
if (!context.run_gc ||
|
||||
(status != Task::completed && status != Task::deleted))
|
||||
task.id = context.tdb2.next_id ();
|
||||
}
|
||||
|
||||
_tasks.push_back (task);
|
||||
|
||||
@@ -462,9 +468,13 @@ void TF2::dependency_scan ()
|
||||
{
|
||||
if (right->get ("uuid") == *d)
|
||||
{
|
||||
Task::status status = right->getStatus ();
|
||||
if (status != Task::completed &&
|
||||
status != Task::deleted)
|
||||
// GC hasn't run yet, check both tasks for their current status
|
||||
Task::status lstatus = left->getStatus ();
|
||||
Task::status rstatus = right->getStatus ();
|
||||
if (lstatus != Task::completed &&
|
||||
lstatus != Task::deleted &&
|
||||
rstatus != Task::completed &&
|
||||
rstatus != Task::deleted)
|
||||
{
|
||||
left->is_blocked = true;
|
||||
right->is_blocking = true;
|
||||
@@ -559,7 +569,9 @@ void TDB2::set_location (const std::string& location)
|
||||
void TDB2::add (Task& task, bool add_to_backlog /* = true */)
|
||||
{
|
||||
// Ensure the task is consistent, and provide defaults if necessary.
|
||||
task.validate ();
|
||||
// bool argument to validate() is "applyDefault". Pass add_to_backlog through
|
||||
// in order to not apply defaults to synchronized tasks.
|
||||
task.validate (add_to_backlog);
|
||||
std::string uuid = task.get ("uuid");
|
||||
|
||||
// If the tasks are loaded, then verify that this uuid is not already in
|
||||
@@ -578,7 +590,7 @@ void TDB2::add (Task& task, bool add_to_backlog /* = true */)
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
void TDB2::modify (Task& task, bool add_to_backlog /* = true */)
|
||||
{
|
||||
// Ensure the task is consistent, and provide defaults if necessary.
|
||||
// Ensure the task is consistent.
|
||||
task.validate (false);
|
||||
std::string uuid = task.get ("uuid");
|
||||
|
||||
@@ -598,7 +610,7 @@ void TDB2::update (
|
||||
const std::string& uuid,
|
||||
Task& task,
|
||||
const bool add_to_backlog,
|
||||
const bool addition)
|
||||
const bool addition /* = false */)
|
||||
{
|
||||
// Validate to add metadata.
|
||||
task.validate (false);
|
||||
@@ -607,6 +619,13 @@ void TDB2::update (
|
||||
Task original;
|
||||
if (not addition && get (task.get ("uuid"), original))
|
||||
{
|
||||
if (add_to_backlog)
|
||||
{
|
||||
// All locally modified tasks are timestamped, implicitly overwriting any
|
||||
// changes the user or hooks tried to apply to the "modified" attribute.
|
||||
task.setAsNow ("modified");
|
||||
}
|
||||
|
||||
// Update the task, wherever it is.
|
||||
if (!pending.modify_task (task))
|
||||
completed.modify_task (task);
|
||||
|
||||
61
src/Task.cpp
61
src/Task.cpp
@@ -65,14 +65,12 @@ static const float epsilon = 0.000001;
|
||||
#endif
|
||||
|
||||
std::string Task::defaultProject = "";
|
||||
std::string Task::defaultPriority = "";
|
||||
std::string Task::defaultDue = "";
|
||||
bool Task::searchCaseSensitive = true;
|
||||
bool Task::regex = false;
|
||||
std::map <std::string, std::string> Task::attributes;
|
||||
|
||||
std::map <std::string, float> Task::coefficients;
|
||||
float Task::urgencyPriorityCoefficient = 0.0;
|
||||
float Task::urgencyProjectCoefficient = 0.0;
|
||||
float Task::urgencyActiveCoefficient = 0.0;
|
||||
float Task::urgencyScheduledCoefficient = 0.0;
|
||||
@@ -87,6 +85,8 @@ float Task::urgencyBlockingCoefficient = 0.0;
|
||||
float Task::urgencyAgeCoefficient = 0.0;
|
||||
float Task::urgencyAgeMax = 0.0;
|
||||
|
||||
std::map <std::string, std::vector <std::string>> Task::customOrder;
|
||||
|
||||
static const std::string dummy ("");
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
@@ -1384,7 +1384,7 @@ void Task::validate (bool applyDefault /* = true */)
|
||||
if (!has ("modified") || get ("modified") == "")
|
||||
setAsNow ("modified");
|
||||
|
||||
if (applyDefault)
|
||||
if (applyDefault && (! has ("parent") || get ("parent") == ""))
|
||||
{
|
||||
// Override with default.project, if not specified.
|
||||
if (Task::defaultProject != "" &&
|
||||
@@ -1394,14 +1394,6 @@ void Task::validate (bool applyDefault /* = true */)
|
||||
set ("project", Task::defaultProject);
|
||||
}
|
||||
|
||||
// Override with default.priority, if not specified.
|
||||
if (Task::defaultPriority != "" &&
|
||||
! has ("priority"))
|
||||
{
|
||||
if (context.columns["priority"]->validate (Task::defaultPriority))
|
||||
set ("priority", Task::defaultPriority);
|
||||
}
|
||||
|
||||
// Override with default.due, if not specified.
|
||||
if (Task::defaultDue != "" &&
|
||||
! has ("due"))
|
||||
@@ -1487,17 +1479,6 @@ void Task::validate (bool applyDefault /* = true */)
|
||||
throw std::string (format (STRING_TASK_VALID_RECUR, value));
|
||||
}
|
||||
}
|
||||
|
||||
// Priorities must be valid.
|
||||
if (has ("priority"))
|
||||
{
|
||||
std::string priority = get ("priority");
|
||||
if (priority != "H" &&
|
||||
priority != "M" &&
|
||||
priority != "L" &&
|
||||
priority != "")
|
||||
throw format (STRING_TASK_VALID_PRIORITY, priority);
|
||||
}
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
@@ -1655,7 +1636,6 @@ float Task::urgency_c () const
|
||||
{
|
||||
float value = 0.0;
|
||||
#ifdef PRODUCT_TASKWARRIOR
|
||||
value += fabsf (Task::urgencyPriorityCoefficient) > epsilon ? (urgency_priority () * Task::urgencyPriorityCoefficient) : 0.0;
|
||||
value += fabsf (Task::urgencyProjectCoefficient) > epsilon ? (urgency_project () * Task::urgencyProjectCoefficient) : 0.0;
|
||||
value += fabsf (Task::urgencyActiveCoefficient) > epsilon ? (urgency_active () * Task::urgencyActiveCoefficient) : 0.0;
|
||||
value += fabsf (Task::urgencyScheduledCoefficient) > epsilon ? (urgency_scheduled () * Task::urgencyScheduledCoefficient) : 0.0;
|
||||
@@ -1697,6 +1677,16 @@ float Task::urgency_c () const
|
||||
if (hasTag (tag))
|
||||
value += var->second;
|
||||
}
|
||||
|
||||
// urgency.user.keyword.<keyword>.coefficient
|
||||
if (var->first.substr (13, 8) == "keyword." &&
|
||||
(end = var->first.find (".coefficient")) != std::string::npos)
|
||||
{
|
||||
std::string keyword = var->first.substr (21, end - 21);
|
||||
|
||||
if (get ("description").find (keyword) != std::string::npos)
|
||||
value += var->second;
|
||||
}
|
||||
}
|
||||
else if (var->first.substr (0, 12) == "urgency.uda.")
|
||||
{
|
||||
@@ -1742,18 +1732,6 @@ float Task::urgency ()
|
||||
return urgency_value;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
float Task::urgency_priority () const
|
||||
{
|
||||
const std::string& value = get_ref ("priority");
|
||||
|
||||
if (value == "H") return 1.0;
|
||||
else if (value == "M") return 0.65;
|
||||
else if (value == "L") return 0.3;
|
||||
|
||||
return 0.0;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
float Task::urgency_inherit () const
|
||||
{
|
||||
@@ -1775,7 +1753,6 @@ float Task::urgency_inherit () const
|
||||
v += it->urgency_annotations ();
|
||||
v += it->urgency_due ();
|
||||
v += it->urgency_next ();
|
||||
v += it->urgency_priority ();
|
||||
v += it->urgency_scheduled ();
|
||||
v += it->urgency_waiting ();
|
||||
|
||||
@@ -1956,17 +1933,13 @@ void Task::modify (modType type, bool text_required /* = false */)
|
||||
}
|
||||
else
|
||||
{
|
||||
// Some columns are not modifiable.
|
||||
if (name == "uuid" ||
|
||||
name == "id" ||
|
||||
name == "mask" ||
|
||||
name == "imask" ||
|
||||
name == "parent")
|
||||
throw format (STRING_INVALID_MOD, name, value);
|
||||
|
||||
// Get the column info.
|
||||
Column* column = context.columns[name];
|
||||
|
||||
// Some columns are not modifiable.
|
||||
if (! column->modifiable ())
|
||||
throw format (STRING_INVALID_MOD, name, value);
|
||||
|
||||
// Dependencies are specified as IDs.
|
||||
if (name == "depends")
|
||||
{
|
||||
|
||||
@@ -37,13 +37,12 @@ class Task : public std::map <std::string, std::string>
|
||||
{
|
||||
public:
|
||||
static std::string defaultProject;
|
||||
static std::string defaultPriority;
|
||||
static std::string defaultDue;
|
||||
static bool searchCaseSensitive;
|
||||
static bool regex;
|
||||
static std::map <std::string, std::string> attributes; // name -> type
|
||||
static std::map <std::string, float> coefficients;
|
||||
static float urgencyPriorityCoefficient;
|
||||
static std::map <std::string, std::vector <std::string>> customOrder;
|
||||
static float urgencyProjectCoefficient;
|
||||
static float urgencyActiveCoefficient;
|
||||
static float urgencyScheduledCoefficient;
|
||||
@@ -164,7 +163,6 @@ private:
|
||||
const std::string decode (const std::string&) const;
|
||||
|
||||
public:
|
||||
float urgency_priority () const;
|
||||
float urgency_project () const;
|
||||
float urgency_active () const;
|
||||
float urgency_scheduled () const;
|
||||
|
||||
120
src/Variant.cpp
120
src/Variant.cpp
@@ -26,6 +26,7 @@
|
||||
|
||||
#include <cmake.h>
|
||||
#include <sstream>
|
||||
#include <algorithm>
|
||||
#include <stdio.h>
|
||||
#include <math.h>
|
||||
#include <stdlib.h>
|
||||
@@ -135,7 +136,7 @@ Variant::Variant (const char* value)
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
Variant::Variant (const time_t value, const enum type new_type /*=type_date*/)
|
||||
Variant::Variant (const time_t value, const enum type new_type)
|
||||
: _type (new_type)
|
||||
, _bool (false)
|
||||
, _integer (0)
|
||||
@@ -166,7 +167,7 @@ void Variant::source (const std::string& input)
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
std::string Variant::source () const
|
||||
const std::string& Variant::source () const
|
||||
{
|
||||
return _source;
|
||||
}
|
||||
@@ -314,19 +315,25 @@ bool Variant::operator< (const Variant& other) const
|
||||
return left._string < right._string;
|
||||
|
||||
case type_string:
|
||||
if (left.source () == "priority" || right.source () == "priority")
|
||||
{
|
||||
if (left._string != "H" && right._string == "H") return true;
|
||||
else if (left._string == "L" && right._string == "M") return true;
|
||||
else if (left._string == "" && right._string != "") return true;
|
||||
else return false;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (left.trivial () || right.trivial ())
|
||||
if (left._string == right._string)
|
||||
return false;
|
||||
|
||||
return left._string < right._string;
|
||||
auto order = Task::customOrder.find (left.source ());
|
||||
if (order != Task::customOrder.end ())
|
||||
{
|
||||
// Guaranteed to be found, because of ColUDA::validate ().
|
||||
auto posLeft = std::find (order->second.begin (), order->second.end (), left._string);
|
||||
auto posRight = std::find (order->second.begin (), order->second.end (), right._string);
|
||||
return posLeft < posRight;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (left.trivial () || right.trivial ())
|
||||
return false;
|
||||
|
||||
return left._string < right._string;
|
||||
}
|
||||
}
|
||||
|
||||
case type_date:
|
||||
@@ -459,20 +466,25 @@ bool Variant::operator<= (const Variant& other) const
|
||||
return left._string <= right._string;
|
||||
|
||||
case type_string:
|
||||
if (left.source () == "priority" || right.source () == "priority")
|
||||
{
|
||||
if (left._string == right._string ) return true;
|
||||
else if ( right._string == "H") return true;
|
||||
else if (left._string == "L" && right._string == "M") return true;
|
||||
else if (left._string == "" ) return true;
|
||||
else return false;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (left.trivial () || right.trivial ())
|
||||
return false;
|
||||
if (left._string == right._string)
|
||||
return true;
|
||||
|
||||
return left._string <= right._string;
|
||||
auto order = Task::customOrder.find (left.source ());
|
||||
if (order != Task::customOrder.end ())
|
||||
{
|
||||
// Guaranteed to be found, because of ColUDA::validate ().
|
||||
auto posLeft = std::find (order->second.begin (), order->second.end (), left._string);
|
||||
auto posRight = std::find (order->second.begin (), order->second.end (), right._string);
|
||||
return posLeft <= posRight;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (left.trivial () || right.trivial ())
|
||||
return false;
|
||||
|
||||
return left._string <= right._string;
|
||||
}
|
||||
}
|
||||
|
||||
case type_date:
|
||||
@@ -605,20 +617,27 @@ bool Variant::operator> (const Variant& other) const
|
||||
return left._string > right._string;
|
||||
|
||||
case type_string:
|
||||
if (left.source () == "priority" || right.source () == "priority")
|
||||
{
|
||||
if (left._string == "H" && right._string != "H") return true;
|
||||
else if (left._string == "M" && right._string == "L") return true;
|
||||
else if (left._string != "" && right._string == "") return true;
|
||||
else return false;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (left.trivial () || right.trivial ())
|
||||
if (left._string == right._string)
|
||||
return false;
|
||||
|
||||
return left._string> right._string;
|
||||
auto order = Task::customOrder.find (left.source ());
|
||||
if (order != Task::customOrder.end ())
|
||||
{
|
||||
// Guaranteed to be found, because of ColUDA::validate ().
|
||||
auto posLeft = std::find (order->second.begin (), order->second.end (), left._string);
|
||||
auto posRight = std::find (order->second.begin (), order->second.end (), right._string);
|
||||
return posLeft > posRight;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (left.trivial () || right.trivial ())
|
||||
return false;
|
||||
|
||||
return left._string > right._string;
|
||||
}
|
||||
}
|
||||
|
||||
case type_date:
|
||||
if (left.trivial () || right.trivial ())
|
||||
return false;
|
||||
@@ -749,20 +768,25 @@ bool Variant::operator>= (const Variant& other) const
|
||||
return left._string >= right._string;
|
||||
|
||||
case type_string:
|
||||
if (left.source () == "priority" || right.source () == "priority")
|
||||
{
|
||||
if (left._string == right._string ) return true;
|
||||
else if (left._string == "H" ) return true;
|
||||
else if (left._string == "M" && right._string == "L") return true;
|
||||
else if ( right._string == "" ) return true;
|
||||
else return false;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (left.trivial () || right.trivial ())
|
||||
return false;
|
||||
if (left._string == right._string)
|
||||
return true;
|
||||
|
||||
return left._string >= right._string;
|
||||
auto order = Task::customOrder.find (left.source ());
|
||||
if (order != Task::customOrder.end ())
|
||||
{
|
||||
// Guaranteed to be found, because of ColUDA::validate ().
|
||||
auto posLeft = std::find (order->second.begin (), order->second.end (), left._string);
|
||||
auto posRight = std::find (order->second.begin (), order->second.end (), right._string);
|
||||
return posLeft >= posRight;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (left.trivial () || right.trivial ())
|
||||
return false;
|
||||
|
||||
return left._string >= right._string;
|
||||
}
|
||||
}
|
||||
|
||||
case type_date:
|
||||
@@ -1964,6 +1988,8 @@ Variant::operator std::string () const
|
||||
case type_unknown:
|
||||
throw std::string (STRING_VARIANT_RENDER_UNK);
|
||||
}
|
||||
|
||||
return "";
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
@@ -2172,7 +2198,7 @@ double Variant::get_real () const
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
std::string Variant::get_string () const
|
||||
const std::string& Variant::get_string () const
|
||||
{
|
||||
return _string;
|
||||
}
|
||||
|
||||
@@ -27,6 +27,7 @@
|
||||
#ifndef INCLUDED_VARIANT
|
||||
#define INCLUDED_VARIANT
|
||||
|
||||
#include <map>
|
||||
#include <string>
|
||||
#include <time.h>
|
||||
#include <Task.h>
|
||||
@@ -49,11 +50,11 @@ public:
|
||||
Variant (const double);
|
||||
Variant (const std::string&);
|
||||
Variant (const char*);
|
||||
Variant (const time_t, const enum type new_type = type_date);
|
||||
Variant (const time_t, const enum type);
|
||||
~Variant ();
|
||||
|
||||
void source (const std::string&);
|
||||
std::string source () const;
|
||||
const std::string& source () const;
|
||||
|
||||
Variant& operator= (const Variant&);
|
||||
|
||||
@@ -99,12 +100,12 @@ public:
|
||||
int type ();
|
||||
bool trivial () const;
|
||||
|
||||
bool get_bool () const;
|
||||
int get_integer () const;
|
||||
double get_real () const;
|
||||
std::string get_string () const;
|
||||
time_t get_date () const;
|
||||
time_t get_duration () const;
|
||||
bool get_bool () const;
|
||||
int get_integer () const;
|
||||
double get_real () const;
|
||||
const std::string& get_string () const;
|
||||
time_t get_date () const;
|
||||
time_t get_duration () const;
|
||||
|
||||
private:
|
||||
enum type _type;
|
||||
|
||||
@@ -143,6 +143,11 @@ std::string ViewTask::render (std::vector <Task>& data, std::vector <int>& seque
|
||||
|
||||
if (min > global_min) global_min = min;
|
||||
if (ideal > global_ideal) global_ideal = ideal;
|
||||
|
||||
// If a fixed-width column was just measured, there is no point repeating
|
||||
// the measurement for all tasks.
|
||||
if (_columns[i]->is_fixed_width ())
|
||||
break;
|
||||
}
|
||||
|
||||
if (print_empty_columns || global_min != 0)
|
||||
@@ -237,7 +242,7 @@ std::string ViewTask::render (std::vector <Task>& data, std::vector <int>& seque
|
||||
|
||||
// Compose column headers.
|
||||
unsigned int max_lines = 0;
|
||||
std::vector <std::vector <std::string> > headers;
|
||||
std::vector <std::vector <std::string>> headers;
|
||||
for (unsigned int c = 0; c < _columns.size (); ++c)
|
||||
{
|
||||
headers.push_back (std::vector <std::string> ());
|
||||
@@ -290,7 +295,7 @@ std::string ViewTask::render (std::vector <Task>& data, std::vector <int>& seque
|
||||
|
||||
// Compose, render columns, in sequence.
|
||||
_rows = 0;
|
||||
std::vector <std::vector <std::string> > cells;
|
||||
std::vector <std::vector <std::string>> cells;
|
||||
std::vector <int>::iterator s;
|
||||
for (unsigned int s = 0; s < sequence.size (); ++s)
|
||||
{
|
||||
|
||||
@@ -132,6 +132,11 @@ std::string ViewText::render ()
|
||||
|
||||
if (min > global_min) global_min = min;
|
||||
if (ideal > global_ideal) global_ideal = ideal;
|
||||
|
||||
// If a fixed-width column was just measured, there is no point repeating
|
||||
// the measurement for all tasks.
|
||||
if (_columns[col]->is_fixed_width ())
|
||||
break;
|
||||
}
|
||||
|
||||
minimal.push_back (global_min);
|
||||
@@ -181,7 +186,7 @@ std::string ViewText::render ()
|
||||
|
||||
// Compose column headers.
|
||||
unsigned int max_lines = 0;
|
||||
std::vector <std::vector <std::string> > headers;
|
||||
std::vector <std::vector <std::string>> headers;
|
||||
for (unsigned int c = 0; c < _columns.size (); ++c)
|
||||
{
|
||||
headers.push_back (std::vector <std::string> ());
|
||||
@@ -233,7 +238,7 @@ std::string ViewText::render ()
|
||||
|
||||
// Compose, render columns, in sequence.
|
||||
_rows = 0;
|
||||
std::vector <std::vector <std::string> > cells;
|
||||
std::vector <std::vector <std::string>> cells;
|
||||
for (unsigned int row = 0; row < _data.size (); ++row)
|
||||
{
|
||||
max_lines = 0;
|
||||
|
||||
@@ -68,24 +68,24 @@ public:
|
||||
std::string render ();
|
||||
|
||||
private:
|
||||
std::vector <std::vector <std::string> > _data;
|
||||
std::vector <std::vector <Color> > _color;
|
||||
std::vector <Column*> _columns;
|
||||
int _width;
|
||||
int _left_margin;
|
||||
Color _header;
|
||||
Color _odd;
|
||||
Color _even;
|
||||
int _intra_padding;
|
||||
Color _intra_odd;
|
||||
Color _intra_even;
|
||||
int _extra_padding;
|
||||
Color _extra_odd;
|
||||
Color _extra_even;
|
||||
int _truncate_lines;
|
||||
int _truncate_rows;
|
||||
int _lines;
|
||||
int _rows;
|
||||
std::vector <std::vector <std::string>> _data;
|
||||
std::vector <std::vector <Color>> _color;
|
||||
std::vector <Column*> _columns;
|
||||
int _width;
|
||||
int _left_margin;
|
||||
Color _header;
|
||||
Color _odd;
|
||||
Color _even;
|
||||
int _intra_padding;
|
||||
Color _intra_odd;
|
||||
Color _intra_even;
|
||||
int _extra_padding;
|
||||
Color _extra_odd;
|
||||
Color _extra_even;
|
||||
int _truncate_lines;
|
||||
int _truncate_rows;
|
||||
int _lines;
|
||||
int _rows;
|
||||
};
|
||||
|
||||
#endif
|
||||
|
||||
@@ -135,7 +135,6 @@ int main (int argc, const char** argv)
|
||||
cli.entity ("attribute", "mask");
|
||||
cli.entity ("attribute", "modified");
|
||||
cli.entity ("attribute", "parent");
|
||||
cli.entity ("attribute", "priority");
|
||||
cli.entity ("attribute", "project");
|
||||
cli.entity ("attribute", "recur");
|
||||
cli.entity ("attribute", "scheduled");
|
||||
|
||||
@@ -17,7 +17,6 @@ set (columns_SRCS Column.cpp Column.h
|
||||
ColMask.cpp ColMask.h
|
||||
ColModified.cpp ColModified.h
|
||||
ColParent.cpp ColParent.h
|
||||
ColPriority.cpp ColPriority.h
|
||||
ColProject.cpp ColProject.h
|
||||
ColRecur.cpp ColRecur.h
|
||||
ColScheduled.cpp ColScheduled.h
|
||||
|
||||
@@ -83,8 +83,15 @@ void ColumnDepends::measure (Task& task, unsigned int& minimum, unsigned int& ma
|
||||
std::vector <Task> blocking;
|
||||
dependencyGetBlocking (task, blocking);
|
||||
|
||||
if (_style == "indicator") minimum = maximum = utf8_width (context.config.get ("dependency.indicator"));
|
||||
else if (_style == "count") minimum = maximum = 2 + format ((int) blocking.size ()).length ();
|
||||
if (_style == "indicator")
|
||||
{
|
||||
minimum = maximum = utf8_width (context.config.get ("dependency.indicator"));
|
||||
_fixed_width = true;
|
||||
}
|
||||
else if (_style == "count")
|
||||
{
|
||||
minimum = maximum = 2 + format ((int) blocking.size ()).length ();
|
||||
}
|
||||
else if (_style == "default" ||
|
||||
_style == "list")
|
||||
{
|
||||
|
||||
@@ -1,141 +0,0 @@
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Copyright 2006 - 2015, Paul Beckingham, Federico Hernandez.
|
||||
//
|
||||
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
// of this software and associated documentation files (the "Software"), to deal
|
||||
// in the Software without restriction, including without limitation the rights
|
||||
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
// copies of the Software, and to permit persons to whom the Software is
|
||||
// furnished to do so, subject to the following conditions:
|
||||
//
|
||||
// The above copyright notice and this permission notice shall be included
|
||||
// in all copies or substantial portions of the Software.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
|
||||
// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
|
||||
// THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
// SOFTWARE.
|
||||
//
|
||||
// http://www.opensource.org/licenses/mit-license.php
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#include <cmake.h>
|
||||
#include <Context.h>
|
||||
#include <ColPriority.h>
|
||||
#include <text.h>
|
||||
#include <i18n.h>
|
||||
|
||||
extern Context context;
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
ColumnPriority::ColumnPriority ()
|
||||
{
|
||||
_name = "priority";
|
||||
_type = "string";
|
||||
_style = "short";
|
||||
_label = STRING_COLUMN_LABEL_PRI;
|
||||
|
||||
_styles.push_back ("short");
|
||||
_styles.push_back ("long");
|
||||
|
||||
_examples.push_back ("H");
|
||||
_examples.push_back ("High");
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
ColumnPriority::~ColumnPriority ()
|
||||
{
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
// Allow lower case, but implicitly convert.
|
||||
bool ColumnPriority::validate (std::string& value)
|
||||
{
|
||||
if (value == "h") { value = "H"; return true; }
|
||||
else if (value == "m") { value = "M"; return true; }
|
||||
else if (value == "l") { value = "L"; return true; }
|
||||
|
||||
return value == "H" || value == "M" || value == "L" || value == "";
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
// Overriden so that style <----> label are linked.
|
||||
// Note that you can not determine which gets called first.
|
||||
void ColumnPriority::setStyle (const std::string& value)
|
||||
{
|
||||
_style = value;
|
||||
|
||||
if (_style == "long" && _label == STRING_COLUMN_LABEL_PRI)
|
||||
_label = STRING_COLUMN_LABEL_PRIORITY;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
// Set the minimum and maximum widths for the value.
|
||||
void ColumnPriority::measure (Task& task, unsigned int& minimum, unsigned int& maximum)
|
||||
{
|
||||
minimum = maximum = 0;
|
||||
if (task.has (_name))
|
||||
{
|
||||
std::string priority = task.get (_name);
|
||||
|
||||
if (priority == "")
|
||||
minimum = maximum = 0;
|
||||
else
|
||||
minimum = maximum = 1;
|
||||
|
||||
if (_style == "long")
|
||||
{
|
||||
if (priority == "H") minimum = maximum = 4;
|
||||
else if (priority == "M") minimum = maximum = 6;
|
||||
else if (priority == "L") minimum = maximum = 3;
|
||||
}
|
||||
else if (_style != "default" &&
|
||||
_style != "short")
|
||||
throw format (STRING_COLUMN_BAD_FORMAT, "priority", _style);
|
||||
}
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
void ColumnPriority::render (
|
||||
std::vector <std::string>& lines,
|
||||
Task& task,
|
||||
int width,
|
||||
Color& color)
|
||||
{
|
||||
if (task.has (_name))
|
||||
{
|
||||
std::string priority = task.get (_name);
|
||||
if (_style == "long")
|
||||
{
|
||||
if (priority == "H") priority = "High";
|
||||
else if (priority == "M") priority = "Medium";
|
||||
else if (priority == "L") priority = "Low";
|
||||
}
|
||||
|
||||
lines.push_back (color.colorize (leftJustify (priority, width)));
|
||||
}
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
std::string ColumnPriority::modify (std::string& value)
|
||||
{
|
||||
if (value == "h") value = "H";
|
||||
else if (value == "m") value = "M";
|
||||
else if (value == "l") value = "L";
|
||||
|
||||
return value;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
bool ColumnPriority::can_modify ()
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
@@ -1,53 +0,0 @@
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Copyright 2006 - 2015, Paul Beckingham, Federico Hernandez.
|
||||
//
|
||||
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
// of this software and associated documentation files (the "Software"), to deal
|
||||
// in the Software without restriction, including without limitation the rights
|
||||
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
// copies of the Software, and to permit persons to whom the Software is
|
||||
// furnished to do so, subject to the following conditions:
|
||||
//
|
||||
// The above copyright notice and this permission notice shall be included
|
||||
// in all copies or substantial portions of the Software.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
|
||||
// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
|
||||
// THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
// SOFTWARE.
|
||||
//
|
||||
// http://www.opensource.org/licenses/mit-license.php
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#ifndef INCLUDED_COLPRIORITY
|
||||
#define INCLUDED_COLPRIORITY
|
||||
|
||||
#include <vector>
|
||||
#include <string>
|
||||
#include <Column.h>
|
||||
#include <Color.h>
|
||||
#include <Task.h>
|
||||
|
||||
class ColumnPriority : public Column
|
||||
{
|
||||
public:
|
||||
ColumnPriority ();
|
||||
~ColumnPriority ();
|
||||
|
||||
bool validate (std::string&);
|
||||
void setStyle (const std::string&);
|
||||
void measure (Task&, unsigned int&, unsigned int&);
|
||||
void render (std::vector <std::string>&, Task&, int, Color&);
|
||||
std::string modify (std::string&);
|
||||
bool can_modify ();
|
||||
|
||||
private:
|
||||
};
|
||||
|
||||
#endif
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
@@ -90,8 +90,8 @@ void ColumnRecur::measure (Task& task, unsigned int& minimum, unsigned int& maxi
|
||||
}
|
||||
else if (_style == "indicator")
|
||||
{
|
||||
if (task.has (_name))
|
||||
minimum = maximum = utf8_width (context.config.get ("recurrence.indicator"));
|
||||
minimum = maximum = utf8_width (context.config.get ("recurrence.indicator"));
|
||||
_fixed_width = true;
|
||||
}
|
||||
else
|
||||
throw format (STRING_COLUMN_BAD_FORMAT, _name, _style);
|
||||
|
||||
@@ -76,8 +76,8 @@ void ColumnStart::measure (Task& task, unsigned int& minimum, unsigned int& maxi
|
||||
{
|
||||
if (_style == "active")
|
||||
{
|
||||
if (! task.has ("end"))
|
||||
minimum = maximum = utf8_width (context.config.get ("active.indicator"));
|
||||
minimum = maximum = utf8_width (context.config.get ("active.indicator"));
|
||||
_fixed_width = true;
|
||||
}
|
||||
else
|
||||
ColumnDate::measure (task, minimum, maximum);
|
||||
|
||||
@@ -88,8 +88,15 @@ void ColumnTags::measure (Task& task, unsigned int& minimum, unsigned int& maxim
|
||||
|
||||
if (task.has (_name))
|
||||
{
|
||||
if (_style == "indicator") minimum = maximum = utf8_width (context.config.get ("tag.indicator"));
|
||||
else if (_style == "count") minimum = maximum = 3;
|
||||
if (_style == "indicator")
|
||||
{
|
||||
minimum = maximum = utf8_width (context.config.get ("tag.indicator"));
|
||||
_fixed_width = true;
|
||||
}
|
||||
else if (_style == "count")
|
||||
{
|
||||
minimum = maximum = 3;
|
||||
}
|
||||
else if (_style == "default" ||
|
||||
_style == "list")
|
||||
{
|
||||
|
||||
@@ -120,8 +120,8 @@ void ColumnUDA::measure (Task& task, unsigned int& minimum, unsigned int& maximu
|
||||
}
|
||||
else if (_style == "indicator")
|
||||
{
|
||||
if (task.has (_name))
|
||||
minimum = maximum = utf8_width (context.config.get ("uda." + _name + ".indicator"));
|
||||
minimum = maximum = utf8_width (context.config.get ("uda." + _name + ".indicator"));
|
||||
_fixed_width = true;
|
||||
}
|
||||
else
|
||||
throw format (STRING_COLUMN_BAD_FORMAT, _name, _style);
|
||||
|
||||
@@ -37,7 +37,6 @@
|
||||
#include <ColMask.h>
|
||||
#include <ColModified.h>
|
||||
#include <ColParent.h>
|
||||
#include <ColPriority.h>
|
||||
#include <ColProject.h>
|
||||
#include <ColRecur.h>
|
||||
#include <ColScheduled.h>
|
||||
@@ -88,7 +87,6 @@ Column* Column::factory (const std::string& name, const std::string& report)
|
||||
else if (column_name == "mask") c = new ColumnMask ();
|
||||
else if (column_name == "modified") c = new ColumnModified ();
|
||||
else if (column_name == "parent") c = new ColumnParent ();
|
||||
else if (column_name == "priority") c = new ColumnPriority ();
|
||||
else if (column_name == "project") c = new ColumnProject ();
|
||||
else if (column_name == "recur") c = new ColumnRecur ();
|
||||
else if (column_name == "scheduled") c = new ColumnScheduled ();
|
||||
@@ -131,7 +129,6 @@ void Column::factory (std::map <std::string, Column*>& all)
|
||||
c = new ColumnMask (); all[c->_name] = c;
|
||||
c = new ColumnModified (); all[c->_name] = c;
|
||||
c = new ColumnParent (); all[c->_name] = c;
|
||||
c = new ColumnPriority (); all[c->_name] = c;
|
||||
c = new ColumnProject (); all[c->_name] = c;
|
||||
c = new ColumnRecur (); all[c->_name] = c;
|
||||
c = new ColumnScheduled (); all[c->_name] = c;
|
||||
@@ -211,19 +208,21 @@ Column::Column ()
|
||||
, _report ("")
|
||||
, _modifiable (true)
|
||||
, _uda (false)
|
||||
, _fixed_width (false)
|
||||
{
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
Column::Column (const Column& other)
|
||||
{
|
||||
_name = other._name;
|
||||
_type = other._type;
|
||||
_style = other._style;
|
||||
_label = other._label;
|
||||
_label = other._report;
|
||||
_modifiable = other._modifiable;
|
||||
_uda = other._uda;
|
||||
_name = other._name;
|
||||
_type = other._type;
|
||||
_style = other._style;
|
||||
_label = other._label;
|
||||
_label = other._report;
|
||||
_modifiable = other._modifiable;
|
||||
_uda = other._uda;
|
||||
_fixed_width = other._fixed_width;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
@@ -238,6 +237,7 @@ Column& Column::operator= (const Column& other)
|
||||
_report = other._report;
|
||||
_modifiable = other._modifiable;
|
||||
_uda = other._uda;
|
||||
_fixed_width = other._fixed_width;
|
||||
}
|
||||
|
||||
return *this;
|
||||
|
||||
@@ -46,12 +46,13 @@ public:
|
||||
bool operator== (const Column&) const; // TODO Is this necessary?
|
||||
virtual ~Column ();
|
||||
|
||||
std::string name () const { return _name; }
|
||||
std::string style () const { return _style; }
|
||||
std::string label () const { return _label; }
|
||||
std::string type () const { return _type; }
|
||||
const std::string& name () const { return _name; }
|
||||
const std::string& style () const { return _style; }
|
||||
const std::string& label () const { return _label; }
|
||||
const std::string& type () const { return _type; }
|
||||
bool modifiable () const { return _modifiable; }
|
||||
bool is_uda () const { return _uda; }
|
||||
bool is_fixed_width () const { return _fixed_width;}
|
||||
std::vector <std::string> styles () const { return _styles; }
|
||||
std::vector <std::string> examples () const { return _examples; }
|
||||
|
||||
@@ -76,6 +77,7 @@ protected:
|
||||
std::string _report;
|
||||
bool _modifiable;
|
||||
bool _uda;
|
||||
bool _fixed_width;
|
||||
std::vector <std::string> _styles;
|
||||
std::vector <std::string> _examples;
|
||||
};
|
||||
|
||||
@@ -120,11 +120,11 @@ int CmdCalendar::execute (std::string& output)
|
||||
argWholeYear = true;
|
||||
|
||||
// YYYY.
|
||||
else if (digitsOnly (*arg) && arg->length () == 4)
|
||||
else if (Lexer::isAllDigits (*arg) && arg->length () == 4)
|
||||
argYear = strtol (arg->c_str (), NULL, 10);
|
||||
|
||||
// MM.
|
||||
else if (digitsOnly (*arg) && arg->length () <= 2)
|
||||
else if (Lexer::isAllDigits (*arg) && arg->length () <= 2)
|
||||
{
|
||||
argMonth = strtol (arg->c_str (), NULL, 10);
|
||||
if (argMonth < 1 || argMonth > 12)
|
||||
@@ -366,7 +366,7 @@ int CmdCalendar::execute (std::string& output)
|
||||
holTable.colorHeader (color_label);
|
||||
|
||||
Config::const_iterator it;
|
||||
std::map <time_t, std::vector<std::string> > hm; // we need to store multiple holidays per day
|
||||
std::map <time_t, std::vector<std::string>> hm; // we need to store multiple holidays per day
|
||||
for (it = context.config.begin (); it != context.config.end (); ++it)
|
||||
if (it->first.substr (0, 8) == "holiday.")
|
||||
if (it->first.substr (it->first.size () - 4) == "name")
|
||||
@@ -389,7 +389,7 @@ int CmdCalendar::execute (std::string& output)
|
||||
if (format == "")
|
||||
format = context.config.get ("dateformat");
|
||||
|
||||
std::map <time_t, std::vector<std::string> >::iterator hm_it;
|
||||
std::map <time_t, std::vector<std::string>>::iterator hm_it;
|
||||
for (hm_it = hm.begin(); hm_it != hm.end(); ++hm_it)
|
||||
{
|
||||
std::vector <std::string> v = hm_it->second;
|
||||
|
||||
@@ -163,7 +163,6 @@ int CmdConfig::execute (std::string& output)
|
||||
if (words.size ())
|
||||
{
|
||||
bool confirmation = context.config.getBoolean ("confirmation");
|
||||
bool change = false;
|
||||
bool found = false;
|
||||
|
||||
std::string name = words[0];
|
||||
|
||||
@@ -82,7 +82,7 @@ int CmdCustom::execute (std::string& output)
|
||||
validateSortColumns (sortOrder);
|
||||
|
||||
// Prepend the argument list with those from the report filter.
|
||||
context.cli.addRawFilter(reportFilter);
|
||||
context.cli.addRawFilter (reportFilter);
|
||||
|
||||
// Apply filter.
|
||||
handleRecurrence ();
|
||||
|
||||
@@ -206,8 +206,7 @@ std::string CmdEdit::formatTask (Task task, const std::string& dateformat)
|
||||
<< "# Status: " << ucFirst (Task::statusToText (task.getStatus ())) << "\n" // L10N safe ucFirst.
|
||||
<< "# Mask: " << task.get ("mask") << "\n"
|
||||
<< "# iMask: " << task.get ("imask") << "\n"
|
||||
<< " Project: " << task.get ("project") << "\n"
|
||||
<< " Priority: " << task.get ("priority") << "\n";
|
||||
<< " Project: " << task.get ("project") << "\n";
|
||||
|
||||
std::vector <std::string> tags;
|
||||
task.getTags (tags);
|
||||
@@ -343,25 +342,6 @@ void CmdEdit::parseTask (Task& task, const std::string& after, const std::string
|
||||
}
|
||||
}
|
||||
|
||||
// priority
|
||||
value = findValue (after, "\n Priority:");
|
||||
if (task.get ("priority") != value)
|
||||
{
|
||||
if (value != "")
|
||||
{
|
||||
if (context.columns["priority"]->validate (value))
|
||||
{
|
||||
context.footnote (STRING_EDIT_PRIORITY_MOD);
|
||||
task.set ("priority", value);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
context.footnote (STRING_EDIT_PRIORITY_DEL);
|
||||
task.remove ("priority");
|
||||
}
|
||||
}
|
||||
|
||||
// tags
|
||||
value = findValue (after, "\n Tags:");
|
||||
std::vector <std::string> tags;
|
||||
|
||||
@@ -39,8 +39,6 @@
|
||||
|
||||
extern Context context;
|
||||
|
||||
static const float epsilon = 0.000001;
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
CmdInfo::CmdInfo ()
|
||||
{
|
||||
@@ -152,14 +150,6 @@ int CmdInfo::execute (std::string& output)
|
||||
view.set (row, 1, task->get ("project"));
|
||||
}
|
||||
|
||||
// priority
|
||||
if (task->has ("priority"))
|
||||
{
|
||||
row = view.addRow ();
|
||||
view.set (row, 0, STRING_COLUMN_LABEL_PRIORITY);
|
||||
view.set (row, 1, task->get ("priority"));
|
||||
}
|
||||
|
||||
// dependencies: blocked
|
||||
{
|
||||
std::vector <Task> blocked;
|
||||
@@ -401,83 +391,107 @@ int CmdInfo::execute (std::string& output)
|
||||
}
|
||||
}
|
||||
|
||||
// Create a second table, containing urgency details.
|
||||
// Create a second table, containing urgency details, if necessary.
|
||||
ViewText urgencyDetails;
|
||||
if (context.color ())
|
||||
if (task->urgency () != 0.0)
|
||||
{
|
||||
Color alternate (context.config.get ("color.alternate"));
|
||||
urgencyDetails.colorOdd (alternate);
|
||||
urgencyDetails.intraColorOdd (alternate);
|
||||
|
||||
Color label (context.config.get ("color.label"));
|
||||
urgencyDetails.colorHeader (label);
|
||||
}
|
||||
|
||||
urgencyDetails.width (context.getWidth ());
|
||||
urgencyDetails.add (Column::factory ("string", "")); // Attribute
|
||||
urgencyDetails.add (Column::factory ("string", "")); // Value
|
||||
urgencyDetails.add (Column::factory ("string", "")); // *
|
||||
urgencyDetails.add (Column::factory ("string", "")); // Coefficient
|
||||
urgencyDetails.add (Column::factory ("string", "")); // =
|
||||
urgencyDetails.add (Column::factory ("string", "")); // Result
|
||||
|
||||
urgencyTerm (urgencyDetails, "project", task->urgency_project (), Task::urgencyProjectCoefficient);
|
||||
urgencyTerm (urgencyDetails, "priority", task->urgency_priority (), Task::urgencyPriorityCoefficient);
|
||||
urgencyTerm (urgencyDetails, "active", task->urgency_active (), Task::urgencyActiveCoefficient);
|
||||
urgencyTerm (urgencyDetails, "scheduled", task->urgency_scheduled (), Task::urgencyScheduledCoefficient);
|
||||
urgencyTerm (urgencyDetails, "waiting", task->urgency_waiting (), Task::urgencyWaitingCoefficient);
|
||||
urgencyTerm (urgencyDetails, "blocked", task->urgency_blocked (), Task::urgencyBlockedCoefficient);
|
||||
urgencyTerm (urgencyDetails, "blocking", task->urgency_blocking (), Task::urgencyBlockingCoefficient);
|
||||
urgencyTerm (urgencyDetails, "annotations", task->urgency_annotations (), Task::urgencyAnnotationsCoefficient);
|
||||
urgencyTerm (urgencyDetails, "tags", task->urgency_tags (), Task::urgencyTagsCoefficient);
|
||||
urgencyTerm (urgencyDetails, "next", task->urgency_next (), Task::urgencyNextCoefficient);
|
||||
urgencyTerm (urgencyDetails, "due", task->urgency_due (), Task::urgencyDueCoefficient);
|
||||
urgencyTerm (urgencyDetails, "age", task->urgency_age (), Task::urgencyAgeCoefficient);
|
||||
|
||||
// Tag, Project- and UDA-specific coefficients.
|
||||
std::map <std::string, float>::iterator var;
|
||||
for (var = Task::coefficients.begin (); var != Task::coefficients.end (); ++var)
|
||||
{
|
||||
if (var->first.substr (0, 13) == "urgency.user.")
|
||||
if (context.color ())
|
||||
{
|
||||
// urgency.user.project.<project>.coefficient
|
||||
std::string::size_type end = std::string::npos;
|
||||
if (var->first.substr (13, 8) == "project." &&
|
||||
(end = var->first.find (".coefficient")) != std::string::npos)
|
||||
Color alternate (context.config.get ("color.alternate"));
|
||||
urgencyDetails.colorOdd (alternate);
|
||||
urgencyDetails.intraColorOdd (alternate);
|
||||
|
||||
Color label (context.config.get ("color.label"));
|
||||
urgencyDetails.colorHeader (label);
|
||||
}
|
||||
|
||||
urgencyDetails.width (context.getWidth ());
|
||||
urgencyDetails.add (Column::factory ("string", "")); // Attribute
|
||||
urgencyDetails.add (Column::factory ("string", "")); // Value
|
||||
urgencyDetails.add (Column::factory ("string", "")); // *
|
||||
urgencyDetails.add (Column::factory ("string", "")); // Coefficient
|
||||
urgencyDetails.add (Column::factory ("string", "")); // =
|
||||
urgencyDetails.add (Column::factory ("string", "")); // Result
|
||||
|
||||
urgencyTerm (urgencyDetails, "project", task->urgency_project (), Task::urgencyProjectCoefficient);
|
||||
urgencyTerm (urgencyDetails, "active", task->urgency_active (), Task::urgencyActiveCoefficient);
|
||||
urgencyTerm (urgencyDetails, "scheduled", task->urgency_scheduled (), Task::urgencyScheduledCoefficient);
|
||||
urgencyTerm (urgencyDetails, "waiting", task->urgency_waiting (), Task::urgencyWaitingCoefficient);
|
||||
urgencyTerm (urgencyDetails, "blocked", task->urgency_blocked (), Task::urgencyBlockedCoefficient);
|
||||
urgencyTerm (urgencyDetails, "blocking", task->urgency_blocking (), Task::urgencyBlockingCoefficient);
|
||||
urgencyTerm (urgencyDetails, "annotations", task->urgency_annotations (), Task::urgencyAnnotationsCoefficient);
|
||||
urgencyTerm (urgencyDetails, "tags", task->urgency_tags (), Task::urgencyTagsCoefficient);
|
||||
urgencyTerm (urgencyDetails, "next", task->urgency_next (), Task::urgencyNextCoefficient);
|
||||
urgencyTerm (urgencyDetails, "due", task->urgency_due (), Task::urgencyDueCoefficient);
|
||||
urgencyTerm (urgencyDetails, "age", task->urgency_age (), Task::urgencyAgeCoefficient);
|
||||
|
||||
// Tag, Project- and UDA-specific coefficients.
|
||||
std::map <std::string, float>::iterator var;
|
||||
for (var = Task::coefficients.begin (); var != Task::coefficients.end (); ++var)
|
||||
{
|
||||
if (var->first.substr (0, 13) == "urgency.user.")
|
||||
{
|
||||
std::string project = var->first.substr (21, end - 21);
|
||||
if (task->get ("project").find (project) == 0)
|
||||
urgencyTerm (urgencyDetails, "PROJECT " + project, 1.0, var->second);
|
||||
// urgency.user.project.<project>.coefficient
|
||||
std::string::size_type end = std::string::npos;
|
||||
if (var->first.substr (13, 8) == "project." &&
|
||||
(end = var->first.find (".coefficient")) != std::string::npos)
|
||||
{
|
||||
std::string project = var->first.substr (21, end - 21);
|
||||
if (task->get ("project").find (project) == 0)
|
||||
urgencyTerm (urgencyDetails, "PROJECT " + project, 1.0, var->second);
|
||||
}
|
||||
|
||||
// urgency.user.tag.<tag>.coefficient
|
||||
if (var->first.substr (13, 4) == "tag." &&
|
||||
(end = var->first.find (".coefficient")) != std::string::npos)
|
||||
{
|
||||
std::string name = var->first.substr (17, end - 17);
|
||||
if (task->hasTag (name))
|
||||
urgencyTerm (urgencyDetails, "TAG " + name, 1.0, var->second);
|
||||
}
|
||||
|
||||
// urgency.user.keyword.<keyword>.coefficient
|
||||
if (var->first.substr (13, 8) == "keyword." &&
|
||||
(end = var->first.find (".coefficient")) != std::string::npos)
|
||||
{
|
||||
std::string keyword = var->first.substr (21, end - 21);
|
||||
if (task->get ("description").find (keyword) != std::string::npos)
|
||||
urgencyTerm (urgencyDetails, "KEYWORD " + keyword, 1.0, var->second);
|
||||
}
|
||||
}
|
||||
|
||||
// urgency.user.tag.<tag>.coefficient
|
||||
if (var->first.substr (13, 4) == "tag." &&
|
||||
(end = var->first.find (".coefficient")) != std::string::npos)
|
||||
// urgency.uda.<name>.coefficient
|
||||
else if (var->first.substr (0, 12) == "urgency.uda.")
|
||||
{
|
||||
std::string name = var->first.substr (17, end - 17);
|
||||
if (task->hasTag (name))
|
||||
urgencyTerm (urgencyDetails, "TAG " + name, 1.0, var->second);
|
||||
// urgency.uda.<name>.coefficient
|
||||
// urgency.uda.<name>.<value>.coefficient
|
||||
std::string::size_type end = var->first.find (".coefficient");
|
||||
if (end != std::string::npos)
|
||||
{
|
||||
const std::string uda = var->first.substr (12, end - 12);
|
||||
std::string::size_type dot = uda.find (".");
|
||||
if (dot == std::string::npos)
|
||||
{
|
||||
// urgency.uda.<name>.coefficient
|
||||
if (task->has (uda))
|
||||
urgencyTerm (urgencyDetails, std::string ("UDA ") + uda, 1.0, var->second);
|
||||
}
|
||||
else
|
||||
{
|
||||
// urgency.uda.<name>.<value>.coefficient
|
||||
if (task->get (uda.substr(0, dot)) == uda.substr(dot+1))
|
||||
urgencyTerm (urgencyDetails, std::string ("UDA ") + uda, 1.0, var->second);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// urgency.uda.<name>.coefficient
|
||||
else if (var->first.substr (0, 12) == "urgency.uda.")
|
||||
{
|
||||
std::string::size_type end = var->first.find (".coefficient");
|
||||
if (end != std::string::npos)
|
||||
{
|
||||
std::string name = var->first.substr (12, end - 12);
|
||||
if (task->has (name))
|
||||
urgencyTerm (urgencyDetails, "UDA " + name, 1.0, var->second);
|
||||
}
|
||||
}
|
||||
row = urgencyDetails.addRow ();
|
||||
urgencyDetails.set (row, 5, rightJustify ("------", 6));
|
||||
row = urgencyDetails.addRow ();
|
||||
urgencyDetails.set (row, 5, rightJustify (format (task->urgency (), 4, 4), 6));
|
||||
}
|
||||
|
||||
row = urgencyDetails.addRow ();
|
||||
urgencyDetails.set (row, 5, rightJustify ("------", 6));
|
||||
row = urgencyDetails.addRow ();
|
||||
urgencyDetails.set (row, 5, rightJustify (format (task->urgency (), 4, 4), 6));
|
||||
|
||||
// Create a third table, containing undo log change details.
|
||||
ViewText journal;
|
||||
|
||||
@@ -562,7 +576,7 @@ void CmdInfo::urgencyTerm (
|
||||
int row = view.addRow ();
|
||||
view.set (row, 0, " " + label);
|
||||
view.set (row, 1, rightJustify (format (measure, 5, 3), 6));
|
||||
view.set (row, 2, "+");
|
||||
view.set (row, 2, "*");
|
||||
view.set (row, 3, rightJustify (format (coefficient, 4, 2), 4));
|
||||
view.set (row, 4, "=");
|
||||
view.set (row, 5, rightJustify (format (value, 5, 3), 6));
|
||||
|
||||
@@ -82,7 +82,6 @@ int CmdProjects::execute (std::string& output)
|
||||
std::map <std::string, int> unique;
|
||||
bool no_project = false;
|
||||
std::string project;
|
||||
std::string priority;
|
||||
std::vector <Task>::iterator task;
|
||||
for (task = filtered.begin (); task != filtered.end (); ++task)
|
||||
{
|
||||
|
||||
@@ -109,10 +109,6 @@ int CmdShow::execute (std::string& output)
|
||||
" color.label"
|
||||
" color.label.sort"
|
||||
" color.overdue"
|
||||
" color.pri.H"
|
||||
" color.pri.L"
|
||||
" color.pri.M"
|
||||
" color.pri.none"
|
||||
" color.recurring"
|
||||
" color.scheduled"
|
||||
" color.summary.background"
|
||||
@@ -142,7 +138,6 @@ int CmdShow::execute (std::string& output)
|
||||
" debug.tls"
|
||||
" default.command"
|
||||
" default.due"
|
||||
" default.priority"
|
||||
" default.project"
|
||||
" defaultheight"
|
||||
" defaultwidth"
|
||||
@@ -183,6 +178,7 @@ int CmdShow::execute (std::string& output)
|
||||
" rule.precedence.color"
|
||||
" search.case.sensitive"
|
||||
" shell.prompt"
|
||||
" summary.all.projects"
|
||||
" tag.indicator"
|
||||
" taskd.server"
|
||||
" taskd.ca"
|
||||
@@ -200,7 +196,6 @@ int CmdShow::execute (std::string& output)
|
||||
" urgency.inherit.coefficient"
|
||||
" urgency.due.coefficient"
|
||||
" urgency.next.coefficient"
|
||||
" urgency.priority.coefficient"
|
||||
" urgency.project.coefficient"
|
||||
" urgency.tags.coefficient"
|
||||
" urgency.waiting.coefficient"
|
||||
@@ -240,6 +235,7 @@ int CmdShow::execute (std::string& output)
|
||||
i->first.substr (0, 8) != "default." &&
|
||||
i->first.substr (0, 21) != "urgency.user.project." &&
|
||||
i->first.substr (0, 17) != "urgency.user.tag." &&
|
||||
i->first.substr (0, 21) != "urgency.user.keyword." &&
|
||||
i->first.substr (0, 12) != "urgency.uda.")
|
||||
{
|
||||
unrecognized.push_back (i->first);
|
||||
@@ -367,15 +363,6 @@ int CmdShow::execute (std::string& output)
|
||||
out << format (STRING_CMD_SHOW_CONFIG_ERROR, "calendar.holidays", calendarholidays)
|
||||
<< "\n";
|
||||
|
||||
// Check for bad values in rc.default.priority.
|
||||
std::string defaultPriority = context.config.get ("default.priority");
|
||||
if (defaultPriority != "H" &&
|
||||
defaultPriority != "M" &&
|
||||
defaultPriority != "L" &&
|
||||
defaultPriority != "")
|
||||
out << format (STRING_CMD_SHOW_CONFIG_ERROR, "default.priority", defaultPriority)
|
||||
<< "\n";
|
||||
|
||||
// Verify installation. This is mentioned in the documentation as the way
|
||||
// to ensure everything is properly installed.
|
||||
|
||||
|
||||
@@ -57,6 +57,7 @@ CmdSummary::CmdSummary ()
|
||||
int CmdSummary::execute (std::string& output)
|
||||
{
|
||||
int rc = 0;
|
||||
bool showAllProjects = context.config.getBoolean ("summary.all.projects");
|
||||
|
||||
// Apply filter.
|
||||
handleRecurrence ();
|
||||
@@ -68,7 +69,7 @@ int CmdSummary::execute (std::string& output)
|
||||
std::map <std::string, bool> allProjects;
|
||||
std::vector <Task>::iterator task;
|
||||
for (task = filtered.begin (); task != filtered.end (); ++task)
|
||||
if (task->getStatus () == Task::pending)
|
||||
if (showAllProjects || task->getStatus () == Task::pending)
|
||||
allProjects[task->get ("project")] = false;
|
||||
|
||||
// Initialize counts, sum.
|
||||
@@ -122,7 +123,6 @@ int CmdSummary::execute (std::string& output)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// Create a table for output.
|
||||
ViewText view;
|
||||
view.width (context.getWidth ());
|
||||
@@ -143,7 +143,7 @@ int CmdSummary::execute (std::string& output)
|
||||
std::map <std::string, bool>::iterator i;
|
||||
for (i = allProjects.begin (); i != allProjects.end (); ++i)
|
||||
{
|
||||
if (countPending[i->first] > 0)
|
||||
if (showAllProjects || countPending[i->first] > 0)
|
||||
{
|
||||
const std::vector <std::string> parents = extractParents (i->first);
|
||||
std::vector <std::string>::const_iterator parent;
|
||||
@@ -169,7 +169,9 @@ int CmdSummary::execute (std::string& output)
|
||||
|
||||
int c = countCompleted[i->first];
|
||||
int p = countPending[i->first];
|
||||
int completedBar = (c * barWidth) / (c + p);
|
||||
int completedBar = 0;
|
||||
if (c + p)
|
||||
completedBar = (c * barWidth) / (c + p);
|
||||
|
||||
std::string bar;
|
||||
std::string subbar;
|
||||
@@ -185,8 +187,9 @@ int CmdSummary::execute (std::string& output)
|
||||
}
|
||||
view.set (row, 4, bar);
|
||||
|
||||
char percent[12];
|
||||
sprintf (percent, "%d%%", 100 * c / (c + p));
|
||||
char percent[12] = "0%";
|
||||
if (c + p)
|
||||
sprintf (percent, "%d%%", 100 * c / (c + p));
|
||||
view.set (row, 3, percent);
|
||||
processed.push_back (i->first);
|
||||
}
|
||||
|
||||
@@ -86,7 +86,6 @@
|
||||
|
||||
#include <Context.h>
|
||||
#include <ColProject.h>
|
||||
#include <ColPriority.h>
|
||||
#include <ColDue.h>
|
||||
|
||||
extern Context context;
|
||||
@@ -323,8 +322,8 @@ bool Command::permission (
|
||||
}
|
||||
|
||||
// 1 < Quantity < bulk modifications have optional confirmation, in the (y/n/a/q)
|
||||
// style.
|
||||
if (quantity < bulk && (!_needs_confirm || !confirmation))
|
||||
// style. Bulk = 0 denotes infinite bulk.
|
||||
if ((bulk == 0 || quantity < bulk) && (!_needs_confirm || !confirmation))
|
||||
return true;
|
||||
|
||||
if (context.verbose ("blank") && !_first_iteration)
|
||||
|
||||
@@ -252,6 +252,7 @@ std::string taskInfoDifferences (
|
||||
|
||||
for (name = beforeAtts.begin (); name != beforeAtts.end (); ++name)
|
||||
if (*name != "uuid" &&
|
||||
*name != "modified" &&
|
||||
before.get (*name) != after.get (*name) &&
|
||||
before.get (*name) != "" && after.get (*name) != "")
|
||||
{
|
||||
|
||||
@@ -172,13 +172,6 @@
|
||||
#define STRING_VARIANT_SQRT_NEG "Quadratwurzel einer negativen Zahl kann nicht berechnet werden."
|
||||
#define STRING_VARIANT_COERCE_UNK "Kann nicht in oder von einem unbekannten Typ konvertieren"
|
||||
|
||||
// Lexer
|
||||
//
|
||||
// These are errors generated at the lowest level of input analysis,
|
||||
// at the character level.
|
||||
#define STRING_LEX_IMMEDIATE_UNK "Lexer konnte nicht gestartet werden, sofort unbekannte Zeichen gefunden."
|
||||
#define STRING_LEX_TYPE_UNK "Lexer kann unbekanntes Symbol nicht verarbeiten."
|
||||
|
||||
// Dates
|
||||
//
|
||||
// These are errors generated when parsing date values.
|
||||
@@ -204,8 +197,6 @@
|
||||
#define STRING_COLUMN_LABEL_ADDED "Hinzugefügt"
|
||||
#define STRING_COLUMN_LABEL_AGE "Alter"
|
||||
#define STRING_COLUMN_LABEL_ID "ID"
|
||||
#define STRING_COLUMN_LABEL_PRI "Pri"
|
||||
#define STRING_COLUMN_LABEL_PRIORITY "Priorität"
|
||||
#define STRING_COLUMN_LABEL_PROJECT "Projekt"
|
||||
#define STRING_COLUMN_LABEL_UNTIL "Bis"
|
||||
#define STRING_COLUMN_LABEL_WAIT "Aufgeschoben"
|
||||
@@ -708,8 +699,6 @@
|
||||
|
||||
#define STRING_EDIT_PROJECT_MOD "Projekt geändert."
|
||||
#define STRING_EDIT_PROJECT_DEL "Projekt gelöscht."
|
||||
#define STRING_EDIT_PRIORITY_MOD "Wichtigkeit geändert."
|
||||
#define STRING_EDIT_PRIORITY_DEL "Wichtigkeit gelöscht."
|
||||
#define STRING_EDIT_DESC_MOD "Beschreibung geändert."
|
||||
#define STRING_EDIT_DESC_REMOVE_ERR "Beschreibung kann nicht entfernt werden."
|
||||
#define STRING_EDIT_ENTRY_REMOVE_ERR "Erstelldatum kann nicht entfernt werden."
|
||||
@@ -874,7 +863,6 @@
|
||||
#define STRING_TASK_VALID_BEFORE "Warnung: Das '{1}'-Datum ist nach dem '{2}'-Datum."
|
||||
#define STRING_TASK_VALID_REC_DUE "Wiederholende Aufgaben müssen eine Fälligkeit besitzen."
|
||||
#define STRING_TASK_VALID_RECUR "Wiederhol-Periode '{1}' ist ungültig."
|
||||
#define STRING_TASK_VALID_PRIORITY "Die Wichtigkeit kann die Werte 'H', 'M' oder 'L' annehmen, nicht jedoch '{1}'."
|
||||
#define STRING_TASK_SAFETY_VALVE "Dieser Befehl hat keinen Filter und wird alle Aufgaben verändern. Sind Sie sicher?"
|
||||
#define STRING_TASK_SAFETY_FAIL "Befehl an Ausführung gehindert."
|
||||
#define STRING_TASK_SAFETY_ALLOW "Kein Filter angegeben, und durch den konfigurierten 'allow.empty.filter'-Wert wurde keine Aktion durchgeführt."
|
||||
@@ -1029,4 +1017,7 @@
|
||||
#define STRING_UTIL_KIBIBYTES "KiB"
|
||||
#define STRING_UTIL_BYTES "B"
|
||||
|
||||
// Legacy
|
||||
#define STRING_LEGACY_PRIORITY "Legacy attribute found. Please change '{1}' to '{2}'."
|
||||
|
||||
#endif
|
||||
|
||||
@@ -172,13 +172,6 @@
|
||||
#define STRING_VARIANT_SQRT_NEG "Cannot take the square root of a negative number."
|
||||
#define STRING_VARIANT_COERCE_UNK "Cannot coerce data either to or from an unknown type"
|
||||
|
||||
// Lexer
|
||||
//
|
||||
// These are errors generated at the lowest level of input analysis,
|
||||
// at the character level.
|
||||
#define STRING_LEX_IMMEDIATE_UNK "Lexer start failure, unknown characters found immediately."
|
||||
#define STRING_LEX_TYPE_UNK "Lexer cannot process an unknown token type."
|
||||
|
||||
// Dates
|
||||
//
|
||||
// These are errors generated when parsing date values.
|
||||
@@ -204,8 +197,6 @@
|
||||
#define STRING_COLUMN_LABEL_ADDED "Added"
|
||||
#define STRING_COLUMN_LABEL_AGE "Age"
|
||||
#define STRING_COLUMN_LABEL_ID "ID"
|
||||
#define STRING_COLUMN_LABEL_PRI "Pri"
|
||||
#define STRING_COLUMN_LABEL_PRIORITY "Priority"
|
||||
#define STRING_COLUMN_LABEL_PROJECT "Project"
|
||||
#define STRING_COLUMN_LABEL_UNTIL "Until"
|
||||
#define STRING_COLUMN_LABEL_WAIT "Wait"
|
||||
@@ -341,7 +332,7 @@
|
||||
#define STRING_CMD_HISTORY_USAGE_A "Shows a report of task history, by year"
|
||||
#define STRING_CMD_HISTORY_AVERAGE "Average"
|
||||
#define STRING_CMD_HISTORY_LEGEND "Legend: {1}, {2}, {3}"
|
||||
#define STRING_CMD_HISTORY_LEGEND_A "Legend: + added, X completed, - deleted"
|
||||
#define STRING_CMD_HISTORY_LEGEND_A "Legend: + Added, X Completed, - Deleted"
|
||||
#define STRING_CMD_GHISTORY_USAGE_M "Shows a graphical report of task history, by month"
|
||||
#define STRING_CMD_GHISTORY_USAGE_A "Shows a graphical report of task history, by year"
|
||||
#define STRING_CMD_GHISTORY_YEAR "Year"
|
||||
@@ -708,8 +699,6 @@
|
||||
|
||||
#define STRING_EDIT_PROJECT_MOD "Project modified."
|
||||
#define STRING_EDIT_PROJECT_DEL "Project deleted."
|
||||
#define STRING_EDIT_PRIORITY_MOD "Priority modified."
|
||||
#define STRING_EDIT_PRIORITY_DEL "Priority deleted."
|
||||
#define STRING_EDIT_DESC_MOD "Description modified."
|
||||
#define STRING_EDIT_DESC_REMOVE_ERR "Cannot remove description."
|
||||
#define STRING_EDIT_ENTRY_REMOVE_ERR "Cannot remove creation date."
|
||||
@@ -874,7 +863,6 @@
|
||||
#define STRING_TASK_VALID_BEFORE "Warning: You have specified that the '{1}' date is after the '{2}' date."
|
||||
#define STRING_TASK_VALID_REC_DUE "A recurring task must also have a 'due' date."
|
||||
#define STRING_TASK_VALID_RECUR "The recurrence value '{1}' is not valid."
|
||||
#define STRING_TASK_VALID_PRIORITY "Priority values may be 'H', 'M' or 'L', not '{1}'."
|
||||
#define STRING_TASK_SAFETY_VALVE "This command has no filter, and will modify all tasks. Are you sure?"
|
||||
#define STRING_TASK_SAFETY_FAIL "Command prevented from running."
|
||||
#define STRING_TASK_SAFETY_ALLOW "You did not specify a filter, and with the 'allow.empty.filter' value, no action is taken."
|
||||
@@ -1026,4 +1014,7 @@
|
||||
#define STRING_UTIL_KIBIBYTES "KiB"
|
||||
#define STRING_UTIL_BYTES "B"
|
||||
|
||||
// Legacy
|
||||
#define STRING_LEGACY_PRIORITY "Legacy attribute found. Please change '{1}' to '{2}'."
|
||||
|
||||
#endif
|
||||
|
||||
@@ -172,13 +172,6 @@
|
||||
#define STRING_VARIANT_SQRT_NEG "Ne povas kalkuli kvadratan radikon de negativa nombro."
|
||||
#define STRING_VARIANT_COERCE_UNK "Ne povas konverta datumon ni el ni al nekonata tipo"
|
||||
|
||||
// Lexer
|
||||
//
|
||||
// These are errors generated at the lowest level of input analysis,
|
||||
// at the character level.
|
||||
#define STRING_LEX_IMMEDIATE_UNK "Malsukcesis eki leksikan analizon; trovis tuj nekonatajn signojn."
|
||||
#define STRING_LEX_TYPE_UNK "Leksika analizilo ne povas interpreti sintagmon de nekonata tipo."
|
||||
|
||||
// Dates
|
||||
//
|
||||
// These are errors generated when parsing date values.
|
||||
@@ -204,8 +197,6 @@
|
||||
#define STRING_COLUMN_LABEL_ADDED "Kreita"
|
||||
#define STRING_COLUMN_LABEL_AGE "Aĝo"
|
||||
#define STRING_COLUMN_LABEL_ID "ID"
|
||||
#define STRING_COLUMN_LABEL_PRI "Gr"
|
||||
#define STRING_COLUMN_LABEL_PRIORITY "Graveco"
|
||||
#define STRING_COLUMN_LABEL_PROJECT "Projekto"
|
||||
#define STRING_COLUMN_LABEL_UNTIL "Ĝis"
|
||||
#define STRING_COLUMN_LABEL_WAIT "Atendu"
|
||||
@@ -708,8 +699,6 @@
|
||||
|
||||
#define STRING_EDIT_PROJECT_MOD "Modifis la projekton."
|
||||
#define STRING_EDIT_PROJECT_DEL "Viŝis la projekton."
|
||||
#define STRING_EDIT_PRIORITY_MOD "Modifis la gravecon."
|
||||
#define STRING_EDIT_PRIORITY_DEL "Viŝis la gravecon."
|
||||
#define STRING_EDIT_DESC_MOD "Modifis la priskribon."
|
||||
#define STRING_EDIT_DESC_REMOVE_ERR "Ne povis viŝi la priskribon."
|
||||
#define STRING_EDIT_ENTRY_REMOVE_ERR "Ne povis viŝi la krean daton."
|
||||
@@ -874,7 +863,6 @@
|
||||
#define STRING_TASK_VALID_BEFORE "Averto: Vi specifis daton '{1}' post dato '{2}'."
|
||||
#define STRING_TASK_VALID_REC_DUE "Reokazanta tasko devas ankaŭ havi daton 'due'."
|
||||
#define STRING_TASK_VALID_RECUR "Reokaz-valoro '{1}' ne estas valida."
|
||||
#define STRING_TASK_VALID_PRIORITY "Gravec-valoro povas esti 'H', 'M', aŭ 'L', sed ne '{1}'."
|
||||
#define STRING_TASK_SAFETY_VALVE "Tiu komando ne havas filtrilo, do ĝi modifos ĉian taskon. Ĉu vi estas certa?"
|
||||
#define STRING_TASK_SAFETY_FAIL "Antaŭmalebligis komandon."
|
||||
#define STRING_TASK_SAFETY_ALLOW "Vi ne specifis filtrilon. Laŭ la valoro 'allow.empty.filter', ne faros nenion."
|
||||
@@ -1026,4 +1014,7 @@
|
||||
#define STRING_UTIL_KIBIBYTES "KiB"
|
||||
#define STRING_UTIL_BYTES "B"
|
||||
|
||||
// Legacy
|
||||
#define STRING_LEGACY_PRIORITY "Legacy attribute found. Please change '{1}' to '{2}'."
|
||||
|
||||
#endif
|
||||
|
||||
@@ -172,13 +172,6 @@
|
||||
#define STRING_VARIANT_SQRT_NEG "No se puede calcular la raíz cuadrada de un tipo desconocido"
|
||||
#define STRING_VARIANT_COERCE_UNK "No se puede convertir un dato ni a un tipo desconocido ni desde el mismo"
|
||||
|
||||
// Lexer
|
||||
//
|
||||
// These are errors generated at the lowest level of input analysis,
|
||||
// at the character level.
|
||||
#define STRING_LEX_IMMEDIATE_UNK "El analizador léxico falló, encontró caracteres desconocidos al comienzo."
|
||||
#define STRING_LEX_TYPE_UNK "El analizador léxico no puede procesar un tipo desconocido de sintagma."
|
||||
|
||||
// Dates
|
||||
//
|
||||
// These are errors generated when parsing date values.
|
||||
@@ -204,8 +197,6 @@
|
||||
#define STRING_COLUMN_LABEL_ADDED "Añadida"
|
||||
#define STRING_COLUMN_LABEL_AGE "Edad"
|
||||
#define STRING_COLUMN_LABEL_ID "ID" // |esp-ESP|==|eng-USA|
|
||||
#define STRING_COLUMN_LABEL_PRI "Pri" // |esp-ESP|==|eng-USA|
|
||||
#define STRING_COLUMN_LABEL_PRIORITY "Prioridad"
|
||||
#define STRING_COLUMN_LABEL_PROJECT "Proyecto"
|
||||
#define STRING_COLUMN_LABEL_UNTIL "Hasta"
|
||||
#define STRING_COLUMN_LABEL_WAIT "Espera"
|
||||
@@ -468,7 +459,7 @@
|
||||
#define STRING_CMD_IMPORT_SUMMARY "Importadas {1} tareas."
|
||||
#define STRING_CMD_IMPORT_NOFILE "Debe especificar un archivo a importar."
|
||||
#define STRING_CMD_IMPORT_FILE "Importando '{1}'"
|
||||
#define STRING_CMD_IMPORT_MISSING "File '{1}' not found."
|
||||
#define STRING_CMD_IMPORT_MISSING "Archivo '{1}' no encontrado."
|
||||
#define STRING_TASK_NO_DESC "La anotación carece de descripción: {1}"
|
||||
#define STRING_TASK_NO_ENTRY "La anotación carece de fecha de entrada: {1}"
|
||||
|
||||
@@ -499,14 +490,14 @@
|
||||
#define STRING_CMD_SYNC_CONNECT "No se pudo conectar a {1} {2}"
|
||||
#define STRING_CMD_SYNC_HANDSHAKE "Handshake fallido. {1}"
|
||||
#define STRING_CMD_SYNC_TRUST_CA "Debe proveer un certificado CA o la verificación de sobrescritura, pero no ambos."
|
||||
#define STRING_CMD_SYNC_TRUST_OBS "The 'taskd.trust' settings may now only contain a value of 'strict', 'ignore hostname' or 'allow all'."
|
||||
#define STRING_CMD_SYNC_TRUST_OBS "Los ajustes de 'taskd.trust' ahora solo pueden contener uno de los valores 'strict', 'ignore hostname' o 'allow all'."
|
||||
#define STRING_CMD_DIAG_USAGE "Detalles de plataforma, construcción y entorno"
|
||||
#define STRING_CMD_DIAG_PLATFORM "Plataforma"
|
||||
#define STRING_CMD_DIAG_UNKNOWN "<desconocido>"
|
||||
#define STRING_CMD_DIAG_COMPILER "Compilador"
|
||||
#define STRING_CMD_DIAG_VERSION "Versión"
|
||||
#define STRING_CMD_DIAG_CAPS "Capacidades"
|
||||
#define STRING_CMD_DIAG_COMPLIANCE "Compliance"
|
||||
#define STRING_CMD_DIAG_COMPLIANCE "Conformidad"
|
||||
#define STRING_CMD_DIAG_FEATURES "Características Constructivas"
|
||||
#define STRING_CMD_DIAG_BUILT "Construido"
|
||||
#define STRING_CMD_DIAG_COMMIT "Commit" // |esp-ESP|==|eng-USA|
|
||||
@@ -521,14 +512,17 @@
|
||||
#define STRING_CMD_DIAG_UUID_NO_DUP "No se encontraron duplicados"
|
||||
#define STRING_CMD_DIAG_NONE "-ninguno-"
|
||||
#define STRING_CMD_DIAG_HOOKS "Hooks" // |esp-ESP|==|eng-USA|
|
||||
#define STRING_CMD_DIAG_HOOK_NAME "nombre de hook no reconocido"
|
||||
#define STRING_CMD_DIAG_HOOK_SYMLINK "symlink" // |esp-ESP|==|eng-USA|
|
||||
#define STRING_CMD_DIAG_HOOK_EXEC "ejecutable"
|
||||
#define STRING_CMD_DIAG_HOOK_NO_EXEC "no ejecutable"
|
||||
#define STRING_CMD_DIAG_HOOK_ENABLE "Habilitado"
|
||||
#define STRING_CMD_DIAG_HOOK_DISABLE "Inhabilitado"
|
||||
|
||||
#define STRING_CMD_HCOMMANDS_USAGE "Genera una lista de todos los comandos, con fines de auto-completado"
|
||||
#define STRING_CMD_ZSHCOMMANDS_USAGE "Genera una lista de todos los comandos, con fines de auto-completado zsh"
|
||||
#define STRING_CMD_DIAG_HOOK_EXEC "executable"
|
||||
#define STRING_CMD_DIAG_HOOK_NO_EXEC "not executable"
|
||||
#define STRING_CMD_DIAG_HOOK_ENABLE "Enabled"
|
||||
#define STRING_CMD_DIAG_HOOK_DISABLE "Disabled"
|
||||
|
||||
#define STRING_CMD_ZSHATTS_USAGE "Generates a list of all attributes, for zsh autocompletion purposes"
|
||||
#define STRING_CMD_ZSHATTS_USAGE "Genera una lista de todos los atributos, con fines de auto-completado zsh"
|
||||
#define STRING_CMD_ALIASES_USAGE "Genera una lista de todos los alias, con fines de auto-completado"
|
||||
#define STRING_CMD_INSTALL_USAGE "Instala extensiones y scripts externos"
|
||||
|
||||
@@ -571,25 +565,25 @@
|
||||
#define STRING_CMD_CONFIG_NO_CHANGE "No se hicieron cambios."
|
||||
#define STRING_CMD_CONFIG_NO_NAME "Especifique el nombre de una variable de configuración a modificar."
|
||||
#define STRING_CMD_HCONFIG_USAGE "Lista todas las variables de configuración soportadas, a fines de completado"
|
||||
#define STRING_CMD_CONTEXT_USAGE "Set and define contexts (default filters)"
|
||||
#define STRING_CMD_CONTEXT_DEF_SUCC "Context '{1}' defined."
|
||||
#define STRING_CMD_CONTEXT_DEF_FAIL "Context '{1}' not defined."
|
||||
#define STRING_CMD_CONTEXT_DEF_USAG "Both context name and its definition must be provided."
|
||||
#define STRING_CMD_CONTEXT_DEF_ABRT "Context definiton aborted."
|
||||
#define STRING_CMD_CONTEXT_DEF_ABRT2 "Filter validation failed: {1}"
|
||||
#define STRING_CMD_CONTEXT_DEF_CONF "The filter '{1}' matches 0 pending tasks. Do you wish to continue?"
|
||||
#define STRING_CMD_CONTEXT_DEL_SUCC "Context '{1}' deleted."
|
||||
#define STRING_CMD_CONTEXT_DEL_FAIL "Context '{1}' not deleted."
|
||||
#define STRING_CMD_CONTEXT_DEL_USAG "Context name needs to be specified."
|
||||
#define STRING_CMD_CONTEXT_LIST_EMPT "No contexts defined."
|
||||
#define STRING_CMD_CONTEXT_SET_NFOU "Context '{1}' not found."
|
||||
#define STRING_CMD_CONTEXT_SET_SUCC "Context '{1}' set. Use 'task context none' to remove."
|
||||
#define STRING_CMD_CONTEXT_SET_FAIL "Context '{1}' not applied."
|
||||
#define STRING_CMD_CONTEXT_SHOW_EMPT "No context is currently applied."
|
||||
#define STRING_CMD_CONTEXT_SHOW "Context '{1}' with filter '{2}' is currently applied."
|
||||
#define STRING_CMD_CONTEXT_NON_SUCC "Context unset."
|
||||
#define STRING_CMD_CONTEXT_NON_FAIL "Context not unset."
|
||||
#define STRING_CMD_HCONTEXT_USAGE "Lists all supported contexts, for completion purposes"
|
||||
#define STRING_CMD_CONTEXT_USAGE "Establece y define contextos (filtros por defecto)"
|
||||
#define STRING_CMD_CONTEXT_DEF_SUCC "Contexto '{1}' definido."
|
||||
#define STRING_CMD_CONTEXT_DEF_FAIL "Contexto '{1}' no definido."
|
||||
#define STRING_CMD_CONTEXT_DEF_USAG "Se deben definir tanto el nombre de un contexto como su definición."
|
||||
#define STRING_CMD_CONTEXT_DEF_ABRT "Definición de contexto abortada."
|
||||
#define STRING_CMD_CONTEXT_DEF_ABRT2 "Validación de filtro fallida: {1}"
|
||||
#define STRING_CMD_CONTEXT_DEF_CONF "El filtro '{1}' coincide con 0 tareas pendientes. ¿Quiere continuar?"
|
||||
#define STRING_CMD_CONTEXT_DEL_SUCC "Contexto '{1}' eliminado."
|
||||
#define STRING_CMD_CONTEXT_DEL_FAIL "Contexto '{1}' no eliminado."
|
||||
#define STRING_CMD_CONTEXT_DEL_USAG "El nombre del contexto necesita ser especificado."
|
||||
#define STRING_CMD_CONTEXT_LIST_EMPT "No hay contextos definidos."
|
||||
#define STRING_CMD_CONTEXT_SET_NFOU "Contexto '{1}' noencontrado."
|
||||
#define STRING_CMD_CONTEXT_SET_SUCC "Contexto '{1}' establecido. Use 'task context none' para eliminarlo."
|
||||
#define STRING_CMD_CONTEXT_SET_FAIL "Contexto '{1}' no aplicado."
|
||||
#define STRING_CMD_CONTEXT_SHOW_EMPT "Actualmente no se aplica ningún contexto."
|
||||
#define STRING_CMD_CONTEXT_SHOW "El contexto '{1}' con filtro '{2}' se aplica actualmente."
|
||||
#define STRING_CMD_CONTEXT_NON_SUCC "Contexto deshabilitado."
|
||||
#define STRING_CMD_CONTEXT_NON_FAIL "Context no deshabilitado."
|
||||
#define STRING_CMD_HCONTEXT_USAGE "Lista todos los contextos soportados, con fines de completado"
|
||||
#define STRING_CMD_CUSTOM_MISMATCH "Hay diferente número de columnas y etiquetas para el informe '{1}'."
|
||||
#define STRING_CMD_CUSTOM_SHOWN "{1} mostrada(s)"
|
||||
#define STRING_CMD_CUSTOM_COUNT "1 tarea"
|
||||
@@ -695,11 +689,11 @@
|
||||
#define STRING_DOM_CANNOT_SET "DOM: No se pudo establecer '{1}'."
|
||||
|
||||
// Eval
|
||||
#define STRING_EVAL_NO_EXPRESSION "No expression to evaluate."
|
||||
#define STRING_EVAL_NO_EXPRESSION "Ninguna expresión para evaluar."
|
||||
#define STRING_EVAL_UNSUPPORTED "Operador no soportado '{1}'."
|
||||
#define STRING_EVAL_OP_EXPECTED "Operator expected."
|
||||
#define STRING_EVAL_NO_EVAL "The expression could not be evaluated."
|
||||
#define STRING_PAREN_MISMATCH "Mismatched parentheses in expression"
|
||||
#define STRING_EVAL_OP_EXPECTED "Se esperaba operador."
|
||||
#define STRING_EVAL_NO_EVAL "La expresión podría no ser evaluada."
|
||||
#define STRING_PAREN_MISMATCH "Paréntesis desemparejados en expresión"
|
||||
|
||||
// edit
|
||||
#define STRING_EDIT_NO_CHANGES "No se detectaron modificaciones."
|
||||
@@ -717,8 +711,6 @@
|
||||
|
||||
#define STRING_EDIT_PROJECT_MOD "Proyecto modificado."
|
||||
#define STRING_EDIT_PROJECT_DEL "Proyecto eliminado."
|
||||
#define STRING_EDIT_PRIORITY_MOD "Prioridad modificada."
|
||||
#define STRING_EDIT_PRIORITY_DEL "Prioridad eliminada."
|
||||
#define STRING_EDIT_DESC_MOD "Descripción modificada."
|
||||
#define STRING_EDIT_DESC_REMOVE_ERR "No se puede eliminar la descripción."
|
||||
#define STRING_EDIT_ENTRY_REMOVE_ERR "No se puede eliminar la fecha de creación."
|
||||
@@ -784,7 +776,7 @@
|
||||
#define STRING_INVALID_MOD "El atributo '{1}' no admite un valor '{2}'."
|
||||
#define STRING_INVALID_SORT_COL "La columna '{1}' no es un campo de ordenación válido."
|
||||
#define STRING_TLS_INIT_FAIL "Error inicializando TLS. {1}"
|
||||
#define STRING_ERROR_DETAILS "The setting 'calendar.details.report' must contain a single report name."
|
||||
#define STRING_ERROR_DETAILS "El ajuste 'calendar.details.report' debe contener un único nombre de informe."
|
||||
|
||||
// Feedback
|
||||
#define STRING_FEEDBACK_NO_TASKS "Ninguna tarea."
|
||||
@@ -821,22 +813,22 @@
|
||||
#define STRING_FILE_PERMS "Taskwarrior no tiene los permisos adecuados para '{1}'."
|
||||
|
||||
// helpers
|
||||
#define STRING_HELPER_PROJECT_CHANGE "The project '{1}' has changed."
|
||||
#define STRING_HELPER_PROJECT_COMPL "Project '{1}' is {2}% complete"
|
||||
#define STRING_HELPER_PROJECT_REM "({1} of {2} tasks remaining)."
|
||||
#define STRING_HELPER_PROJECT_REM1 "({1} task remaining)."
|
||||
#define STRING_HELPER_PROJECT_CHANGE "El proyecto '{1}' ha cambiado."
|
||||
#define STRING_HELPER_PROJECT_COMPL "El proyecto '{1}' está completado en un {2}%"
|
||||
#define STRING_HELPER_PROJECT_REM "({1} de {2} tareas restantes)."
|
||||
#define STRING_HELPER_PROJECT_REM1 "({1} tarea restante)."
|
||||
|
||||
// Hooks
|
||||
#define STRING_HOOK_ERROR_OBJECT "Hook Error: JSON Object '{...}' expected."
|
||||
#define STRING_HOOK_ERROR_NODESC "Hook Error: JSON Object missing 'description' attribute."
|
||||
#define STRING_HOOK_ERROR_NOUUID "Hook Error: JSON Object missing 'uuid' attribute."
|
||||
#define STRING_HOOK_ERROR_SYNTAX "Hook Error: JSON syntax error in: {1}"
|
||||
#define STRING_HOOK_ERROR_OBJECT "Hook Error: se esperaba 0bjeto JSON '{...}'."
|
||||
#define STRING_HOOK_ERROR_NODESC "Hook Error: falta atributo 'description' en objeto JSON."
|
||||
#define STRING_HOOK_ERROR_NOUUID "Hook Error: falta atributo 'uuid' en objeto JSON."
|
||||
#define STRING_HOOK_ERROR_SYNTAX "Hook Error: error de sintaxis JSON en: {1}"
|
||||
#define STRING_HOOK_ERROR_JSON "Hook Error: JSON "
|
||||
#define STRING_HOOK_ERROR_NOPARSE "Hook Error: JSON failed to parse: "
|
||||
#define STRING_HOOK_ERROR_BAD_NUM "Hook Error: Expected {1} JSON task(s), found {2}"
|
||||
#define STRING_HOOK_ERROR_SAME1 "Hook Error: JSON must be for the same task: {1}"
|
||||
#define STRING_HOOK_ERROR_SAME2 "Hook Error: JSON must be for the same task: {1} != {2}"
|
||||
#define STRING_HOOK_ERROR_NOFEEDBACK "Hook Error: Expected feedback from a failing hook script."
|
||||
#define STRING_HOOK_ERROR_NOPARSE "Hook Error: JSON falló al analizar: "
|
||||
#define STRING_HOOK_ERROR_BAD_NUM "Hook Error: se esperaba {1} tarea(s) JSON, se encontraron {2}"
|
||||
#define STRING_HOOK_ERROR_SAME1 "Hook Error: JSON debe ser para la misma tarea: {1}"
|
||||
#define STRING_HOOK_ERROR_SAME2 "Hook Error: JSON debe ser para la misma tarea: {1} != {2}"
|
||||
#define STRING_HOOK_ERROR_NOFEEDBACK "Hook Error: se esperaba retro-alimentación desde un hook script que falló."
|
||||
|
||||
// JSON
|
||||
#define STRING_JSON_MISSING_VALUE "Error: falta valor después de ',' en posición {1}"
|
||||
@@ -869,9 +861,9 @@
|
||||
#define STRING_CMD_SHOWRAW "Muestra todas las variables de configuración en un formato legible por la máquina"
|
||||
|
||||
// Task
|
||||
#define STRING_TASK_NO_FF1 "Taskwarrior ya no admite el formato de archivo 1, usado originalmente entre el 27 de noviembre del 2006 y el 31 de diciembre del 2007."
|
||||
#define STRING_TASK_NO_FF2 "Taskwarrior ya no admite el formato de archivo 2, usado originalmente entre el 1 de enero del 2008 y el 12 de abril del 2009."
|
||||
#define STRING_TASK_NO_FF3 "Taskwarrior no longer supports file format 3, originally used between 23 March 2009 and 16 May 2009."
|
||||
#define STRING_TASK_NO_FF1 "Taskwarrior ya no admite el formato de archivo 1, usado originalmente entre el 27 de noviembre de 2006 y el 31 de diciembre de 2007."
|
||||
#define STRING_TASK_NO_FF2 "Taskwarrior ya no admite el formato de archivo 2, usado originalmente entre el 1 de enero de 2008 y el 12 de abril de 2009."
|
||||
#define STRING_TASK_NO_FF3 "Taskwarrior ya no admite el formato de archivo 3, usado originalmente entre el 23 de marzo de 2009 y el 16 de mayo de 2009."
|
||||
#define STRING_TASK_PARSE_UNREC_FF "Formato de archivo taskwarrior no reconocido."
|
||||
#define STRING_TASK_DEPEND_ITSELF "Una tarea no puede depender de sí misma."
|
||||
#define STRING_TASK_DEPEND_MISS_CREA "No se pudo crear una dependencia de la tarea {1} - no encontrada."
|
||||
@@ -883,12 +875,11 @@
|
||||
#define STRING_TASK_VALID_BEFORE "Advertencia: ha especificado que la fecha '{1}' es después de la fecha '{2}'."
|
||||
#define STRING_TASK_VALID_REC_DUE "Una tarea recurrente debe tener también una fecha de vencimiento."
|
||||
#define STRING_TASK_VALID_RECUR "El valor de recurrencia '{1}' no es válido."
|
||||
#define STRING_TASK_VALID_PRIORITY "Valores de prioridad pueden ser 'H', 'M' o 'L', no '{1}'."
|
||||
#define STRING_TASK_SAFETY_VALVE "Este comando no tiene filtro, y modificará todas las tareas. ¿Está seguro?"
|
||||
#define STRING_TASK_SAFETY_FAIL "Se impidió la ejecución del comando."
|
||||
#define STRING_TASK_SAFETY_ALLOW "You did not specify a filter, and with the 'allow.empty.filter' value, no action is taken."
|
||||
#define STRING_TASK_INVALID_DUR "The duration value '{1}' is not supported."
|
||||
#define STRING_TASK_INVALID_COL_TYPE "Unrecognized column type '{1}' for column '{2}'"
|
||||
#define STRING_TASK_SAFETY_ALLOW "No especificó un filtro, y con el valor de 'allow.empty.filter', no se toma ninguna acción."
|
||||
#define STRING_TASK_INVALID_DUR "El valor de duración '{1}' no está soportado."
|
||||
#define STRING_TASK_INVALID_COL_TYPE "Tipo de columna no reconocido '{1}' para la columna '{2}'"
|
||||
|
||||
// TDB2
|
||||
#define STRING_TDB2_PARSE_ERROR " en {1} en la línea {2}"
|
||||
@@ -909,7 +900,7 @@
|
||||
#define STRING_TDB2_REMOVED "Tarea eliminada."
|
||||
#define STRING_TDB2_UNDO_COMPLETE "Deshacer completado."
|
||||
#define STRING_TDB2_UNDO_SYNCED "No se puede deshacer el cambio porque la tarea ya ha sido sincronizada. Como alternativa, modifique la tarea."
|
||||
#define STRING_TDB2_DIRTY_EXIT "Exiting with unwritten changes to {1}"
|
||||
#define STRING_TDB2_DIRTY_EXIT "Saliendo con cambios sin escribir a {1}"
|
||||
|
||||
// View
|
||||
#define STRING_VIEW_TOO_SMALL "El informe tiene una anchura mínima de {1} y no cabe en la disponible, que es {2}."
|
||||
@@ -1051,4 +1042,7 @@
|
||||
#define STRING_UTIL_KIBIBYTES "KiB" // |esp-ESP|==|eng-USA|
|
||||
#define STRING_UTIL_BYTES "B" // |esp-ESP|==|eng-USA|
|
||||
|
||||
// Legacy
|
||||
#define STRING_LEGACY_PRIORITY "Encontrado atributo anticuado. Por favor, cambie '{1}' a '{2}'."
|
||||
|
||||
#endif
|
||||
|
||||
@@ -172,13 +172,6 @@
|
||||
#define STRING_VARIANT_SQRT_NEG "Ne peut pas calculer la racine carrée d'un nombre négatif."
|
||||
#define STRING_VARIANT_COERCE_UNK "Cannot coerce data either to or from an unknown type"
|
||||
|
||||
// Lexer
|
||||
//
|
||||
// These are errors generated at the lowest level of input analysis,
|
||||
// at the character level.
|
||||
#define STRING_LEX_IMMEDIATE_UNK "Lexer start failure, unknown characters found immediately."
|
||||
#define STRING_LEX_TYPE_UNK "Lexer cannot process and unknown token type."
|
||||
|
||||
// Dates
|
||||
//
|
||||
// These are errors generated when parsing date values.
|
||||
@@ -204,8 +197,6 @@
|
||||
#define STRING_COLUMN_LABEL_ADDED "Ajoutée"
|
||||
#define STRING_COLUMN_LABEL_AGE "Age"
|
||||
#define STRING_COLUMN_LABEL_ID "ID"
|
||||
#define STRING_COLUMN_LABEL_PRI "Pri"
|
||||
#define STRING_COLUMN_LABEL_PRIORITY "Priorité"
|
||||
#define STRING_COLUMN_LABEL_PROJECT "Projet"
|
||||
#define STRING_COLUMN_LABEL_UNTIL "Until"
|
||||
#define STRING_COLUMN_LABEL_WAIT "Attente"
|
||||
@@ -567,6 +558,7 @@
|
||||
#define STRING_CMD_CONTEXT_DEF_FAIL "Context '{1}' not defined."
|
||||
#define STRING_CMD_CONTEXT_DEF_USAG "Both context name and its definition must be provided."
|
||||
#define STRING_CMD_CONTEXT_DEF_ABRT "Context definiton aborted."
|
||||
#define STRING_CMD_CONTEXT_DEF_ABRT2 "Filter validation failed: {1}"
|
||||
#define STRING_CMD_CONTEXT_DEF_CONF "The filter '{1}' matches 0 pending tasks. Do you wish to continue?"
|
||||
#define STRING_CMD_CONTEXT_DEL_SUCC "Context '{1}' deleted."
|
||||
#define STRING_CMD_CONTEXT_DEL_FAIL "Context '{1}' not deleted."
|
||||
@@ -707,8 +699,6 @@
|
||||
|
||||
#define STRING_EDIT_PROJECT_MOD "Projet modifié."
|
||||
#define STRING_EDIT_PROJECT_DEL "Projet supprimé."
|
||||
#define STRING_EDIT_PRIORITY_MOD "Priorité modifiée."
|
||||
#define STRING_EDIT_PRIORITY_DEL "Priorité supprimée."
|
||||
#define STRING_EDIT_DESC_MOD "Description modifiée."
|
||||
#define STRING_EDIT_DESC_REMOVE_ERR "Impossible de supprimer la description."
|
||||
#define STRING_EDIT_ENTRY_REMOVE_ERR "Impossible de supprimer la date de création."
|
||||
@@ -873,7 +863,6 @@
|
||||
#define STRING_TASK_VALID_BEFORE "Warning: You have specified that the '{1}' date is after the '{2}' date."
|
||||
#define STRING_TASK_VALID_REC_DUE "A recurring task must also have a 'due' date."
|
||||
#define STRING_TASK_VALID_RECUR "The recurrence value '{1}' is not valid."
|
||||
#define STRING_TASK_VALID_PRIORITY "Priority values may be 'H', 'M' or 'L', not '{1}'."
|
||||
#define STRING_TASK_SAFETY_VALVE "This command has no filter, and will modify all tasks. Are you sure?"
|
||||
#define STRING_TASK_SAFETY_FAIL "Command prevented from running."
|
||||
#define STRING_TASK_SAFETY_ALLOW "You did not specify a filter, and with the 'allow.empty.filter' value, no action is taken."
|
||||
@@ -1025,4 +1014,7 @@
|
||||
#define STRING_UTIL_KIBIBYTES "kio"
|
||||
#define STRING_UTIL_BYTES "o"
|
||||
|
||||
// Legacy
|
||||
#define STRING_LEGACY_PRIORITY "Legacy attribute found. Please change '{1}' to '{2}'."
|
||||
|
||||
#endif
|
||||
|
||||
@@ -172,13 +172,6 @@
|
||||
#define STRING_VARIANT_SQRT_NEG "Cannot take the square root of a negative number."
|
||||
#define STRING_VARIANT_COERCE_UNK "Cannot coerce data either to or from an unknown type"
|
||||
|
||||
// Lexer
|
||||
//
|
||||
// These are errors generated at the lowest level of input analysis,
|
||||
// at the character level.
|
||||
#define STRING_LEX_IMMEDIATE_UNK "Lexer start failure, unknown characters found immediately."
|
||||
#define STRING_LEX_TYPE_UNK "Lexer cannot process an unknown token type."
|
||||
|
||||
// Dates
|
||||
//
|
||||
// These are errors generated when parsing date values.
|
||||
@@ -204,8 +197,6 @@
|
||||
#define STRING_COLUMN_LABEL_ADDED "Aggiunto"
|
||||
#define STRING_COLUMN_LABEL_AGE "Età"
|
||||
#define STRING_COLUMN_LABEL_ID "ID"
|
||||
#define STRING_COLUMN_LABEL_PRI "Pri"
|
||||
#define STRING_COLUMN_LABEL_PRIORITY "Priorità"
|
||||
#define STRING_COLUMN_LABEL_PROJECT "Progetto"
|
||||
#define STRING_COLUMN_LABEL_UNTIL "Fino a"
|
||||
#define STRING_COLUMN_LABEL_WAIT "Attesa"
|
||||
@@ -707,8 +698,6 @@
|
||||
|
||||
#define STRING_EDIT_PROJECT_MOD "Progetto modificato."
|
||||
#define STRING_EDIT_PROJECT_DEL "Progetto cancellato."
|
||||
#define STRING_EDIT_PRIORITY_MOD "Progetto modificato."
|
||||
#define STRING_EDIT_PRIORITY_DEL "Priorità cancellata."
|
||||
#define STRING_EDIT_DESC_MOD "Descrizione modificata."
|
||||
#define STRING_EDIT_DESC_REMOVE_ERR "Impossibile rimuovere la descrizione."
|
||||
#define STRING_EDIT_ENTRY_REMOVE_ERR "Impossibile rimuovere la data di creazione."
|
||||
@@ -873,7 +862,6 @@
|
||||
#define STRING_TASK_VALID_BEFORE "Warning: data '{1}' con valore successivo alla data '{2}'."
|
||||
#define STRING_TASK_VALID_REC_DUE "Un task periodico deve avere una data di scadenza."
|
||||
#define STRING_TASK_VALID_RECUR "Il valore di periodicità '{1}' non è valido."
|
||||
#define STRING_TASK_VALID_PRIORITY "I valori di priorità possono essere 'H', 'M' o 'L', non '{1}'."
|
||||
#define STRING_TASK_SAFETY_VALVE "Questo comando non ha filtro, e modificherà tutti i task. Sicuro?"
|
||||
#define STRING_TASK_SAFETY_FAIL "Prevenuta l'esecuzione del comando."
|
||||
#define STRING_TASK_SAFETY_ALLOW "You did not specify a filter, and with the 'allow.empty.filter' value, no action is taken."
|
||||
@@ -1025,4 +1013,7 @@
|
||||
#define STRING_UTIL_KIBIBYTES "Kb"
|
||||
#define STRING_UTIL_BYTES "B"
|
||||
|
||||
// Legacy
|
||||
#define STRING_LEGACY_PRIORITY "Legacy attribute found. Please change '{1}' to '{2}'."
|
||||
|
||||
#endif
|
||||
|
||||
@@ -172,13 +172,6 @@
|
||||
#define STRING_VARIANT_SQRT_NEG "Nie można wyciągnąć pierwiastka kwadratowego z wartości ujemnej."
|
||||
#define STRING_VARIANT_COERCE_UNK "Nie można rzutować danych z/na nieznaney typ"
|
||||
|
||||
// Lexer
|
||||
//
|
||||
// These are errors generated at the lowest level of input analysis,
|
||||
// at the character level.
|
||||
#define STRING_LEX_IMMEDIATE_UNK "Nieudany start lexera, znaleziono niepoprawny symbol."
|
||||
#define STRING_LEX_TYPE_UNK "Lexer nie może przetworzyć nieznanego tokenu."
|
||||
|
||||
// Dates
|
||||
//
|
||||
// These are errors generated when parsing date values.
|
||||
@@ -204,8 +197,6 @@
|
||||
#define STRING_COLUMN_LABEL_ADDED "Dodane"
|
||||
#define STRING_COLUMN_LABEL_AGE "Wiek"
|
||||
#define STRING_COLUMN_LABEL_ID "ID"
|
||||
#define STRING_COLUMN_LABEL_PRI "Pri"
|
||||
#define STRING_COLUMN_LABEL_PRIORITY "Priorytet"
|
||||
#define STRING_COLUMN_LABEL_PROJECT "Projekt"
|
||||
#define STRING_COLUMN_LABEL_UNTIL "Do"
|
||||
#define STRING_COLUMN_LABEL_WAIT "Czeka"
|
||||
@@ -708,8 +699,6 @@
|
||||
|
||||
#define STRING_EDIT_PROJECT_MOD "Projekt zmieniony."
|
||||
#define STRING_EDIT_PROJECT_DEL "Projekt usunięty."
|
||||
#define STRING_EDIT_PRIORITY_MOD "Priorytet zmieniony."
|
||||
#define STRING_EDIT_PRIORITY_DEL "Priorytet usunięty."
|
||||
#define STRING_EDIT_DESC_MOD "Opis zmieniony."
|
||||
#define STRING_EDIT_DESC_REMOVE_ERR "Nie można usunąć opisu."
|
||||
#define STRING_EDIT_ENTRY_REMOVE_ERR "Nie można usunąć daty utworzenia."
|
||||
@@ -874,7 +863,6 @@
|
||||
#define STRING_TASK_VALID_BEFORE "Uwaga: podałeś datę '{1}' jako datę po '{2}'."
|
||||
#define STRING_TASK_VALID_REC_DUE "Zadanie cykliczne musi posiadać datę zakończenia."
|
||||
#define STRING_TASK_VALID_RECUR "Wartość '{1}' określająca okres zadania jest niepoprawna."
|
||||
#define STRING_TASK_VALID_PRIORITY "Poprawne wartości określające priorytet to 'H', 'M' lub 'L', nie '{1}'."
|
||||
#define STRING_TASK_SAFETY_VALVE "Nie nałożono filtra, wszystkie zadania zostaną poddane modyfikacji. Czy chcesz kontynuować?"
|
||||
#define STRING_TASK_SAFETY_FAIL "Niedopuszczono do wykonania polecenia."
|
||||
#define STRING_TASK_SAFETY_ALLOW "Brak filtra, z aktywną flagą 'allow.empty.filter', nie podjęto akcji."
|
||||
@@ -1026,4 +1014,7 @@
|
||||
#define STRING_UTIL_KIBIBYTES "KiB"
|
||||
#define STRING_UTIL_BYTES "B"
|
||||
|
||||
// Legacy
|
||||
#define STRING_LEGACY_PRIORITY "Legacy attribute found. Please change '{1}' to '{2}'."
|
||||
|
||||
#endif
|
||||
|
||||
@@ -172,13 +172,6 @@
|
||||
#define STRING_VARIANT_SQRT_NEG "Impossível calcular a raiz quadrada de um número negativo."
|
||||
#define STRING_VARIANT_COERCE_UNK "Impossível converter dados de ou para um tipo desconhecido"
|
||||
|
||||
// Lexer
|
||||
//
|
||||
// These are errors generated at the lowest level of input analysis,
|
||||
// at the character level.
|
||||
#define STRING_LEX_IMMEDIATE_UNK "Falha de parser lexical, caracteres desconhecidos encontrados imediatamente."
|
||||
#define STRING_LEX_TYPE_UNK "O parser lexical consegue processar tokens de tipo desconhecido."
|
||||
|
||||
// Dates
|
||||
//
|
||||
// These are errors generated when parsing date values.
|
||||
@@ -204,8 +197,6 @@
|
||||
#define STRING_COLUMN_LABEL_ADDED "Adicionada"
|
||||
#define STRING_COLUMN_LABEL_AGE "Idade"
|
||||
#define STRING_COLUMN_LABEL_ID "ID" // |por-PRT|==|eng-USA|
|
||||
#define STRING_COLUMN_LABEL_PRI "Pri" // |por-PRT|==|eng-USA|
|
||||
#define STRING_COLUMN_LABEL_PRIORITY "Prioridade"
|
||||
#define STRING_COLUMN_LABEL_PROJECT "Projeto"
|
||||
#define STRING_COLUMN_LABEL_UNTIL "Até"
|
||||
#define STRING_COLUMN_LABEL_WAIT "Adiada"
|
||||
@@ -708,8 +699,6 @@
|
||||
|
||||
#define STRING_EDIT_PROJECT_MOD "Projeto modificado."
|
||||
#define STRING_EDIT_PROJECT_DEL "Projeto removido."
|
||||
#define STRING_EDIT_PRIORITY_MOD "Prioridade modificada."
|
||||
#define STRING_EDIT_PRIORITY_DEL "Prioridade removida."
|
||||
#define STRING_EDIT_DESC_MOD "Descrição modificada."
|
||||
#define STRING_EDIT_DESC_REMOVE_ERR "Não é possível remover a descrição."
|
||||
#define STRING_EDIT_ENTRY_REMOVE_ERR "Não é possível remover a data de criação."
|
||||
@@ -874,7 +863,6 @@
|
||||
#define STRING_TASK_VALID_BEFORE "Aviso: Especificou que a data de '{1}' é posterior à data de '{2}'."
|
||||
#define STRING_TASK_VALID_REC_DUE "Uma tarefa recorrente necessita de uma data de vencimento."
|
||||
#define STRING_TASK_VALID_RECUR "O valor de recorrência '{1}' não é válido."
|
||||
#define STRING_TASK_VALID_PRIORITY "Valores de prioridade podem ser 'A', 'M' ou 'B', não '{1}'."
|
||||
#define STRING_TASK_SAFETY_VALVE "Este comando não possui um filtro e irá modificar todas as tarefas. Tem a certeza?"
|
||||
#define STRING_TASK_SAFETY_FAIL "Execução do comando abortada."
|
||||
#define STRING_TASK_SAFETY_ALLOW "Não especificou um filtro e com o valor de 'allow.empty.filter', nenhuma ação foi tomada."
|
||||
@@ -1026,4 +1014,7 @@
|
||||
#define STRING_UTIL_KIBIBYTES "KiB" // |por-PRT|==|eng-USA|
|
||||
#define STRING_UTIL_BYTES "B" // |por-PRT|==|eng-USA|
|
||||
|
||||
// Legacy
|
||||
#define STRING_LEGACY_PRIORITY "Legacy attribute found. Please change '{1}' to '{2}'."
|
||||
|
||||
#endif
|
||||
|
||||
@@ -54,6 +54,21 @@ void legacyColumnMap (std::string& name)
|
||||
// 2014-01-26: recurrence_indicator --> recur.indicator Mapping removed
|
||||
// 2014-01-26: tag_indicator --> tags.indicator Mapping removed
|
||||
// 2014-01-26: description_only --> description.desc Mapping removed
|
||||
|
||||
// One-time initialization, on demand.
|
||||
static std::map <std::string, std::string> legacyMap;
|
||||
if (! legacyMap.size ())
|
||||
{
|
||||
legacyMap["priority."] = "priority";
|
||||
}
|
||||
|
||||
// If a legacy column was used, complain about it, but modify it anyway.
|
||||
std::map <std::string, std::string>::iterator found = legacyMap.find (name);
|
||||
if (found != legacyMap.end ())
|
||||
{
|
||||
context.footnote (format (STRING_LEGACY_PRIORITY, name, found->second));
|
||||
name = found->second;
|
||||
}
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
@@ -71,6 +86,21 @@ void legacySortColumnMap (std::string& name)
|
||||
// 2014-01-26: recurrence_indicator --> recur Mapping removed
|
||||
// 2014-01-26: tag_indicator --> tags Mapping removed
|
||||
// 2014-01-26: description_only --> description Mapping removed
|
||||
|
||||
// One-time initialization, on demand.
|
||||
static std::map <std::string, std::string> legacyMap;
|
||||
if (! legacyMap.size ())
|
||||
{
|
||||
legacyMap["priority."] = "priority";
|
||||
}
|
||||
|
||||
// If a legacy column was used, complain about it, but modify it anyway.
|
||||
std::map <std::string, std::string>::iterator found = legacyMap.find (name);
|
||||
if (found != legacyMap.end ())
|
||||
{
|
||||
context.footnote (format (STRING_LEGACY_PRIORITY, name, found->second));
|
||||
name = found->second;
|
||||
}
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
31
src/lex.cpp
Normal file
31
src/lex.cpp
Normal file
@@ -0,0 +1,31 @@
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#include <iostream>
|
||||
#include <Lexer.h>
|
||||
#include <Context.h>
|
||||
|
||||
Context context;
|
||||
|
||||
int main (int argc, char** argv)
|
||||
{
|
||||
for (auto i = 1; i < argc; i++)
|
||||
{
|
||||
std::cout << "argument '" << argv[i] << "'\n";
|
||||
|
||||
// Low-level tokens.
|
||||
Lexer lexer (argv[i]);
|
||||
std::string token;
|
||||
Lexer::Type type;
|
||||
while (lexer.token (token, type))
|
||||
std::cout << " token '" << token << "' " << Lexer::typeToString (type) << "\n";
|
||||
|
||||
/*
|
||||
// High-level tokens.
|
||||
auto all = Lexer::tokens (argv[i]);
|
||||
for (auto token : Lexer::tokens (argv[i]))
|
||||
std::cout << " token '" << token.first << "' " << Lexer::typeToString (token.second) << "\n";
|
||||
*/
|
||||
}
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
@@ -40,6 +40,7 @@
|
||||
#include <Context.h>
|
||||
#include <Date.h>
|
||||
#include <Duration.h>
|
||||
#include <Lexer.h>
|
||||
#include <ISO8601.h>
|
||||
#include <text.h>
|
||||
#include <util.h>
|
||||
@@ -242,7 +243,7 @@ Date getNextRecurrence (Date& current, std::string& period)
|
||||
return current + (days * 86400);
|
||||
}
|
||||
|
||||
else if (isdigit (period[0]) && period[period.length () - 1] == 'm')
|
||||
else if (Lexer::isDigit (period[0]) && period[period.length () - 1] == 'm')
|
||||
{
|
||||
std::string numeric = period.substr (0, period.length () - 1);
|
||||
int increment = atoi (numeric.c_str ());
|
||||
@@ -275,7 +276,7 @@ Date getNextRecurrence (Date& current, std::string& period)
|
||||
return Date (m, d, y);
|
||||
}
|
||||
|
||||
else if (isdigit (period[0]) && period[period.length () - 1] == 'q')
|
||||
else if (Lexer::isDigit (period[0]) && period[period.length () - 1] == 'q')
|
||||
{
|
||||
std::string numeric = period.substr (0, period.length () - 1);
|
||||
int increment = atoi (numeric.c_str ());
|
||||
|
||||
@@ -111,34 +111,6 @@ static void colorizeTagged (Task& task, const Color& base, Color& c)
|
||||
c.blend (base);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
static void colorizePriorityL (Task& task, const Color& base, Color& c)
|
||||
{
|
||||
if (task.get ("priority") == "L")
|
||||
c.blend (base);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
static void colorizePriorityM (Task& task, const Color& base, Color& c)
|
||||
{
|
||||
if (task.get ("priority") == "M")
|
||||
c.blend (base);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
static void colorizePriorityH (Task& task, const Color& base, Color& c)
|
||||
{
|
||||
if (task.get ("priority") == "H")
|
||||
c.blend (base);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
static void colorizePriorityNone (Task& task, const Color& base, Color& c)
|
||||
{
|
||||
if (task.get ("priority") == "")
|
||||
c.blend (base);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
static void colorizeActive (Task& task, const Color& base, Color& c)
|
||||
{
|
||||
@@ -329,10 +301,6 @@ void autoColorize (Task& task, Color& c)
|
||||
if (*r == "color.blocked") colorizeBlocked (task, base, c);
|
||||
else if (*r == "color.blocking") colorizeBlocking (task, base, c);
|
||||
else if (*r == "color.tagged") colorizeTagged (task, base, c);
|
||||
else if (*r == "color.pri.L") colorizePriorityL (task, base, c);
|
||||
else if (*r == "color.pri.M") colorizePriorityM (task, base, c);
|
||||
else if (*r == "color.pri.H") colorizePriorityH (task, base, c);
|
||||
else if (*r == "color.pri.none") colorizePriorityNone (task, base, c);
|
||||
else if (*r == "color.active") colorizeActive (task, base, c);
|
||||
else if (*r == "color.scheduled") colorizeScheduled (task, base, c);
|
||||
else if (*r == "color.until") colorizeUntil (task, base, c);
|
||||
|
||||
149
src/sort.cpp
149
src/sort.cpp
@@ -30,6 +30,7 @@
|
||||
#include <string>
|
||||
#include <stdlib.h>
|
||||
#include <Context.h>
|
||||
#include <Variant.h>
|
||||
#include <Duration.h>
|
||||
#include <Task.h>
|
||||
#include <text.h>
|
||||
@@ -67,6 +68,7 @@ void sort_tasks (
|
||||
// require re-parsing.
|
||||
//
|
||||
// Essentially a static implementation of a dynamic operator<.
|
||||
// UDA string values delegate to Variant::operator<.
|
||||
static bool sort_compare (int left, int right)
|
||||
{
|
||||
std::string field;
|
||||
@@ -77,8 +79,6 @@ static bool sort_compare (int left, int right)
|
||||
int right_number;
|
||||
float left_real;
|
||||
float right_real;
|
||||
char left_char;
|
||||
char right_char;
|
||||
|
||||
std::vector <std::string>::iterator k;
|
||||
for (k = global_keys.begin (); k != global_keys.end (); ++k)
|
||||
@@ -111,6 +111,64 @@ static bool sort_compare (int left, int right)
|
||||
: (left_number > right_number);
|
||||
}
|
||||
|
||||
// String.
|
||||
else if (field == "description" ||
|
||||
field == "project" ||
|
||||
field == "status" ||
|
||||
field == "tags" ||
|
||||
field == "uuid" ||
|
||||
field == "parent" ||
|
||||
field == "imask" ||
|
||||
field == "mask")
|
||||
{
|
||||
const std::string& left_string = (*global_data)[left].get_ref (field);
|
||||
const std::string& right_string = (*global_data)[right].get_ref (field);
|
||||
|
||||
if (left_string == right_string)
|
||||
continue;
|
||||
|
||||
return ascending ? (left_string < right_string)
|
||||
: (left_string > right_string);
|
||||
}
|
||||
|
||||
// Due Date.
|
||||
else if (field == "due")
|
||||
{
|
||||
const std::string& left_string = (*global_data)[left].get_ref (field);
|
||||
const std::string& right_string = (*global_data)[right].get_ref (field);
|
||||
|
||||
if (left_string != "" && right_string == "")
|
||||
return true;
|
||||
|
||||
if (left_string == "" && right_string != "")
|
||||
return false;
|
||||
|
||||
if (left_string == right_string)
|
||||
continue;
|
||||
|
||||
return ascending ? (left_string < right_string)
|
||||
: (left_string > right_string);
|
||||
}
|
||||
|
||||
// Date.
|
||||
else if (field == "end" ||
|
||||
field == "entry" ||
|
||||
field == "start" ||
|
||||
field == "until" ||
|
||||
field == "wait" ||
|
||||
field == "modified" ||
|
||||
field == "scheduled")
|
||||
{
|
||||
const std::string& left_string = (*global_data)[left].get_ref (field);
|
||||
const std::string& right_string = (*global_data)[right].get_ref (field);
|
||||
|
||||
if (left_string == right_string)
|
||||
continue;
|
||||
|
||||
return ascending ? (left_string < right_string)
|
||||
: (left_string > right_string);
|
||||
}
|
||||
|
||||
// Depends string.
|
||||
else if (field == "depends")
|
||||
{
|
||||
@@ -138,78 +196,6 @@ static bool sort_compare (int left, int right)
|
||||
: (left_number > right_number);
|
||||
}
|
||||
|
||||
// String.
|
||||
else if (field == "description" ||
|
||||
field == "project" ||
|
||||
field == "status" ||
|
||||
field == "tags" ||
|
||||
field == "uuid")
|
||||
{
|
||||
const std::string& left_string = (*global_data)[left].get_ref (field);
|
||||
const std::string& right_string = (*global_data)[right].get_ref (field);
|
||||
|
||||
if (left_string == right_string)
|
||||
continue;
|
||||
|
||||
return ascending ? (left_string < right_string)
|
||||
: (left_string > right_string);
|
||||
}
|
||||
|
||||
// Priority.
|
||||
else if (field == "priority")
|
||||
{
|
||||
left_char = ((*global_data)[left].get (field))[0];
|
||||
right_char = ((*global_data)[right].get (field))[0];
|
||||
|
||||
if (left_char == right_char)
|
||||
continue;
|
||||
|
||||
if (ascending)
|
||||
return (left_char == '\0' && right_char != '\0') ||
|
||||
(left_char == 'L' && (right_char == 'M' || right_char == 'H')) ||
|
||||
(left_char == 'M' && right_char == 'H');
|
||||
|
||||
return (left_char != '\0' && right_char == '\0') ||
|
||||
(left_char == 'M' && right_char == 'L') ||
|
||||
(left_char == 'H' && (right_char == 'M' || right_char == 'L'));
|
||||
}
|
||||
|
||||
// Due Date.
|
||||
else if (field == "due")
|
||||
{
|
||||
const std::string& left_string = (*global_data)[left].get_ref (field);
|
||||
const std::string& right_string = (*global_data)[right].get_ref (field);
|
||||
|
||||
if (left_string != "" && right_string == "")
|
||||
return true;
|
||||
|
||||
if (left_string == "" && right_string != "")
|
||||
return false;
|
||||
|
||||
if (left_string == right_string)
|
||||
continue;
|
||||
|
||||
return ascending ? (left_string < right_string)
|
||||
: (left_string > right_string);
|
||||
}
|
||||
|
||||
// Date.
|
||||
else if (field == "end" ||
|
||||
field == "entry" ||
|
||||
field == "start" ||
|
||||
field == "until" ||
|
||||
field == "wait")
|
||||
{
|
||||
const std::string& left_string = (*global_data)[left].get_ref (field);
|
||||
const std::string& right_string = (*global_data)[right].get_ref (field);
|
||||
|
||||
if (left_string == right_string)
|
||||
continue;
|
||||
|
||||
return ascending ? (left_string < right_string)
|
||||
: (left_string > right_string);
|
||||
}
|
||||
|
||||
// Duration.
|
||||
else if (field == "recur")
|
||||
{
|
||||
@@ -240,16 +226,19 @@ static bool sort_compare (int left, int right)
|
||||
return ascending ? (left_real < right_real)
|
||||
: (left_real > right_real);
|
||||
}
|
||||
// UDA values of type 'string' are sorted by Variant::operator<.
|
||||
// By setting 'source' to the UDA name, the comparison operator can use
|
||||
// the custom sort order, if defined.
|
||||
else if (type == "string")
|
||||
{
|
||||
const std::string& left_string = (*global_data)[left].get_ref (field);
|
||||
const std::string& right_string = (*global_data)[right].get_ref (field);
|
||||
|
||||
if (left_string == right_string)
|
||||
Variant l ((*global_data)[left].get_ref (field));
|
||||
Variant r ((*global_data)[right].get_ref (field));
|
||||
if (l == r)
|
||||
continue;
|
||||
|
||||
return ascending ? (left_string < right_string)
|
||||
: (left_string > right_string);
|
||||
l.source (field);
|
||||
r.source (field);
|
||||
return ascending ? (l < r) : (r < l);
|
||||
}
|
||||
else if (type == "date")
|
||||
{
|
||||
|
||||
52
src/text.cpp
52
src/text.cpp
@@ -32,7 +32,6 @@
|
||||
#include <vector>
|
||||
#include <string>
|
||||
#include <strings.h>
|
||||
#include <ctype.h>
|
||||
#include <Context.h>
|
||||
#include <Lexer.h>
|
||||
#include <math.h>
|
||||
@@ -351,7 +350,7 @@ std::string commify (const std::string& data)
|
||||
int i;
|
||||
for (int i = 0; i < (int) data.length (); ++i)
|
||||
{
|
||||
if (isdigit (data[i]))
|
||||
if (Lexer::isDigit (data[i]))
|
||||
end = i;
|
||||
|
||||
if (data[i] == '.')
|
||||
@@ -369,11 +368,11 @@ std::string commify (const std::string& data)
|
||||
int consecutiveDigits = 0;
|
||||
for (; i >= 0; --i)
|
||||
{
|
||||
if (isdigit (data[i]))
|
||||
if (Lexer::isDigit (data[i]))
|
||||
{
|
||||
result += data[i];
|
||||
|
||||
if (++consecutiveDigits == 3 && i && isdigit (data[i - 1]))
|
||||
if (++consecutiveDigits == 3 && i && Lexer::isDigit (data[i - 1]))
|
||||
{
|
||||
result += ',';
|
||||
consecutiveDigits = 0;
|
||||
@@ -393,11 +392,11 @@ std::string commify (const std::string& data)
|
||||
int consecutiveDigits = 0;
|
||||
for (; i >= 0; --i)
|
||||
{
|
||||
if (isdigit (data[i]))
|
||||
if (Lexer::isDigit (data[i]))
|
||||
{
|
||||
result += data[i];
|
||||
|
||||
if (++consecutiveDigits == 3 && i && isdigit (data[i - 1]))
|
||||
if (++consecutiveDigits == 3 && i && Lexer::isDigit (data[i - 1]))
|
||||
{
|
||||
result += ',';
|
||||
consecutiveDigits = 0;
|
||||
@@ -473,49 +472,12 @@ bool nontrivial (const std::string& input)
|
||||
std::string::size_type i = 0;
|
||||
int character;
|
||||
while ((character = utf8_next_char (input, i)))
|
||||
if (! Lexer::is_ws (character))
|
||||
if (! Lexer::isWhitespace (character))
|
||||
return true;
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
bool digitsOnly (const std::string& input)
|
||||
{
|
||||
for (size_t i = 0; i < input.length (); ++i)
|
||||
if (!isdigit (input[i]))
|
||||
return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
bool noSpaces (const std::string& input)
|
||||
{
|
||||
std::string::size_type i = 0;
|
||||
int character;
|
||||
while ((character = utf8_next_char (input, i)))
|
||||
if (Lexer::is_ws (character))
|
||||
return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
// Override of ispunct, that considers #, $ and @ not to be punctuation.
|
||||
//
|
||||
// ispunct: ! " # $ % & ' ( ) * + , - . / : ; < = > ? @ [ \ ] ^ _ ` { | } ~
|
||||
// Punctuation: ! " % & ' ( ) * + , - . / : ; < = > ? [ \ ] ^ _ ` { | } ~
|
||||
// delta: # $ @
|
||||
//
|
||||
bool isPunctuation (char c)
|
||||
{
|
||||
if (c == '@' || c == '#' || c == '$')
|
||||
return false;
|
||||
|
||||
return ispunct (c);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
bool compare (
|
||||
const std::string& left,
|
||||
@@ -978,7 +940,7 @@ std::string rightJustify (const int input, const int width)
|
||||
std::string rightJustify (const std::string& input, const int width)
|
||||
{
|
||||
unsigned int len = utf8_text_width (input);
|
||||
return ((width > len)
|
||||
return (((unsigned int) width > len)
|
||||
? std::string (width - len, ' ')
|
||||
: "")
|
||||
+ input;
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user