diff --git a/.github/issue_template.md b/.github/issue_template.md new file mode 100644 index 000000000..b65581ad7 --- /dev/null +++ b/.github/issue_template.md @@ -0,0 +1,12 @@ +#### To report a bug... + +* What command(s) did you run? +* What did you expect to happen? +* What actually happened? +* Paste the output of the ```task diag``` command. + +#### To request a feature... + +* Clearly describe the feature. +* Clearly state the use case. We are only interested in use cases, do not waste time with implementation details or suggested syntax. +* Please see our notes on [How to request a feature](https://taskwarrior.org/docs/features.html) diff --git a/.github/pull_request_template.md b/.github/pull_request_template.md new file mode 100644 index 000000000..43476299b --- /dev/null +++ b/.github/pull_request_template.md @@ -0,0 +1,9 @@ +#### Description + +Replace this text with a description of the PR. + +#### Additional information... + +- [ ] Have you run the test suite? + Many changes need to be tested. Please run the test suite + and include the output of ```cd test && ./problems```. diff --git a/.gitignore b/.gitignore index 3ba2ade24..03300d5c8 100644 --- a/.gitignore +++ b/.gitignore @@ -19,3 +19,4 @@ CPackSourceConfig.cmake patches *.exe tutorials +.prove diff --git a/.gitmodules b/.gitmodules new file mode 100644 index 000000000..fed3de512 --- /dev/null +++ b/.gitmodules @@ -0,0 +1,3 @@ +[submodule "src/libshared"] + path = src/libshared + url = https://github.com/GothenburgBitFactory/libshared.git diff --git a/.travis.yml b/.travis.yml new file mode 100644 index 000000000..b72147f9e --- /dev/null +++ b/.travis.yml @@ -0,0 +1,49 @@ +sudo: required +language: generic +matrix: + include: + - name: "Centos 7" + os: linux + env: CONTAINER=centos7 + services: docker + - name: "Fedora 28" + os: linux + env: CONTAINER=fedora28 + services: docker + - name: "Fedora 29" + os: linux + env: CONTAINER=fedora28 + services: docker + - name: "Debian Stable" + os: linux + env: CONTAINER=debianstable + services: docker + - name: "Debian Testing" + os: linux + env: CONTAINER=debiantesting + services: docker + - name: "Ubuntu 16.04" + os: linux + env: CONTAINER=ubuntu1604 + services: docker + - name: "Ubuntu 18.04" + os: linux + env: CONTAINER=ubuntu1804 + services: docker + - name: "OpenSUSE 15.0" + os: linux + env: CONTAINER=opensuse1500 + services: docker + - name: "Archlinux 2018.01.01" + os: linux + env: CONTAINER=arch180101 + services: docker + - name: "Mac OS X 10.13" + os: osx + env: CONTAINER=osx +install: + # Build the docker container + - pushd $TRAVIS_BUILD_DIR + - if [[ $CONTAINER != "osx" ]]; then docker-compose build test-$CONTAINER ; fi +script: + - if [[ $CONTAINER != "osx" ]]; then docker-compose run test-$CONTAINER; else bash test/scripts/test_osx.sh ; fi diff --git a/AUTHORS b/AUTHORS index 32b8d3752..7e85d72c1 100644 --- a/AUTHORS +++ b/AUTHORS @@ -126,7 +126,33 @@ The following submitted code, packages or analysis, and deserve special thanks: Sunil Joshi Misty De Meo Kent R. Spillner - Konstantin + Konstantin Vorobyev + Tom Sydney Kerckhove + Lynoure Braakman + Sebastien Badia + Ran Benita + Vladimir + Zachary Manning + jrabbit + Jelle van der Waa + Flavio Poletti + Antonio Huete Jimenez + Lukas Barth + Øyvind A. Holm + Paul J. Fenwick + Michael Neumann + Mark Scannell + buhtz + Tiago Matias + Simon Ruderich + Kirill Bobyrev + Simon Désaulniers + Janik Rabe + mrossinek + taiyu-len + Lionel Miller + Chad Phillips + Lionel Miller Thanks to the following, who submitted detailed bug reports and excellent suggestions: @@ -274,7 +300,6 @@ suggestions: James Cline Ryan Simon W. Jackson - Sebastien Badia Michale Meier Svetoslav Trochev Marc Cornellà @@ -288,3 +313,28 @@ suggestions: pawprint Reg Yaroslav Molochko + Michael Meier + Slaven ʙanovic + Ellington Santos + george js + E. Manuel Cerr'on Angeles + Andrew + bjonnh + OKOMper + eldios + Eli + Sergey Trofimov + eezewaek + Hubert Toullec + Eric Hymowitz + Dan Callahan + Martin Strunz + Kai HTML + Marc Richter + rjc + php-coder + Martin F. Krafft + tom-doerr + ad-si + Adrien Lemaire + Wray Zheng diff --git a/CMakeLists.txt b/CMakeLists.txt index e96e0a64b..08a30d95f 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -1,5 +1,5 @@ -cmake_minimum_required (VERSION 2.8) -set(CMAKE_LEGACY_CYGWIN_WIN32 0) # Remove when CMake >= 2.8.4 is required +cmake_minimum_required (VERSION 3.0) +set (CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH} "${CMAKE_SOURCE_DIR}/cmake") include (CheckFunctionExists) include (CheckStructHasMember) @@ -7,7 +7,15 @@ include (CheckStructHasMember) set (HAVE_CMAKE true) project (task) -set (PROJECT_VERSION "2.5.1") +set (PROJECT_VERSION "2.5.2") +include (CXXSniffer) + +OPTION (ENABLE_WASM "Enable 'wasm' support" OFF) + +if (ENABLE_WASM) + message ("Enabling WASM support.") + set(CMAKE_EXECUTABLE_SUFFIX ".js") +endif (ENABLE_WASM) OPTION (ENABLE_SYNC "Enable 'task sync' support" ON) @@ -18,81 +26,14 @@ else (ENABLE_SYNC) message (WARNING "ENABLE_SYNC=OFF. Not building sync support.") endif (ENABLE_SYNC) -message ("CMAKE_SYSTEM_NAME ${CMAKE_SYSTEM_NAME}") - -include (CheckCXXCompilerFlag) - -# NOTE: If we are to actually use C++11 features, we should either require -# a compiler that supports the -std=c++11 flag or check for the -# features used. -# Relying on -std=c++0x or even -std=gnu++0x is highly volatile. - -CHECK_CXX_COMPILER_FLAG("-std=c++11" _HAS_CXX11) -CHECK_CXX_COMPILER_FLAG("-std=c++0x" _HAS_CXX0X) -CHECK_CXX_COMPILER_FLAG("-std=gnu++0x" _HAS_GNU0X) - -if (_HAS_CXX11) - set (_CXX11_FLAGS "-std=c++11") -elseif (_HAS_CXX0X) - message (WARNING "Enabling -std=c++0x draft compile flag. Your compiler does not support the standard '-std=c++11' option. Consider upgrading.") - set (_CXX11_FLAGS "-std=c++0x") -elseif (_HAS_GNU0X) - message (WARNING "Enabling -std=gnu++0x draft compile flag. Your compiler does not support the standard '-std=c++11' option. Consider upgrading.") - set (_CXX11_FLAGS "-std=gnu++0x") -else (_HAS_CXX11) - message (FATAL_ERROR "C++11 support missing. Try upgrading your C++ compiler. If you have a good reason for using an outdated compiler, please let us know at support@taskwarrior.org.") -endif (_HAS_CXX11) - -if (${CMAKE_CXX_COMPILER_ID} STREQUAL "Clang") - set (_CXX11_FLAGS "${_CXX11_FLAGS} -stdlib=libc++") -endif (${CMAKE_CXX_COMPILER_ID} STREQUAL "Clang") - -if (${CMAKE_SYSTEM_NAME} MATCHES "Linux") - set (LINUX true) -elseif (${CMAKE_SYSTEM_NAME} MATCHES "Darwin") - set (DARWIN true) -elseif (${CMAKE_SYSTEM_NAME} MATCHES "kFreeBSD") - set (KFREEBSD true) -elseif (${CMAKE_SYSTEM_NAME} MATCHES "FreeBSD") - set (FREEBSD true) -elseif (${CMAKE_SYSTEM_NAME} MATCHES "OpenBSD") - set (OPENBSD true) -elseif (${CMAKE_SYSTEM_NAME} MATCHES "NetBSD") - set (NETBSD true) -elseif (${CMAKE_SYSTEM_NAME} MATCHES "SunOS") - set (SOLARIS true) -elseif (${CMAKE_SYSTEM_NAME} STREQUAL "GNU") - set (GNUHURD true) -elseif (${CMAKE_SYSTEM_NAME} STREQUAL "CYGWIN") - set (CYGWIN true) - # NOTE: Not setting -std=gnu++0x leads to compile errors even with - # GCC 4.8.3, and debugging those leads to insanity. Adding this - # workaround instead of fixing Cygwin. - set (_CXX11_FLAGS "-std=gnu++0x") -else (${CMAKE_SYSTEM_NAME} MATCHES "Linux") - set (UNKNOWN true) -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 - set (CMAKE_INSTALL_RPATH_USE_LINK_PATH TRUE) -endif (NETBSD) - -if (FREEBSD) -SET (TASK_MAN1DIR man/man1 CACHE STRING "Installation directory for man pages, section 1") -SET (TASK_MAN5DIR man/man5 CACHE STRING "Installation directory for man pages, section 5") -else (FREEBSD) -SET (TASK_MAN1DIR share/man/man1 CACHE STRING "Installation directory for man pages, section 1") -SET (TASK_MAN5DIR share/man/man5 CACHE STRING "Installation directory for man pages, section 5") -endif (FREEBSD) -SET (TASK_DOCDIR share/doc/task CACHE STRING "Installation directory for doc files") -SET (TASK_RCDIR "${TASK_DOCDIR}/rc" CACHE STRING "Installation directory for configuration files") -SET (TASK_BINDIR bin CACHE STRING "Installation directory for the binary") +message ("-- Looking for libshared") +if (EXISTS ${CMAKE_SOURCE_DIR}/src/libshared/.git) + message ("-- Found libshared") +else (EXISTS ${CMAKE_SOURCE_DIR}/src/libshared/.git) + message ("-- Cloning libshared") + execute_process (COMMAND git submodule update --init + WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}) +endif (EXISTS ${CMAKE_SOURCE_DIR}/src/libshared/.git) message ("-- Looking for SHA1 references") if (EXISTS ${CMAKE_SOURCE_DIR}/.git/index) @@ -107,12 +48,23 @@ endif (EXISTS ${CMAKE_SOURCE_DIR}/.git/index) set (PACKAGE "${PROJECT_NAME}") set (VERSION "${PROJECT_VERSION}") -set (PACKAGE_BUGREPORT "support@taskwarrior.org") +set (PACKAGE_BUGREPORT "support@gothenburgbitfactory.org") set (PACKAGE_NAME "${PACKAGE}") set (PACKAGE_TARNAME "${PACKAGE}") set (PACKAGE_VERSION "${VERSION}") set (PACKAGE_STRING "${PACKAGE} ${VERSION}") +if (FREEBSD OR DRAGONFLY) +SET (TASK_MAN1DIR man/man1 CACHE STRING "Installation directory for man pages, section 1") +SET (TASK_MAN5DIR man/man5 CACHE STRING "Installation directory for man pages, section 5") +else (FREEBSD OR DRAGONFLY) +SET (TASK_MAN1DIR share/man/man1 CACHE STRING "Installation directory for man pages, section 1") +SET (TASK_MAN5DIR share/man/man5 CACHE STRING "Installation directory for man pages, section 5") +endif (FREEBSD OR DRAGONFLY) +SET (TASK_DOCDIR share/doc/task CACHE STRING "Installation directory for doc files") +SET (TASK_RCDIR "${TASK_DOCDIR}/rc" CACHE STRING "Installation directory for configuration files") +SET (TASK_BINDIR bin CACHE STRING "Installation directory for the binary") + if (USE_GNUTLS) message ("-- Looking for GnuTLS") find_package (GnuTLS) @@ -159,22 +111,25 @@ else (HAVE_UUID_UNPARSE_LOWER) message ("-- Found libuuid, using internal uuid_unparse_lower") endif (HAVE_UUID_UNPARSE_LOWER) -# Set the package language. -if (LANGUAGE) - set (PACKAGE_LANGUAGE ${LANGUAGE}) -else (LANGUAGE) - set (PACKAGE_LANGUAGE 1) -endif (LANGUAGE) +if (SOLARIS) + # accept() is in libsocket according to its manpage + message("-- Looking for libsocket") + find_library (SOCKET_LIBRARY NAMES socket) + if (SOCKET_LIBRARY) + set (TASK_LIBRARIES ${TASK_LIBRARIES} ${SOCKET_LIBRARY}) + else (SOCKET_LIBRARY) + message(FATAL_ERROR "-- libsocket not found.") + endif (SOCKET_LIBRARY) -set (LANGUAGE_ENG_USA 1) -set (LANGUAGE_ESP_ESP 2) -set (LANGUAGE_DEU_DEU 3) -set (LANGUAGE_FRA_FRA 4) -set (LANGUAGE_ITA_ITA 5) -set (LANGUAGE_POR_PRT 6) -set (LANGUAGE_EPO_RUS 7) -set (LANGUAGE_POL_POL 8) -set (LANGUAGE_JPN_JPN 9) + # inet_ntop() is in libnsl according to its manpage + message("-- Looking for libnsl") + find_library (NSL_LIBRARY NAMES nsl) + if (NSL_LIBRARY) + set (TASK_LIBRARIES ${TASK_LIBRARIES} ${NSL_LIBRARY}) + else (NSL_LIBRARY) + message(FATAL_ERROR "-- libnsl not found.") + endif (NSL_LIBRARY) +endif (SOLARIS) message ("-- Configuring cmake.h") configure_file ( @@ -206,5 +161,5 @@ set (CPACK_SOURCE_IGNORE_FILES "CMakeCache" "CMakeFiles" "CPackConfig" "CPackSo "_CPack_Packages" "cmake_install" "install_manifest" "Makefile$" "test" "package-config" "misc/*" "src/task$" "src/calc$" "performance" "src/libtask.a" "src/columns/libcolumns.a" "src/commands/libcommands.a" - "/\\\\.gitignore" "/\\\\.git/" "swp$" "src/lex$") + ".github/" ".travis.yml" "/\\\\.gitignore" "/\\\\.git/" "swp$" "src/lex$") include (CPack) diff --git a/COPYING b/COPYING index a518570b0..2f43e0f23 100644 --- a/COPYING +++ b/COPYING @@ -1,6 +1,6 @@ Taskwarrior - a command line task list manager. -Copyright 2006 - 2016, Paul Beckingham, Federico Hernandez. +Copyright 2006 - 2020, 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 @@ -20,4 +20,4 @@ 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 +https://www.opensource.org/licenses/mit-license.php diff --git a/ChangeLog b/ChangeLog index bc2164ccb..face46372 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,159 @@ +2.5.2 () - + +- TD-64 sync conflict deleted all annotations of the task + Thanks to Markus Beppler, Konstantin Vorobyev +- TI-91 Timewarrior does not compile on DragonFly + Thanks to Michael Neumann +- TW #1 URL formating + Thanks to buhtz +- TW #2 Update to markdown and rename DEVELOPER to DEVELOPER.md + Thanks to Lynoure Braakman +- TW-54/#115 Reduce output for timesheet + Thanks to Aikido guy +- TW-61 Extract only tasks with annotations + Thanks to Aikido Guy +- TW-213 Align countdown column on boundary between number and text. + Thanks to Eric Fluger +- TW-1572 Alternative approach to urgency inheritance + Thanks to Jens Erat, Wim Schuermann +- TW-1667 hooks: upon failure indicate which hook failed + Thanks to Daniel Shahaf +- TW-1785 Purge command to remove deleted tasks + Thanks to Paul Beckingham +- TW-1772 Implementation of circular dependency detection is inefficient + Thanks to Michael Meier +- TW-1778 Unicode strings are truncated in task description + Thanks to Andrew, bjonnh, OKOMPer, Vladimir +- TW-1788 Closing a reopened task does not update the end time + Thanks to Ralph Bean +- TW-1791 taskrc(5) manpage: spurious "pri." in rule.precedence.color + Thanks to Sebastien Badia +- TW-1792 The info command uses '0' to reference dependencies on non- + pending tasks. +- TW-1795 Calendar underline on Day padding + Thanks to Renato Alves +- TW-1805 project:ide is not allowed + Thanks to Slaven ʙanovic +- TW-1807 dateformat lacks a flag to display day of week + Thanks to Ellington Santos +- TW-1813 Range filter doesn't work + Thanks to george js +- TW-1820 Install with -DLANGUAGE=2 flag not work. + Thanks to E. Manuel Cerr'on Angeles +- TW-1823 Incorrect unicode text wrapping / justifying. + Thanks to Sergey Trofimov +- TW-1827 Extract annotations from a task + Thanks to Ryan +- TW-1855 "Well-known" CA certificates not properly auto-loaded + Thanks to Flavio Poletti +- TW-1857 Change Task::get call to the more efficient Task::has + Thanks to Zachary Manning +- TW‐1858 Change signature for dependencyGetBlocked +- TW-1859 Change signature of Task::getTags +- TW-1860 Change signature of Task::getAnnotations +- TW-1861 Truncated description when adding annotation + Thanks to eezewaek +- TW-1869 segmentation fault (on unusual installation) + Thanks to Eric Hymowitz +- TW-1873 Specify different path to extensions/hooks directory + Thanks to Eli +- TW-1877 task done, task edit, task is now pending + Thanks to Eric Hymowitz +- TW-1878 uuids subcommand produces a space-delimited list, not comma-delimited + Thanks to Scott Kostyshak +- TW-1881 Missing last character(s) in Description field + Thanks to Hubert Toullec +- TW-1881 default.scheduled seems not to work + Thanks to Onion +- TW-1885 Task Sync does not send TLS SNI headers + Thanks to Dan Callahan +- TW-1903 grammar error -- There are 1 local changes. + Thanks to Eric Hymowitz +- TW-1906/#1919 sync sub-command is missing from task(1) manual page + Thanks to rjc +- TW-1910 unreachable statement + Thanks to Martin Strunz +- TW-1917/#1930 "above" does a string comparison, even when the value is numeric + Thanks to Dirk Deimeke +- TW-1930 Typo in help + Thanks to Kai HTML +- TW-1935 Separate verbosity category for rc overrides + Thanks to Paul J. Fenwick +- TW-1936 Tweak tests to have fuller TAP compliance + Thanks to Paul J. Fenwick +- TW-1938 Adjust behaviour of new-uuid and new-id verbosity levels + Thanks to Paul J. Fenwick +- TW-1947 "urgency.over" filter seems to not work correct + Thanks to Marc Richter +- TW #1964 task burndown shows extra brackets #1964 + Thanks to php-coder +- TW #1966 Tests: Don't hardcode errno constants #1966 + Thanks to Jakub Wilk +- TW #1973 Don't nag when no tasks are READY + Thanks to Martin F. Krafft +- TW #1986 [Nit] Update DEVELOPER.md after migration to Github + Thanks to Kirill Bobyrev +- TW #1922 Can't find export scripts + Thanks to tom-doerr +- TW #2020 reserved.lines is not affecting the burndown height + Thanks to ad₋si +- TW #2047 Exiting the task editor with an error code doesn't remove the lock file + Thanks to coaxial +- TW #2051 doc/man: ready tasks sorted with started tasks 1st + Thanks to Simon Désaulniers +- TW #2053 Do not set CMP0037 on CMake 3.11.0 and above + Thanks to Janik Rabe +- #2077 Change taskrc override priority, respect verbose override, refactor. + Thanks to taiyu-len +- #2108 CmdHistory: repeat unit if a larger unit changes + Thanks to Janik Rabe +- #2132 JSON encode/decode string UDAs + Thanks to Chad Phillips +- #2176 How to get the full list of tags ? + Thanks to Adrien Lemaire +- #2091 duration of task is set to a wrong and extremely big value + Thanks to Wray Zheng +- Added 'juhannus' as a synonym for 'midsommarafton' + Thanks to Lynoure Braakman +- Deprecated the 'DUETODAY' virtual tag, which is a synonym for the 'TODAY' + virtual tag. +- Removed deprecated 'alias._query' setting. +- Fixed ambiguity in the esp-ESP localization + Thanks to Fidel Mato +- Deprecated the 'new-uuid' verbosity option, since its functionality can be + removed by merging with 'new-id'. +- Correct a false-positive warning when a due date is removed and a wait is + added. +- Added 'QUARTER' virtual tag. +- Fixed unquoted glob in bash completion script + Thanks to Ran Benita +- Deprecated use of alternate Boolean configuration settings. Use values "0" for + off, and "1" for on. Avoid used of "on", "off", "true", "t", "false", "f", + "yes", "y", "no", "n". +- Fixed test harness for Python 3.x. + Thanks to jrabbit +- Improved certificate validation diagnostics + Thanks to Jelle van der Waa +- Improved portability for SunOS-like OSes. + Thanks to Antonio Huete Jimenez +- Updated the 'timesheet' command with a more compact report that accepts a + filter, and has a default filter showing the last four weeks of completed and + started tasks. +- Added 'history.weekly', 'history.daily', 'ghistory.weekly', 'ghistory.daily' + report variations, with code refactoring. + Thanks to Lukas Barth +- New DOM references: annotations.count, tw.syncneeded, tw.program, tw.args, + tw.width, tw.height, tw.version. +- The message telling you to sync now indicates how many local changes will be + synced. +- Removed compile-time language settings and I18N. +- Workaround for alias grep=rg in fish + Thanks to Lionel Miller. +- Do not set CMP0037 on CMake 3.11.0 and above + Thanks to Janik Rabe + +------ current release --------------------------- + 2.5.1 (2016-02-24) 8b4ae3b54b44dfbd00b96cdd6dceb8dfe7cc1ea0 - TD-104 Unrecognized taskwarrior file format @@ -108,7 +264,7 @@ - The 'run_all' script was not correctly using exit code 0 when all tests pass (thanks to Gordon Ball). ------- current release --------------------------- +------ old releases ------------------------------ 2.5.0 (2015-10-21) dd5968a61b1fab258b38879cfdbb7d67f1bcd550 @@ -168,7 +324,7 @@ - TW-1488 You have more urgent tasks (thanks to Stefan Betz, Denis Kasak). - TW-1496 Translation manuals are outdated/miss information (thanks to Jens Erat). -- TW-1499 Invalid due date produces jump to beggining of the unix epoch (thanks +- TW-1499 Invalid due date produces jump to beginning of the unix epoch (thanks to Tomas Babej). - TW-1511 Project titles not properly parsed if they contain hyphens (thanks to Leon Feng, Blake Sweeney, Dylan Mikus). @@ -222,7 +378,7 @@ John Reeder). - TW-1630 "Due" parsing behavior seems inconsistent (thanks to Jim B). - TW-1632 Japanese translation for Taskwarrior(150713) (thanks to ribbon). -- TW-1634 due.not: excludes only tasks scheduled at mitnight (thanks to +- TW-1634 due.not: excludes only tasks scheduled at midnight (thanks to Tomas Babej). - TW-1635 Running "task anystringatall" does not filter anything (thanks to Tomas Babej). @@ -323,8 +479,6 @@ added. - When GC is turned off, disable the query shortcuts, which no longer apply. ------- old releases ------------------------------ - 2.4.4 (2015-05-10) df49aaba126484b668c41d3ff9301f8d8ec49987 - TW-69 wait dates relative to due date (thanks to John Florian). @@ -435,7 +589,7 @@ Babej). - TW-1505 completely ignore mis-named hook scripts (thanks to Tomas Babej, David Patrick). -- TW-1509 Hooks modifications performed on sync not sycning back (thanks to +- TW-1509 Hooks modifications performed on sync not syncing back (thanks to Tomas Babej). - TW-1510 Task can save empty value in the data backlog (thanks to Tomas Babej). - TW-1517 Hook performance should be measured individually for each hook (thanks @@ -543,7 +697,7 @@ "Description ( Information)". - TW-248 Substitute text doesn't work with forward slash (thanks to Jostein Berntsen). -- TW-249 Report filters don't allow parantheses (thanks to Philipp Woelfel). +- TW-249 Report filters don't allow parentheses (thanks to Philipp Woelfel). - TW-250 Opening parenthesis in description gets padded in task 2.0.0 bet 2 (thanks to Michelle Crane). - TW-251 extra spaces added after ( and / (thanks to Andy Spiegl). @@ -818,7 +972,7 @@ Bugs .taskrc file (thanks to Haitham Gad). - #1247 Tests now create a local dir, rather than use the insecure /tmp dir (thanks to Jakub Wilk). -- #1248 Merge tests no longer connect to takwarrior.org (thank to Jakub Wilk). +- #1248 Merge tests no longer connect to taskwarrior.org (thank to Jakub Wilk). - #1249 Build system now recognizes GNU/Hurd and GNU/kFreeBSD (thanks to Jakub Wilk). - #1263 The 'waiting' report properly lists only pending tasks with a wait date @@ -884,7 +1038,7 @@ Features - Stop consider new tasks after quitting a bulk change. - Removed deprecated 'fg:' and 'bg:' attributes. - The 'diagnostics' command now reports libuuid details. -- New characters for parsing and formating dates ('n', 's' and 'v'). +- New characters for parsing and formatting dates ('n', 's' and 'v'). - Virtual tags (BLOCKED, UNBLOCKED, BLOCKING, DUE, DUETODAY, OVERDUE, TODAY, ACTIVE, SCHEDULED, CHILD, UNTIL, WAITING and ANNOTATED). - New 'modified' attribute, which contains the most recent modification date, @@ -1350,7 +1504,7 @@ Bugs Michelle Crane). - Fixed bug #823, so that recurring task change propagations are now always confirmed (thanks to Miguel de Val Borro). -- Fixed bug #824, which caused probles when completing recurring tasks (thanks +- Fixed bug #824, which caused problems when completing recurring tasks (thanks to Matt Kraai). - Fixed bug #831, which prevented some date fields from being properly parsed. - Fixed bug #835, which prevented hierarchical projects from being recognized. @@ -1429,7 +1583,7 @@ Bugs (thanks to Michal Vyskocil). - Fixed problem where update-holidays.pl did not properly handle UTF8 JSON data. -- Fixed problem where update-holidays.pl did not use the YYYYMMDD date foramt. +- Fixed problem where update-holidays.pl did not use the YYYYMMDD date format. - Fixed problem where urgency was not properly calculated for waiting tasks. - Fixed problem where 'project' was not supported as a verbosity token (thanks to Adam Gibbins). @@ -1943,7 +2097,7 @@ Bugs - Supports 'rc.name:value' for a command line override to .taskrc data (thanks to Federico Hernandez). - Removed obsolete DEVELOPERS file. The online support forums at - http://taskwarrior.org will provide better information. + https://taskwarrior.org will provide better information. - Fixed bug that kept some deleted tasks showing up on the calendar report (thanks to Federico Hernandez). - Now asks the user to confirm large changes if configuration variable diff --git a/DEVELOPER b/DEVELOPER deleted file mode 100644 index 6af9d9631..000000000 --- a/DEVELOPER +++ /dev/null @@ -1,168 +0,0 @@ -How to Build Taskwarrior - - Satisfy the Requirements: - - gcc 4.7 or later, clang 3.3 or later or equivalent. This is because C++11 - is now used. - - libuuid - - gnutls (optional) - - python 2.7 or 3 (optional, for running the test suite) - - Obtain and build code: - $ git clone https://git.tasktools.org/scm/tm/task.git task.git - $ cd task.git - $ git checkout 2.5.0 # Latest dev branch - $ cmake -DCMAKE_BUILD_TYPE=debug . # debug or release. Default: neither. - $ make VERBOSE=1 # Shows details - - Running Test Suite: - $ cd tests - $ make VERBOSE=1 # Shows details - $ ./run_all # Runs all tests silently > all.log - $ ./problems # Enumerate test failures in all.log - - Note that any development should be performed using a git clone, and the - current development branch. The source tarballs do not reflect HEAD, and do - not contain the test suite. - - If you send a patch (support@taskwarrior.org), make sure that patch is made - against git HEAD on the development branch. We cannot apply patches made - against the tarball source, or master. - -General Statement - This file is intended to convey the current efforts, priorities and needs of - the codebase. It is for anyone looking for a way to start contributing. - While this is biased towards developers, anyone can contribute, and everyone - is encouraged to do so. Here are many ways to contribute that may not be - immediately obvious to you: - - - Use Taskwarrior, become familiar with it, and make suggestions. There are - always ongoing discussions about new features and changes to existing - features. - - - Join us in the #taskwarrior IRC channel on freenode.net. Many great ideas, - suggestions, testing and discussions have taken place there. It is also - the quickest way to get help, or confirm a bug. - - - Join https://answers.tasktools.org and help us by asking, answering and - voting on questions and answers, directly helping those who ask, and - helping future users who search for existing answers. - - - Review documentation: there are man pages, online articles, tutorials and - so on, and these may contain errors, or they may not convey ideas in the - best way. Perhaps you can help improve it. Contact us - documentation is - a separate effort from the codebase, and includes all web sites, and all - are available using git. - - - Take a look at the bug database, and help triage the bug list. This is a - review process that involves confirming bugs, providing additional data, - information or analysis. Bug triage is very useful and much needed. You - could check to see that an old bug is still relevant - sometimes they are - not. - - - Review the source code, and point out inefficiencies, problems, unreadable - functions, bugs and assumptions. - - - Fix a bug. For this you'll need C++ and Git skills, but this is one of - the largest ways you can contribute. We welcome all bug fixes, provided - the work is done well and doesn't create other problems or introduce new - dependencies. We recommend talking to us before starting. Seriously. - - - Add unit tests. Unit tests are possibly the most useful contributions of - all, because they not only improve the quality of the code, but prevent - future regressions, therefore maintaining quality of subsequent releases. - Plus, broken tests are a great motivator for us to fix the causal defect. - You'll need Python skills. - - - Add a feature. Well, let's be very clear about this: adding a feature is - not usually well-received, and if you add a feature and send a patch, it - will most likely be rejected. The reason for this is that there are many - efforts under way, in various code branches. There is a very good chance - that the feature you add is either already in progress, or being done in a - way that is more fitting when considering other work in progress. So if - you want to add a feature, please don't. Start by talking to us, and find - out what is currently under way or planned. You might find that we've - already rejected such a feature for some very good reasons. So please - check first, so we don't duplicate effort or waste anyone's time. - - - Donate some server time to the testing effort, by participating in the - continuous integration of all changes, with our Flod software. See this - page for an example: http://central.tasktools.org. Ask us about running a - Flod satellite, we're always looking for exotic platforms to test on. - - - Spread the word. Help others become more effective at managing tasks. - - - Encouragement. Tell us what works for you, and what doesn't. Tell us about - your methodology for managing tasks. It's all useful information. - - - Request a feature. This not only tells us that you think something is - missing from the software, but gives us insights into how you use it. - Plus, you might get your feature implemented. - - Next are some specific areas that need attention. - -New Code Needs - This is code that needs to be written. - - - Need an external script that can locate and correct duplicate UUIDs in the - data file, as found by 'task diag'. This should check to see if there is - a suitable UUID generator installed. This should also be careful to - properly handle recurring tasks. - - Take a look at: - - https://bug.tasktools.org/browse/EX - - This 'extension' release is a collection of all the requested features that - lie outside of the core product, and will be implemented as external scripts - by anyone who wishes to participate. - -Unit Tests Needed - There are always more unit tests needed. More specifically, better unit tests - are always needed. The convention is that there are four types of unit test: - - 1. High level tests that exercise large features, or combinations of commands. - For example, dependencies.t runs through a long list of commands that test - dependencies, but do so by using 'add', 'modify', 'done' and 'delete'. - 2. Regression tests that ensure certain bugs are fixed and stay fixed. These - tests are named bug.NNN.t where NNN refers to the bug number. While it is - not worth creating tests for small fixes like typos, it is for changes to - the logic. - 3. Small feature tests. When small features are added, we would like small, - low-level feature tests named feature.t, with a descriptive name and - focused tests. - 4. Code tests. These are tests written in C++ that exercise C++ objects, or - function calls. These are the lowest level tests. It is important that - these kind of tests be extensive and thorough, because the software depends - on this code the most. - - The tests are written in Python, Bash and C++, and all use TAP. - - Tests needed: - - - Take a look at the bug database (https://bug.tasktools.org) and notice that - many issues, open and closed, have the "needsTest" label. These are things - that we would like to see in the test suite, as regression tests. - - Test regex support. - - Need unit tests for each bug in the issue list that is marked with the - 'needsTest' label. - - Note that all new unit tests should follow the test/template.t standard. - -Work in Progress - - Things that are currently in flux, which is another way of saying leave it - alone while it is being worked on. - - - All columns/Col*::validate methods. - - New columns/Col*::modify methods. - -Current Codebase Condition - - 'master' branch: - - 2.4.4 Current release, locked. - - '2.5.0' branch: - - Current development branch no plans yet. - ---- - -2015-09-07 Updated for 2.5.0 diff --git a/DEVELOPER.md b/DEVELOPER.md new file mode 100644 index 000000000..e2bad15f9 --- /dev/null +++ b/DEVELOPER.md @@ -0,0 +1,157 @@ +# How to Build Taskwarrior + +## Satisfy the Requirements: + * CMake 3.0 or later + * gcc 5.0 or later, clang 3.4 or later, or a compiler with full C++14 support + * libuuid (if not on macOS) + * gnutls (optional) + * python 2.7 or 3 (optional, for running the test suite) + +## Obtain and build code: +``` + $ git clone --recursive https://github.com/GothenburgBitFactory/taskwarrior taskwarrior.git + $ cd taskwarrior.git + $ git checkout 2.6.0 # Latest dev branch + $ git submodule init # This is now done by cmake as a test + $ git submodule update # Update the libhsared.git submodule + $ cmake -DCMAKE_BUILD_TYPE=debug . # debug or release. Default: neither + $ make VERBOSE=1 -j4 # Shows details, builds using 4 jobs + # Alternately 'export MAKEFLAGS=-j 4' +``` +## Running Test Suite: +``` + $ cd tests + $ make VERBOSE=1 # Shows details + $ ./run_all # Runs all tests silently > all.log + $ ./problems # Enumerate test failures in all.log +``` + + Note that any development should be performed using a git clone, and the + current development branch. The source tarballs do not reflect HEAD, and do + not contain the test suite. + + If you send a patch (support@gothenburgbitfactory.org), make sure that patch is made + against git HEAD on the development branch. We cannot apply patches made + against the tarball source, or master. + + +# General Statement + This file is intended to convey the current efforts, priorities and needs of + the code base. It is for anyone looking for a way to start contributing. + Here are many ways to contribute that may not be obvious: + + * Use Taskwarrior, become familiar with it, and make suggestions. There are + always ongoing discussions about new features and changes to existing + features. + + * Join us in the #taskwarrior IRC channel on freenode.net. Many great ideas, + suggestions, testing and discussions have taken place there. It is also + the quickest way to get help, or confirm a bug. + + * Review documentation: there are man pages, online articles, tutorials and + so on, and these may contain errors, or they may not convey ideas in the + best way. Perhaps you can help improve it. Contact us - documentation is + a separate effort from the code base, and includes all web sites, and all + are available as git repositories. + + * Take a look at the bug database, and help triage the bug list. This is a + review process that involves confirming bugs, providing additional data, + information or analysis. Bug triage is very useful and much needed. You + could check to see that an old bug is still relevant - sometimes they are + not. + + * Review the source code, and point out inefficiencies, problems, unreadable + functions, bugs and assumptions. + + * Fix a bug. For this you'll need C++ and Git skills. We welcome all bug + fixes, provided the work is done well and doesn't create other problems or + introduce new dependencies. We recommend talking to us before starting. + Seriously. + + * Add unit tests. Unit tests are possibly the most useful contributions of + all, because they not only improve the quality of the code, but prevent + future regressions, therefore maintaining quality of subsequent releases. + Plus, broken tests are a great motivator for us to fix the causal defect. + You'll need Python skills. + + * Add a feature. Well, let's be very clear about this: adding a feature is + not usually well-received, and if you add a feature and send a patch, it + will most likely be rejected. The reason for this is that there are many + efforts under way, in various code branches. There is a very good chance + that the feature you add is either already in progress, or being done in a + way that is more fitting when considering other work in progress. So if + you want to add a feature, please don't. Start by talking to us, and find + out what is currently under way or planned. You might find that we've + already rejected such a feature for some very good reasons. So please + check first, so we don't duplicate effort or waste anyone's time. + + * Spread the word. Help others become more effective at managing tasks. + + * Encouragement. Tell us what works for you, and what doesn't. Tell us about + your methodology for managing tasks. It's all useful information. + + * Request a feature. This not only tells us that you think something is + missing from the software, but gives us insights into how you use it. + Plus, you might get your feature implemented. + +# Unit Tests Needed + There are always more unit tests needed. More specifically, better unit tests + are always needed. The convention is that there are four types of unit test: + + 1. High level tests that exercise large features, or combinations of commands. + For example, dependencies.t runs through a long list of commands that test + dependencies, but do so by using 'add', 'modify', 'done' and 'delete'. + 1. Regression tests that ensure certain bugs are fixed and stay fixed. These + tests are named tw-NNNN.t where NNNN refers to the bug number. While it is + not worth creating tests for small fixes like typos, it is for logic + changes. + 1. Small feature tests. When small features are added, we would like small, + low-level feature tests named feature.t, with a descriptive name and + focused tests. + 1. Code tests. These are tests written in C++ that exercise C++ objects, or + function calls. These are the lowest level tests. It is important that + these kind of tests be extensive and thorough, because the software depends + on this code the most. + + The tests are written in Python, Bash and C++, and all use TAP. + +## Tests needed + + * Take a look at the bug database (https://github.com/GothenburgBitFactory/taskwarrior/issues) + and notice that many issues, open and closed, have the "needsTest" label. + These are things that we would like to see in the test suite, as regression + tests. + + All new unit tests should follow the test/template.t standard. + +# Patches + Patches are encouraged and welcomed. Either send a pull request on Github or + email a patch to support@taskwarrior.org. A good patch: + + * Maintains the MIT license, and does not contain code lifted from other + sources. You will have written 100% of the code in the patch, otherwise + we cannot maintain the license. + * Precisely addresses one issue only. + * Doesn't break unit tests. This means yes, run the unit tests. + * Doesn't introduce dependencies. + * Is accompanied by new or updated unit tests, where appropriate. + * Is accompanied by documentation changes, where appropriate. + * Conforms to the prevailing coding standards - in other words, it should + fit in with the existing code. + + A patch may be rejected for violating any of the above rules, and more. + Bad patches may be accepted and modified depending on work load and mood. It + is possible that a patch may be rejected because it conflicts in some way with + plans or upcoming changes. Check with us first, before sinking time and effort + into a patch. + +# Current Code Base Condition + +**'master' branch**: + * 2.5.1 Current release, locked. + + **'2.6.0' branch**: + * Current development branch. + +--- +2018-05-13 Updated for 2.5.2 diff --git a/EXPOSITION b/EXPOSITION deleted file mode 100644 index 0912f44af..000000000 --- a/EXPOSITION +++ /dev/null @@ -1,210 +0,0 @@ -Startup - On startup, main creates a global Context object, then calls the - Context::initialize and Context::run methods. - - Context is a large object that holds all task information, both in terms of - the task data, and intermediate run-time data. Having one global Context - object means we don't have 50 global variables. Context is therefore just a - big global bucket of data. - - Context::initialize sets up all the data and processes the command line. The - initialization process is a big chicken-and-egg problem, because the command - line depends on configuration (aliases) and the command line can force a - reload of configuration (rc:foo). This is solved by look-ahead: the command - line is scanned for 'rc:xxx' and 'rc.data.location:xxx' arguments, then later - for overrides. - - The Context::run method handles all the debug output and exceptions. Its - main purpose is to set up exception handling and call Context::dispatch. - - -Command Line Parsing - Command line parsing is difficult because of all the ambiguity. The solution - is to make multiple passes over the command line. For example, the command - determines whether subsequent arguments are interpreted as part of a filter or - set of modifications. - - The CLI2 object is fed command line arguments, then through a succession of - calls builds and annotates a parse tree. To help with this, the Lexer is - used to break up strings into tokens. - - -Dispatch - Dispatch is simple: once the command line is parsed, the command is used to - look up a command object, then a call is made to the Command::execute method. - - Context stores an associative map of command object pointers indexed by a - string. This means the 'done' string is an index to the CmdDone object that - implements the functionality. - - -Command Objects - Every task command is implemented by a command object. The command object - provides metadata, usage and one-line help in addition to the ::execute method - that implements the command. The Command base class implements common - functionality. - - -Column Objects - There is a 1:1 correspondence between attributes stored in the data files and - the columns that may be reported. These are represented by column objects, - which are responsible for validating input, measuring space needed according - to various formats, and for rendering data for reports. There is a - ColDescription object that inherits from a Column base class. - - -TDB2 - The TDB2 object is a layered, transactioned I/O manager. Its purpose is to - isolate code from file I/O, locking and parsing details. It is also - responsible for minimizing reads, writes and parsing of data files. - - All input is assumed to be UTF8. All stored data is UTF8. - - -GC - Garbage Collection is the process that moves tasks between the pending.data - and completed.data files. It is also responsible for waking tasks out of the - wait state. - - Every command that displays task IDs will cause a GC to be run first, which - minimizes the number of changes necessary to the task IDs. This means that - when a report shows task IDs, those IDs will remain valid while subsequent - write commands are issued. The next report run may show different IDs. - - Minimizing the size of pending.data is important for performance, because it - is the file that is accessed most. - - -Files - The data files used are all kept in the rc.data.location directory, which - defaults to ~/.task. The files are: - - pending.data - completed.data - undo.data - backlog.data - - The pending.data file aspires to contain only pending, waiting and recurring - tasks, but this is only correct after a GC, and before any tasks are modified. - This file tends to be relatively stable in size, reflecting the length of the - task list. - - The completed.data file accumulates data over time, and grows unbounded. - - The undo.data file accumulates changes over time, and grows unbounded. It - provides all the necessary metadata to support the 'undo' command. - - The backlog.data file contains an accumulated set of changes that have not - been transmitted to Taskserver. It grows unbounded between 'sync' commands. - - -Filter - A filter is simply a set of command line arguments, but is only a subset of - the complete command line. These arguments are extracted from the parse tree - according to whether the command found is a read or write command. - - There is a Filter::subset method for applying a filter to a set of tasks, - yielding a result set. It does this by creating an expression from the - parse tree using the Eval object, then evaluating the expression for each task, - such that the result set contains only tasks for which the expression evaluates - to Boolean true. - - -Eval & Variant - The Eval class evaluates expressions, provided in string form, using the - Variant class to represent data elements. Variant implements all operators - for all Variant types. - - -Sorting - Sorting is performed on a set of tasks. More specifically, the list that is - sorted is a set of numeric indexes to tasks that are stored in a separate - list. This minimizes the amount of data copying involved to just integers - rather than Task objects, but at the expense of one level of indirection. - Memory fragmentation is a bigger problem than the performance of vector - indexing. - - The actual sorting is performed by std::stable_sort, but the compare function - is custom. - - -Render - There are two rendering objects, ViewTask and ViewText. These both have the - same tabular grid rendering capabilities. ViewText maintains a 2D vector of - strings to contain the data to be rendered, so it is used for things like the - help command output. ViewTask does not copy data, but assumes all data is - stored externally in a vector of Tasks, which minimizes data copying. - - ViewTask contains projection data in the form of a set of Column objects that - represent the X axis. The Y axis is represented by a vector of tasks. - - The rendering process is complex. It involves dynamically setting column - widths based on (1) available terminal width, (2) the columns to be included - in the output, (3) ability to wrap text for certain columns and (4) the size - of the data to be rendered, which involves added complexity when UTF8 is used. - - The Column objects determine minimum width for a column and the maximum width - which then allows ViewT* to make choices. - - -Test Suite - A strong and diverse test suite is critical to the successful release of any - software. With the complex command set and its myriad permutations, a test - suite is the only way to ensure quality levels, and guarantee that big changes - are robust. - - It is intended that the test suite continues growing, mostly feature tests. - The test are mostly written in Python. Some tests are written in C++ and all - tests generate TAP output. - - There are currently about 8,000 unit tests, that take only a few seconds to - run on a multi-core machine. - - Taskwarrior uses flod software to automate continuous integration across many - platforms. Code changes are automatically detected, propagated, built and - tested on a variety of participating platforms. Grid testing results are here: - - http://central.tasktools.org/ - - When making code changes, it is important that the test suite be run to verify - that functionality was not broken. - - -Debugging - The 'rc.debug=on' override provides the following additional information which - is useful during debugging: - - - Timing of various components (used to generate the data for the charts at - http://tasktools.org/performance). - - Data load times. - - Terminal size, color capabilities. - - Command line parse tree. - - TDB2 layer and I/O information. - - Additionally, there are other settings (see 'man taskrc' for full details) that - may also be helpful: 'rc.hooks=on|off', 'rc.debug.parser=0|1|2|3', - 'rc.debug.hooks=0|1|2', 'rc.debug.tls=0|1|2|3...'. - - -Patches - Patches are encouraged and welcomed. Either attach them to the appropriate - Jira issue, or send them to support@taskwarrior.org. A good patch: - - - Maintains the MIT license, and does not contain code lifted from other - sources. You will have written 100% of the code in the patch, otherwise - we cannot maintain the license. - - Precisely addresses one issue only. - - Doesn't break unit tests. - - Doesn't introduce dependencies. - - Is accompanied by unit tests, where appropriate, written in Python. - - Is accompanied by documentation changes, where appropriate. - - Conforms to the prevailing coding standards - in other words, it should - fit right in with the existing code. - - A patch may be rejected for violating any of the above rules, and more. - Bad patches may be accepted and modified depending on work load and mood. It - is possible that a patch may be rejected because it conflicts in some way with - plans or upcoming changes. Check with us first, before sinking time and effort - into a patch. - ---- diff --git a/INSTALL b/INSTALL index 034caee9a..1dd26dcc6 100644 --- a/INSTALL +++ b/INSTALL @@ -8,15 +8,15 @@ source. Dependencies ------------ -You will need the CMake build system installed in order to build Taskwarrior -from source. More information on cmake can be obtained at http://cmake.org +You will need the CMake 3.0+ build system installed in order to build Taskwarrior +from source. More information on CMake can be obtained at https://cmake.org You will also need: - make -You will need a C++ compiler that supports full C++11, which includes: - - gcc 4.7 (released 2012-03-23) - - clang 3.3 (released 2013-01-07) +You will need a C++ compiler that supports full C++14, which includes: + - gcc 5.0 (released 2013-12-23) + - clang 3.4 (released 2014-01-02) You will need the following libraries: - libuuid (not needed for OSX) @@ -103,26 +103,6 @@ In order to build Taskwarrior without "sync" support, call cmake with the and proceed as described in "Basic Installation". -Localizations -------------- - -To make use of a translation, specify a language number, as found in cmake.h: - - $ cmake -DLANGUAGE=2 . - -Currently the defined languages are: - - eng_USA 1 - esp_ESP 2 - deu_DEU 3 - fra_FRA 4 - ita_ITA 5 - por_PRT 6 - epo_RUS 7 - pol_POL 8 - jpn-JPN 9 - - Uninstallation -------------- @@ -161,7 +141,7 @@ Darwin, 32bit cmake -DCMAKE_C_FLAGS=-m32 -DCMAKE_CXX_FLAGS=-m32 -DCMAKE_EXE_LINKER_FLAGS=-m32 . See: - http://taskwarrior.org/issues/817 + https://taskwarrior.org/issues/817 http://stackoverflow.com/questions/3261909/build-32bit-on-64-bit-linux-using-a-configure-script http://stackoverflow.com/questions/2617508/cmake-gcc-cuda-and-m32-wtf http://stackoverflow.com/questions/6077414/cmake-how-to-set-the-ldflags-in-cmakelists-txt @@ -176,8 +156,16 @@ OpenBSD and build normally. - See: https://bug.tasktools.org/browse/TW-1579 + See: https://github.com/GothenburgBitFactory/taskwarrior/issues/1605 +WASM + Using the Emscripten compiler, you can achieve it like this: + + cmake -DCMAKE_CXX_COMPILER=emcc -DENABLE_SYNC=OFF -DCMAKE_BUILD_TYPE=release -DENABLE_WASM=ON \ + -DCMAKE_EXE_LINKER_FLAGS="-m32 -s NO_DYNAMIC_EXECUTION=1 -s WASM=1 -s NO_EXIT_RUNTIME=1 -s INVOKE_RUN=0" \ + -DCMAKE_CXX_FLAGS_RELEASE="-O2 -m32" + + This will produce an optimized WASM with a main() that is callable multiple times. Troubleshooting --------------- @@ -192,8 +180,7 @@ CMake with no reported problems, and the build will fail later. This is almost always because CMake is mistaken about some assumption. If a build does not succeed, please send the contents of the 'CMakeCache.txt' -and 'CMakeFiles/CMakeOutput.log' files to support@taskwarrior.org, or post a -message in the support forums at taskwarrior.org along with the information. +and 'CMakeFiles/CMakeOutput.log' files to support@gothenburgbitfactory.org. If CMake runs but Taskwarrior does not build, please send the contents of the above files as well as a transcript from the build, which is not written to a diff --git a/LICENSE b/LICENSE index a518570b0..2f43e0f23 100644 --- a/LICENSE +++ b/LICENSE @@ -1,6 +1,6 @@ Taskwarrior - a command line task list manager. -Copyright 2006 - 2016, Paul Beckingham, Federico Hernandez. +Copyright 2006 - 2020, 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 @@ -20,4 +20,4 @@ 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 +https://www.opensource.org/licenses/mit-license.php diff --git a/NEWS b/NEWS index 3aaa93582..7d28057e0 100644 --- a/NEWS +++ b/NEWS @@ -1,26 +1,48 @@ -New Features in Taskwarrior 2.5.1 +New Features in Taskwarrior 2.5.2 - - As a bug-fix, code cleanup and performance release, new features are - limited to only small tweaks. + - The 'QUARTER' virutal tag was added. - The 'help' command now takes a 'usage' argument, which displays only the command usage. + - Improved compatibility with SmartOS, OmniOS and OpenIndiana. + - New DOM references: annotations.count, tw.syncneeded, tw.program, tw.args, + tw.width, tw.height, tw.version. + - Renovated 'timesheet' command with a more compact report that accepts a + filter, and has a default filter showing the last four weeks of completed + and started tasks. + - The message telling you to sync now indicates how many local changes will be + synced. -New Commands in Taskwarrior 2.5.1 +New Commands in Taskwarrior 2.5.2 - - None. + - The 'purge' command was added, which completely removes old tasks. + - Added new 'history.weekly', 'history.daily', 'ghistory.weekly', + 'ghistory.daily' reports. -New Configuration Options in Taskwarrior 2.5.1 +New Configuration Options in Taskwarrior 2.5.2 - New 'relative' column format for 'date' type columns does what 'remaining' and 'countdown' do, but in one format. + - The 'default.scheduled' date/duration works just like 'default.due'. + - The 'report.timesheet.filter' setting controls the tasks shown by the + 'timesheet' command. -Newly Deprecated Features in Taskwarrior 2.5.1 +Newly Deprecated Features in Taskwarrior 2.5.2 - - + - The 'DUETODAY' virtual tag is a synonym for the 'TODAY' virtual tag, and is + not needed. + - The 'new-uuid' verbosity option is to be removed, as it is redundant, its + functionality will be merged with 'new-id' option. + - The use of alternate Boolean configuration settings is deprecated. Use values + "0" for off, and "1" for on. Avoid used of "on", "off", "true", "t", + "false", "f", "yes", "y", "no", "n". + - The 'context.program', 'context.args', 'context.width' and 'context.height' + DOM references are deprecated, replaced by similarly-named 'tw.xxx' + references. -Removed Features in 2.5.1 +Removed Features in 2.5.2 + - Removed 'alias._query' default configuration. - There is no longer a 16-color default configuration for some platforms, making all platforms 256-color. - The configuration setting 'burndown.bias' is no longer used. @@ -28,34 +50,32 @@ Removed Features in 2.5.1 been replaced by something less icky. Estimates are now based on the net completion rate after the peak number of pending tasks. - The unused 'dom' and 'shell.prompt' configuration settings were removed. + - Translations are no longer supported. Known Issues - - https://bug.tasktools.org/ + - https://github.com/GothenburgBitFactory/taskwarrior Taskwarrior has been built and tested on the following configurations: - * OS X + * macOS * Fedora * Ubuntu * Debian * Arch * FreeBSD - * Cygwin + * CentOS --- While Taskwarrior has undergone testing, bugs are sure to remain. If you encounter a bug, please enter a new issue at: - https://bug.tasktools.org - -Or you can also report the issue in the forums at: - - https://answers.tasktools.org + https://github.com/GothenburgBitFactory/taskwarrior Or just send a message to: - support@taskwarrior.org + support@GothenburgBitFactory.org Thank you. + diff --git a/README.md b/README.md index 1bf742bb5..8a7429baa 100644 --- a/README.md +++ b/README.md @@ -1,47 +1,90 @@ -# Disclaimer during ongoing development +# Taskwarrior -We want to discourage you from using the development version of Taskwarrior. - -The development branch is a work in progress and may not pass all quality tests, -therefore it may harm your data. We do not guarantee proper or even adequate -functionality, performance or timely fixes. - -We welcome bug reports from beta- and release-level software, but generally not -development versions. If you are undaunted by this, please: - -- Make proper backups. -- Expect broken and missing functionality. -- Be aware that using the development branch involves risks. - ---- +[![Travis build status](https://travis-ci.org/GothenburgBitFactory/taskwarrior.svg?branch=2.5.2)](https://travis-ci.org/GothenburgBitFactory/taskwarrior) Thank you for taking a look at Taskwarrior! Taskwarrior is a GTD, todo list, task management, command line utility with a multitude of features. It is a portable, well supported and very active Open -Source project. Taskwarrior has binary distributions, online documentation, -demonstration movies, and you'll find all the details at: +Source project. - http://taskwarrior.org +## Documentation + +There is extensive online documentation. +You'll find all the details at [taskwarrior.org/docs](https://taskwarrior.org/docs) At the site you'll find online documentation, downloads, news and more. -Your contributions are especially welcome. Whether it comes in the form of -code patches, ideas, discussion, bug reports, encouragement or criticism, your -input is needed. +## Support -For support options, take a look at: +For support options, take a look at [taskwarrior.org/support](https://taskwarrior.org/support) - http://taskwarrior.org/support +Please use pull requests, or alternately send your code patches to +[support@gothenburgbitfactory.org](mailto:support@gothenburgbitfactory.org) -Please send your code patches to: +## Branching Model - support@taskwarrior.org +We use the following branching model: -Consider joining bug.tasktools.org, answers.tasktools.org and participating in -the future of Taskwarrior. +* `master` is the stable branch. Building from here is the same as building + from the latest tarball, or installing a binary package. No development is + done on the `master` branch. ---- +* `2.6.0` is the current development branch. All work is done here, and upon + release it will be merged to `master`. This development branch is not stable, + may not even build or pass tests, and should be treated accordingly. + Make backups. + +## Installing + +There are many binary packages available, but to install from source requires: + +* git +* cmake +* make +* C++ compiler, currently gcc 5.0+ or clang 3.4+ for full C++14 support + +Download the tarball, and expand it: + + $ curl -O https://taskwarrior.org/download/task-2.6.0.tar.gz + $ tar xzf task-2.6.0.tar.gz + $ cd task-2.6.0 + +Or clone this repository: + + $ git clone --recursive -b 2.6.0 https://github.com/GothenburgBitFactory/taskwarrior.git + $ cd taskwarrior + +In case of errors with libshared - URL pointing to git.tasktools.org in either .git/config or .gitmodules: + + $ sed -i 's/git.tasktools.org\/TM/github.com\/GothenburgBitFactory/' .git/config + $ git submodule update + +or + + $ sed -i 's/git.tasktools.org\/TM/github.com\/GothenburgBitFactory/' .gitmodules + $ git submodule init + $ git submodule update + +Then build: + + $ cmake -DCMAKE_BUILD_TYPE=release . + ... + $ make + ... + [$ make test] + ... + $ sudo make install + +## Contributing + +Your contributions are especially welcome. +Whether it comes in the form of code patches, ideas, discussion, bug reports, encouragement or criticism, your input is needed. + +Visit [Github](https://github.com/GothenburgBitFactory/taskwarrior) and participate in the future of Taskwarrior. + +## License + +Taskwarrior is released under the MIT license. +For details check the [LICENSE](LICENSE) file. -Taskwarrior is released under the MIT license. For details check the LICENSE -file. diff --git a/cmake.h.in b/cmake.h.in index 0041e6ea7..ff74c832b 100644 --- a/cmake.h.in +++ b/cmake.h.in @@ -17,18 +17,6 @@ /* Installation details */ #define TASK_RCDIR "${CMAKE_INSTALL_PREFIX}/${TASK_RCDIR}" -/* Localization */ -#define PACKAGE_LANGUAGE ${PACKAGE_LANGUAGE} -#define LANGUAGE_ENG_USA ${LANGUAGE_ENG_USA} -#define LANGUAGE_ESP_ESP ${LANGUAGE_ESP_ESP} -#define LANGUAGE_FRA_FRA ${LANGUAGE_FRA_FRA} -#define LANGUAGE_DEU_DEU ${LANGUAGE_DEU_DEU} -#define LANGUAGE_ITA_ITA ${LANGUAGE_ITA_ITA} -#define LANGUAGE_POR_PRT ${LANGUAGE_POR_PRT} -#define LANGUAGE_EPO_RUS ${LANGUAGE_EPO_RUS} -#define LANGUAGE_POL_POL ${LANGUAGE_POL_POL} -#define LANGUAGE_JPN_JPN ${LANGUAGE_JPN_JPN} - /* git information */ #cmakedefine HAVE_COMMIT @@ -43,6 +31,7 @@ #cmakedefine FREEBSD #cmakedefine OPENBSD #cmakedefine NETBSD +#cmakedefine DRAGONFLY #cmakedefine HAIKU #cmakedefine SOLARIS #cmakedefine KFREEBSD diff --git a/cmake/CXXSniffer.cmake b/cmake/CXXSniffer.cmake new file mode 100644 index 000000000..a2d0ba222 --- /dev/null +++ b/cmake/CXXSniffer.cmake @@ -0,0 +1,40 @@ +message ("-- Configuring C++17") +message ("-- System: ${CMAKE_SYSTEM_NAME}") + +include (CheckCXXCompilerFlag) + +CHECK_CXX_COMPILER_FLAG("-std=c++17" _HAS_CXX17) + +if (_HAS_CXX17) + set (_CXX14_FLAGS "-std=c++17") +else (_HAS_CXX17) + message (FATAL_ERROR "C++17 support missing. Try upgrading your C++ compiler. If you have a good reason for using an outdated compiler, please let us know at support@gothenburgbitfactory.org.") +endif (_HAS_CXX17) + +if (${CMAKE_SYSTEM_NAME} MATCHES "Linux") + set (LINUX true) +elseif (${CMAKE_SYSTEM_NAME} MATCHES "Darwin") + set (DARWIN true) + set (_CXX14_FLAGS "${_CXX14_FLAGS} -stdlib=libc++") +elseif (${CMAKE_SYSTEM_NAME} MATCHES "kFreeBSD") + set (KFREEBSD true) +elseif (${CMAKE_SYSTEM_NAME} MATCHES "FreeBSD") + set (FREEBSD true) +elseif (${CMAKE_SYSTEM_NAME} MATCHES "OpenBSD") + set (OPENBSD true) +elseif (${CMAKE_SYSTEM_NAME} MATCHES "NetBSD") + set (NETBSD true) +elseif (${CMAKE_SYSTEM_NAME} MATCHES "DragonFly") + set (DRAGONFLY true) +elseif (${CMAKE_SYSTEM_NAME} MATCHES "SunOS") + set (SOLARIS true) +elseif (${CMAKE_SYSTEM_NAME} STREQUAL "GNU") + set (GNUHURD true) +elseif (${CMAKE_SYSTEM_NAME} STREQUAL "CYGWIN") + set (CYGWIN true) +else (${CMAKE_SYSTEM_NAME} MATCHES "Linux") + set (UNKNOWN true) +endif (${CMAKE_SYSTEM_NAME} MATCHES "Linux") + +set (CMAKE_CXX_FLAGS "${_CXX14_FLAGS} ${CMAKE_CXX_FLAGS}") +set (CMAKE_CXX_FLAGS "-Wall -Wextra -Wsign-compare -Wreturn-type ${CMAKE_CXX_FLAGS}") diff --git a/doc/CMakeLists.txt b/doc/CMakeLists.txt index a0072349d..81df9d08f 100644 --- a/doc/CMakeLists.txt +++ b/doc/CMakeLists.txt @@ -1,4 +1,4 @@ -cmake_minimum_required (VERSION 2.8) +cmake_minimum_required (VERSION 3.0) message ("-- Configuring man pages") set (man_FILES task-color.5 task-sync.5 taskrc.5 task.1) foreach (man_FILE ${man_FILES}) diff --git a/doc/man/task-color.5.in b/doc/man/task-color.5.in index 4b35d8782..2056d57d0 100644 --- a/doc/man/task-color.5.in +++ b/doc/man/task-color.5.in @@ -3,33 +3,6 @@ .SH NAME task-color \- A color tutorial for the Taskwarrior command line todo manager. -.SH SETUP -The first thing you need is a terminal program that supports color. All -terminal programs support color, but only a few support lots of colors. First -tell your terminal program to use color by specifying the TERM environment -variable like this: - - TERM=xterm-color - -In this example, xterm-color is used - a common value, and one that doesn't -require that you use xterm. This works for most setups. This setting belongs -in your shell profile (~/.bash_profile, ~/.bashrc, ~/.cshrc etc, depending on -which shell you use). If this is a new setting, you will need to either run -that profile script, or close and reopen the terminal window (which does the -same thing). - -Now tell Taskwarrior that you want to use color. This is the default for -Taskwarrior, so the following step may be unnecessary. - - $ task config color on - -This command will make sure there is an entry in your ~/.taskrc file that looks -like: - - color=on - -Now Taskwarrior is ready. - .SH AUTOMATIC MONOCHROME It should be mentioned that Taskwarrior is aware of whether its output is going to a terminal, or to a file or through a pipe. When Taskwarrior output goes to @@ -249,11 +222,10 @@ variable 'rule.precedence.color', which by default contains: deleted,completed,active,keyword.,tag.,project.,overdue,scheduled,due.today,due,blocked,blocking,recurring,tagged,uda. These are just the color rules with the 'color.' prefix removed. The -rule 'color.due.today' is the highest precedence, and 'color.deleted' is the lowest. +rule 'color.deleted' has the highest precedence, and 'color.uda.' the lowest. The keyword rule shown here as 'keyword.' corresponds to a wildcard pattern, -meaning 'color.keyword.*', or in other words all the keyword rules. Similarly -for the 'color.tag.*' and 'color.project.*' rules. +meaning 'color.keyword.*', or in other words all the keyword rules. There is also 'color.project.none', 'color.tag.none' and 'color.pri.none' to specifically represent missing data. @@ -313,34 +285,34 @@ You can also see how the theme will color the various tasks with the command: $ task color legend Better yet, create your own, and share it. We will gladly host the theme file -on . +on . .SH "CREDITS & COPYRIGHTS" -Copyright (C) 2006 \- 2016 P. Beckingham, F. Hernandez. +Copyright (C) 2006 \- 2020 P. Beckingham, F. Hernandez. Taskwarrior is distributed under the MIT license. See -http://www.opensource.org/licenses/mit-license.php for more information. +https://www.opensource.org/licenses/mit-license.php for more information. .SH SEE ALSO .BR task(1), .BR taskrc(5), .BR task-sync(5) -For more information regarding Taskwarrior, the following may be referenced: +For more information regarding Taskwarrior, see the following: .TP The official site at - + .TP The official code repository at - + .TP -You can contact the project by writing an email to - +You can contact the project by emailing + .SH REPORTING BUGS .TP Bugs in Taskwarrior may be reported to the issue-tracker at - + diff --git a/doc/man/task-sync.5.in b/doc/man/task-sync.5.in index 454628cf4..c066178f1 100644 --- a/doc/man/task-sync.5.in +++ b/doc/man/task-sync.5.in @@ -5,8 +5,8 @@ task-sync \- A discussion and tutorial for the various task(1) data synchronization capabilities. .SH INTRODUCTION -Taskwarrior has several sync options, external and internal. If you wish to -sync your data, choose one method only; mixing methods is only going to lead to +Taskwarrior has several sync options, both external and built in. If you wish +to sync your data, choose one method only; mixing methods is going to lead to problems. Each of the methods discussed have their own strengths. .SH ALTERNATIVES @@ -14,14 +14,15 @@ There are three alternatives for syncing data, which are: 1) Version control systems, such as git, hg, svn .br -2) File hosting systems, such as DropBox +2) File sharing systems, such as DropBox, Google Drive .br 3) Using the Taskserver and the 'sync' command .SH OPTION 1: VERSION CONTROL SYSTEMS There are several good, distributed VCS systems (git, hg, ...) and centralized -VCS systems (svn ...), and they function in a similar fashion for our purposes. +VCS systems (svn, cvs ...), and they all function in a similar fashion for our +purposes. Setup is straightforward. You place your .task directory under revision control. You then need to perform a regular commit/push/pull/update to make @@ -44,8 +45,8 @@ Weaknesses: - You need to provide the mechanism for making sure copies are up to date -.SH OPTION 2: FILE HOSTING SERVICES -There are many file hosting services, such as DropBox, Amazon S3, Google Drive, +.SH OPTION 2: FILE SHARING SERVICES +There are many file sharing services, such as DropBox, Amazon S3, Google Drive, SkyDrive and more. This technique involves storing your .task directory in a shared directory under the control of the file hosting services. @@ -61,8 +62,6 @@ configuration variable like this: $ task config data.location /path/to/shared/directory Strengths: -.br - - Always secure .br - Good client support .br @@ -76,7 +75,7 @@ Weaknesses: .SH OPTION 3: TASKSERVER -The Taskserver was designed for this purpose to be secure, fast and conflict +The Taskserver was designed for this purpose to be secure, fast and conflict- free, allowing data interchange between assorted Taskwarrior clients, and tolerant of network connectivity problems. @@ -86,7 +85,7 @@ done on demand. Setup is a matter of creating an account on a Taskserver (see your Taskserver provider or operate your own - see -http://taskwarrior.org/docs/server_setup.html) +https://taskwarrior.org/docs/taskserver/setup.html) Once you have an account, you'll receive a certificate, key, and credentials. You'll need to put the certificate and key somewhere like this: @@ -107,16 +106,10 @@ certificate, which means you will need one of the following additional entries: $ task config taskd.ca ~/.task/ca.cert.pem The CA (Certificate Authority) will be used to verify the server certificate. -Alternatively, you can override the cert verification process using: - - $ task config taskd.trust 'allow all' - -This is an insecure option that should be used with caution, because it directs -Taskwarrior to trust any certificate. After setup, you run a one-time sync initialization, like this: - $ task sync initialize + $ task sync init This will make sure your client and the server are properly in sync to begin with. From this point on, you never run the 'initialize' command again, just @@ -130,9 +123,20 @@ nothing happens. If you do not have connectivity, your task changes accumulate so that when you next run 'sync' with proper connectivity, the changes are properly handled, in the right order. +If you run multiple clients that sync to the same server, you will need to run +this command on your primary client (the one you use most often): + + $ task config recurrence on + +And on the other clients, run: + + $ task config recurrence off + +This protects you against the effects of a sync/duplication bug. + Strengths: .br - - Always secure + - Secure communication .br - Minimal bandwidth .br @@ -143,31 +147,31 @@ Weaknesses: - You need to manage your own server, or gain access to a hosted server. .SH "CREDITS & COPYRIGHTS" -Copyright (C) 2006 \- 2016 P. Beckingham, F. Hernandez. +Copyright (C) 2006 \- 2020 P. Beckingham, F. Hernandez. Taskwarrior is distributed under the MIT license. See -http://www.opensource.org/licenses/mit-license.php for more information. +https://www.opensource.org/licenses/mit-license.php for more information. .SH SEE ALSO .BR task(1), .BR taskrc(5), .BR task-color(5), -For more information regarding task, the following may be referenced: +For more information regarding Taskwarrior, see the following: .TP The official site at - + .TP The official code repository at - + .TP -You can contact the project by writing an email to - +You can contact the project by emailing + .SH REPORTING BUGS .TP -Bugs in task may be reported to the issue-tracker at - +Bugs in Taskwarrior may be reported to the issue-tracker at + diff --git a/doc/man/task.1.in b/doc/man/task.1.in index d293abf4e..47fbe5a47 100644 --- a/doc/man/task.1.in +++ b/doc/man/task.1.in @@ -151,12 +151,12 @@ the specified month and year. If the 'due' argument is provided, will show the starting month of the earliest due task. .TP -.B task colors [sample | legend] +.B task colors [ | legend] Displays all possible colors, a named sample, or a legend containing all currently defined colors. .TP -.B task columns [substring] +.B task columns [] Displays all supported columns and formatting styles. Useful when creating custom reports. If a substring is provided, only matching column names are shown. @@ -177,8 +177,8 @@ Displays only a count of tasks matching the filter. .B task export Exports all tasks in the JSON format. Redirect the output to a file, if you wish to save it, or pipe it to another command or script to convert it to -another format. The standard task release comes with a few example scripts, -such as: +another format. You'll find these example scripts online at +: export-csv.pl export-sql.py @@ -200,6 +200,14 @@ Shows a graphical report of task status by year. Shows a graphical report of task status by month. Note that 'ghistory' is an alias to 'ghistory.monthly'. +.TP +.B task ghistory.weekly +Shows a graphical report of task status by week. + +.TP +.B task ghistory.daily +Shows a graphical report of task status by day. + .TP .B task help Shows the long usage text. @@ -213,6 +221,14 @@ Shows a report of task history by year. Shows a report of task history by month. Note that 'history' is an alias to 'history.monthly'. +.TP +.B task history.weekly +Shows a report of task history by week. + +.TP +.B task history.daily +Shows a report of task history by day. + .TP .B task ids Applies the filter then extracts only the task IDs and presents them as @@ -231,9 +247,8 @@ This command is mainly of use to external scripts. .TP .B task uuids Applies the filter on all tasks (even deleted and completed tasks) -then extracts only the task UUIDs and presents them as -a comma-separated list. This is useful as input to a task command, to achieve -this: +then extracts only the task UUIDs and presents them as a space-separated list. +This is useful as input to a task command, to achieve this: task $(task project:Home status:completed uuids) modify status:pending @@ -279,9 +294,9 @@ value. .TP .B task ready -Shows a page of the most urgent ready tasks, sorted by urgency. A ready task is -one that is either unscheduled, or has a scheduled date that is past and has no -wait date. +Shows a page of the most urgent ready tasks, sorted by urgency with started +tasks first. A ready task is one that is either unscheduled, or has a scheduled +date that is past and has no wait date. .TP .B task oldest @@ -376,6 +391,14 @@ Modifies the existing task with provided information. .B task prepend Prepends description text to an existing task. +.TP +.B task purge +Permanently removes the specified tasks from the data files. Only +tasks that are alredy deleted can be purged. This command has a +local-only effect and changes introduced by it are not synced. + +Warning: causes permanent, non-revertible loss of data. + .TP .B task start Marks the specified tasks as started. @@ -408,7 +431,7 @@ Examples: 2015-03-31T23:59:59 .TP -.B task config [name [value | '']] +.B task config [ [ | '']] Add, modify and remove settings directly in the Taskwarrior configuration. This command either modifies the 'name' setting with a new value of 'value', or adds a new entry that is equivalent to 'name=value': @@ -493,7 +516,7 @@ Lists all supported reports. This includes the built-in reports, and any custom reports you have defined. .TP -.B task show [all | substring] +.B task show [all | ] Shows all the current settings. If a substring is specified just the settings containing that substring will be displayed. @@ -506,6 +529,25 @@ Shows statistics of the tasks defined by the filter. .B task summary Shows a report of aggregated task status by project. +.TP +.B task sync [init] +The sync command synchronizes data with the Taskserver, if configured. + +The init subcommand should only ever be run once, and only on one client, because +it sends all data to the Taskserver. This allows all the subsequent sync commands +to only send small deltas. + +Note: If you use multiple sync clients, make sure this setting (which is the default) +is on your primary client: + + recurrence=on + +and on all other clients (this is not the default): + + recurrence=off + +This is a workaround to avoid a recurrence bug that duplicates recurring tasks. + .TP .B task tags Show a list of all tags used. Any special tags used are highlighted. Note that @@ -514,7 +556,7 @@ notation for other task metadata. It is an error to attempt to add or remove a virtual tag. .TP -.B task timesheet [weeks] +.B task timesheet [] Shows a weekly report of tasks completed and started. .TP @@ -610,10 +652,16 @@ Accesses and displays the DOM reference(s). Used to extract individual values from tasks, or the system. Supported DOM references are: rc. - context.program - context.args - context.width - context.height + tw.syncneeded + tw.program + tw.args + tw.width + tw.height + tw.version + context.program (Deprecated in 2.6.0) + context.args (Deprecated in 2.6.0) + context.width (Deprecated in 2.6.0) + context.height (Deprecated in 2.6.0) system.version system.os . @@ -633,7 +681,7 @@ extracted by DOM references. For a full list of supported attribute-specific DOM references, consult the online documentation at: - + .SH ATTRIBUTES AND METADATA @@ -674,7 +722,6 @@ are: COMPLETED Matches if the task has completed status DELETED Matches if the task has deleted status DUE Matches if the task is due - DUETODAY Matches if the task is due today LATEST Matches if the task is the newest added task MONTH Matches if the task is due this month ORPHAN Matches if the task has any orphaned UDA values @@ -683,6 +730,7 @@ are: PENDING Matches if the task has pending status PRIORITY Matches if the task has a priority PROJECT Matches if the task has a project + QUARTER Matches if the task is due this quarter READY Matches if the task is actionable SCHEDULED Matches if the task is scheduled TAGGED Matches if the task has tags @@ -780,6 +828,13 @@ Attribute modifiers improve filters. Supported modifiers are: .B noword .RE +They can be applied to all regular attributes (see above) and the following +calculated attributes: + +.RS +\fBurgency\fR (or short \fBurg\fR) +.RE + For example: .RS @@ -1040,6 +1095,8 @@ task ... due:pentecost task ... due:midsommar .br task ... due:midsommarafton +.br +task ... due:juhannus .RE .SS FREQUENCIES @@ -1243,7 +1300,7 @@ the 'data.location' configuration setting of the task data directory. For examples please see the online documentation starting at .RS - + .RE Note that the online documentation can be more detailed and more current than @@ -1275,10 +1332,10 @@ The file that contains the completed ("done") tasks. The file that contains information needed by the "undo" command. .SH "CREDITS & COPYRIGHTS" -Copyright (C) 2006 \- 2016 P. Beckingham, F. Hernandez. +Copyright (C) 2006 \- 2020 P. Beckingham, F. Hernandez. Taskwarrior is distributed under the MIT license. See -http://www.opensource.org/licenses/mit-license.php for more information. +https://www.opensource.org/licenses/mit-license.php for more information. .SH SEE ALSO .BR taskrc(5), @@ -1289,18 +1346,17 @@ For more information regarding Taskwarrior, see the following: .TP The official site at - + .TP The official code repository at - + .TP You can contact the project by emailing - + .SH REPORTING BUGS .TP Bugs in Taskwarrior may be reported to the issue-tracker at - - + diff --git a/doc/man/taskrc.5.in b/doc/man/taskrc.5.in index 2de7799bf..f9990c149 100644 --- a/doc/man/taskrc.5.in +++ b/doc/man/taskrc.5.in @@ -55,7 +55,7 @@ default, sample .I .taskrc file in the user's home directory. -The .taskrc file follows a very simply syntax defining name/value pairs: +The .taskrc file follows a very simple syntax defining name/value pairs: .RS = @@ -68,8 +68,8 @@ 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". +items. You can use "1" to enable, anything else is interpreted as disabled. +The values "on", "yes", "y" and "true" are currently supported but deprecated. .RS include @@ -181,33 +181,37 @@ shell meta character, which will be properly expanded. Note that the TASKDATA environment variable overrides this setting. .TP -.B locking=on +.B hooks.location=$HOME/.task/hooks +This is a path to the hook scripts directory. By default it is ~/.task/hooks. + +.TP +.B locking=1 Determines whether to use file locking when accessing the pending.data and -completed.data files. Defaults to "on". Solaris users who store the data -files on an NFS mount may need to set locking to "off". Note that there is -danger in setting this value to "off" - another program (or another instance of +completed.data files. Defaults to "1". Solaris users who store the data +files on an NFS mount may need to set locking to "0". Note that there is +danger in setting this value to "0" - another program (or another instance of task) may write to the task.pending file at the same time. .TP -.B gc=on +.B gc=1 Can be used to temporarily suspend garbage collection (gc), so that task IDs don't change. Note that this should be used in the form of a command line -override (task rc.gc=off ...), and not permanently used in the .taskrc file, +override (task rc.gc=0 ...), and not permanently used in the .taskrc file, as this significantly affects performance in the long term. .TP -.B hooks=on +.B hooks=1 This master control switch enables hook script processing. The default value -is 'on', but certain extensions and environments may need to disable hooks. +is '1', but certain extensions and environments may need to disable hooks. .TP -.B exit.on.missing.db=no -When set to 'yes' causes the program to exit if the database (~/.task or -rc.data.location or TASKDATA override) is missing. Default value is 'no'. +.B exit.on.missing.db=0 +When set to '1' causes the program to exit if the database (~/.task or +rc.data.location or TASKDATA override) is missing. Default value is '0'. .SS TERMINAL .TP -.B detection=on +.B detection=1 Determines whether to use ioctl to establish the size of the window you are using, for text wrapping. @@ -225,14 +229,14 @@ to 24. If set to 0, it is interpreted as infinite height. This is useful when re charts to a file for subsequent handling. .TP -.B avoidlastcolumn=no +.B avoidlastcolumn=0 Causes the width of the terminal minus one to be used as the full width. This avoids placing color codes in the last column which can cause problems for -Cygwin users. Default value is 'no'. +Cygwin users. Default value is '0'. .TP -.B hyphenate=on -Hyphenates lines when wrapping breaks occur mid-word. Default value is 'on'. +.B hyphenate=1 +Hyphenates lines when wrapping breaks occur mid-word. Default value is '1'. .TP .B editor=vi @@ -250,9 +254,9 @@ prompt. This is only referenced when 'limit:page' is used. .SS MISCELLANEOUS .TP -.B verbose=on|off|nothing|list... -When set to "on" (the default), helpful explanatory comments are added to all -output from Taskwarrior. Setting this to "off" means that you would see regular +.B verbose=1|0|nothing|list... +When set to "1" (the default), helpful explanatory comments are added to all +output from Taskwarrior. Setting this to "0" means that you would see regular output. The special value "nothing" can be used to eliminate all optional output, which @@ -263,8 +267,8 @@ Alternatively, you can specify a comma-separated list of verbosity tokens that control specific occasions when output is generated. This list may contain: blank Inserts extra blank lines in output, for clarity - header Messages that appear before report output - footnote Messages that appear after report output + header Messages that appear before report output (this includes .taskrc/.task overrides and the "[task next]" message) + footnote Messages that appear after report output (mostly status messages and change descriptions) label Column labels on tabular reports new-id Provides feedback of any new task IDs new-uuid Provides feedback of any new task UUIDs. Deprecated, to be @@ -276,19 +280,21 @@ control specific occasions when output is generated. This list may contain: sync Feedback about sync filter Shows the filter used in the command unwait Notification when a task leaves the 'waiting' state + override Notification when configuration options are overridden recur Notification when a new recurring task instance is created -"affected", "new-id", "new-uuid" "project" and "unwait" imply "footnote". +"affected", "new-id", "new-uuid", "project", "unwait", "override" and "recur" +imply "footnote". -Note that the "on" setting is equivalent to all the tokens being specified, +Note that the "1" setting is equivalent to all the tokens being specified, and the "nothing" setting is equivalent to none of the tokens being specified. Here are the shortcut equivalents: verbose=on - verbose=blank,header,footnote,label,new-id,affected,edit,special,project,sync,filter,unwait + verbose=blank,header,footnote,label,new-id,affected,edit,special,project,sync,filter,unwait,override - verbose=off + verbose=0 verbose=blank,label,new-id,edit verbose=nothing @@ -298,16 +304,16 @@ Those additional comments are sent to the standard error for header, footnote and project. The others are sent to standard output. .TP -.B confirmation=yes -May be "yes" or "no", and determines whether Taskwarrior will ask for +.B confirmation=1 +May be "1" or "0", and determines whether Taskwarrior will ask for confirmation before deleting a task or performing the undo command. The default -value is "yes". Consider leaving this setting as "yes", for safety. +value is "1". Consider leaving this enabled, for safety. .TP -.B allow.empty.filter=yes +.B allow.empty.filter=1 An empty filter combined with a write command is potentially a way to modify 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 +Setting this to '0' means that it is an error to use a write command with no filter. .TP @@ -344,47 +350,47 @@ 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=no -May be yes or no, and determines whether the 'projects' command lists all the project +.B list.all.projects=0 +May be "1" or "0", 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". +"0". .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". +.B summary.all.projects=0 +If set to "1", shows all projects in the summary report, even if there are no +pending tasks. The default value is "0". .TP -.B complete.all.tags=yes -May be yes or no, and determines whether the tab completion scripts consider all +.B complete.all.tags=1 +May be "1" or "0", and determines whether the tab completion scripts consider all the tag names you have used, or just the ones used in active tasks. The default -value is "no". +value is "0". .TP -.B list.all.tags=yes -May be yes or no, and determines whether the 'tags' command lists all the tag +.B list.all.tags=1 +May be "1" or "0", and determines whether the 'tags' command lists all the tag names you have used, or just the ones used in active tasks. The default value is -"no". +"0". .TP -.B print.empty.columns=no -May be yes or no, and determines whether columns with no data for any task are -printed. Defaults to no. +.B print.empty.columns=1 +May be "1" or "0", and determines whether columns with no data for any task are +printed. Defaults to "0". .TP -.B search.case.sensitive=yes -May be yes or no, and determines whether keyword lookup and substitutions on the -description and annotations are done in a case sensitive way. Defaults to yes on -most platforms. Defaults to no on Cygwin due to older regex library problems with +.B search.case.sensitive=1 +May be "1" or "0", and determines whether keyword lookup and substitutions on the +description and annotations are done in a case sensitive way. Defaults to "1" on +most platforms. Defaults to "0" on Cygwin due to older regex library problems with case-insensitivity. .TP -.B regex=on -Controls whether regular expression support is enabled. The default value is on. +.B regex=1 +Controls whether regular expression support is enabled. The default value is "1". .TP -.B xterm.title=no -Sets the xterm window title when reports are run. Defaults to off. +.B xterm.title=1 +Sets the xterm window title when reports are run. Defaults to "0". .TP .B expressions=infix|postfix @@ -392,21 +398,21 @@ Sets a preference for infix expressions (1 + 2) or postfix expressions (1 2 +). Defaults to infix. .TP -.B json.array=on +.B json.array=1 Determines whether the export command encloses the JSON output in '[...]' and adds ',' after each exported task object to create a properly-formed JSON array. -With json.array=off, export writes raw JSON objects to STDOUT, one per line. -Defaults to on. +With json.array=0, export writes raw JSON objects to STDOUT, one per line. +Defaults to "1". .TP -.B json.depends.array=on +.B json.depends.array=1 Determines whether the export command encodes dependencies as an array of string UUIDs, or one comma-separated string. -Defaults to on. +Defaults to "1". .TP -.B _forcecolor=no +.B _forcecolor=1 Taskwarrior shuts off color automatically when the output is not sent directly to a TTY. For example, this command: @@ -422,6 +428,8 @@ $ task rc._forcecolor=yes list > file .RE .RE +Defaults to "0". + .TP .B active.indicator=* The character or string to show in the start.active column. Defaults to *. @@ -439,9 +447,13 @@ The character or string to show in the depends.indicator column. Defaults to +. The character or string to show in the .indicator column. Defaults to U. .TP -.B recurrence=yes +.B recurrence=1 Controls whether recurrence is enabled, and whether recurring tasks continue to -generate new task instances. Defaults to 'yes'. +generate new task instances. Defaults to "1". + +If you are syncing multiple clients, then it is advised that you set 'recurrence=1' +on your primary client, and 'recurrence=0' on ALL other clients. This is a workaround +for a duplication bug. .TP .B recurrence.confirmation=prompt @@ -475,7 +487,7 @@ Minimum length of any abbreviated command/value. This means that "ve", "ver", Default is 2. .TP -.B debug=off +.B debug=0 Taskwarrior has a debug mode that causes diagnostic output to be displayed. Typically this is not something anyone would want, but when reporting a bug, debug output can be useful. It can also help explain how the command line is @@ -483,7 +495,7 @@ being parsed, but the information is displayed in a developer-friendly, not a user-friendly way. Turning debug on automatically sets debug.hooks=1, debug.parser=1 and debug.tls=2 -if they do not already have assigned values. +if they do not already have assigned values. Defaults to "0". .TP .B debug.hooks=0 @@ -583,6 +595,8 @@ S two-digit seconds, for example 07 or 47 J three-digit Julian day, for example 023 or 365 .br j Julian day, for example 23 or 365 +.br +w Week day, for example 0 for Monday, 5 for Friday .RE .RE @@ -645,8 +659,8 @@ field that is set. Otherwise, they are set to the corresponding values of .RE .TP -.B date.iso=yes -Enables ISO-8601 date support. The default value is "yes". +.B date.iso=1 +Enables ISO-8601 date support. The default value is "1". .TP .B weekstart=Sunday @@ -654,10 +668,10 @@ Determines the day a week starts. Valid values are Sunday or Monday only. The default value is "Sunday". .TP -.B displayweeknumber=yes +.B displayweeknumber=1 Determines if week numbers are displayed when using the "task calendar" command. The week number is dependent on the day a week starts. The default value is -"yes". +"1". .TP .B due=7 @@ -666,11 +680,11 @@ considered due, and is colored accordingly. The default value is 7. .TP .B calendar.details=sparse -If set to full running "task calendar" will display the details of tasks with +If set to "full" running "task calendar" will display the details of tasks with due dates that fall into the calendar period. The corresponding days will be -color-coded in the calendar. If set to sparse only the corresponding days will +color-coded in the calendar. If set to "sparse" only the corresponding days will be color coded and no details will be displayed. The displaying of due dates -with details is turned off by setting the variable to none. The default value +with details is turned off by setting the variable to "none". The default value is "sparse". .TP @@ -679,9 +693,9 @@ The report to run when displaying the details of tasks with due dates when running the "task calendar" command. The default value is "list". .TP -.B calendar.offset=off -If "on" the first month in the calendar report is effectively changed by the -offset value specified in calendar.offset.value. It defaults to "off". +.B calendar.offset=0 +If "1" the first month in the calendar report is effectively changed by the +offset value specified in calendar.offset.value. It defaults to "0". .TP .B calendar.offset.value=-1 @@ -697,15 +711,15 @@ and no details on the holidays will be displayed. The displaying of holidays is turned off by setting the variable to none. The default value is "none". .TP -.B calendar.legend=yes -Determines whether the calendar legend is displayed. The default value is "yes". +.B calendar.legend=1 +Determines whether the calendar legend is displayed. The default value is "1". .SS JOURNAL ENTRIES .TP -.B journal.time=no -May be yes or no, and determines whether the 'start' and 'stop' commands should -record an annotation when being executed. The default value is "no". The text of +.B journal.time=0 +May be "1" or "0", and determines whether the 'start' and 'stop' commands should +record an annotation when being executed. The default value is "0". The text of the corresponding annotations is controlled by: .TP @@ -719,9 +733,9 @@ The text of the annotation that is recorded when executing the stop command and having set journal.time. .TP -.B journal.info=on +.B journal.info=1 When enabled, this setting causes a change log of each task to be displayed by -the 'info' command. Default value is "on". +the 'info' command. Default value is "1". .SS HOLIDAYS Holidays are entered either directly in the .taskrc file or via an include file @@ -780,22 +794,22 @@ specified, Taskwarrior will only show as many that will fit. .SS DEPENDENCIES .TP -.B dependency.reminder=on +.B dependency.reminder=1 Determines whether dependency chain violations generate reminders. .TP -.B dependency.confirmation=yes +.B dependency.confirmation=1 Determines whether dependency chain repair requires confirmation. .SS COLOR CONTROLS .TP -.B color=on -May be "on" or "off". Determines whether Taskwarrior uses color. When "off", +.B color=1 +May be "1" or "0". Determines whether Taskwarrior uses color. When "0", will use dashes (-----) to underline column headings. .TP -.B fontunderline=on +.B fontunderline=1 Determines if font underlines or ASCII dashes should be used to underline headers, even when color is enabled. .RE @@ -806,7 +820,7 @@ automatic coloring of that task. A list of valid colors, depending on your terminal, can be obtained by running the command: .RS -.B task color +.B task colors .RE .RS @@ -878,12 +892,11 @@ desired. In such cases, use the following option to disable this behaviour: .RE .TP -.B rule.color.merge=yes -Can be "yes" or "no". When "no", disables merging of colors produced by +.B rule.color.merge=1 +Can be "1" or "0". When "0", disables merging of colors produced by different color rules. Use if your color scheme produces unpleasing foreground and background combinations. - See the task-color(5) man pages for color details. .RE @@ -1056,7 +1069,7 @@ Colors the output of the sync command. .TP .B rule.precedence.color=due.today,active,blocking,blocked,overdue,due, .B scheduled,keyword.,project.,tag.,uda.,recurring, -.B pri.,tagged,completed,deleted +.B tagged,completed,deleted .RS This setting specifies the precedence of the color rules, from highest to lowest. Note that the prefix 'color.' is omitted (for brevity), and that any @@ -1149,7 +1162,7 @@ The coefficients reflect the relative importance of the various terms in the urgency calculation. These are default values, and may be modified to suit your preferences, but it is important that you carefully consider any modifications. -.B urgency.inherit=off +.B urgency.inherit=0 .RS Not actually a coefficient. When enabled, blocking tasks inherit the highest urgency value found in the tasks they block. This is @@ -1176,6 +1189,14 @@ Provides a default due date for the command, if you don't specify one. You can use a date, or a duration value which is assumed to be relative to 'now'. The default is blank. +.TP +.B +default.scheduled=... +Provides a default scheduled date for the +.I task add +command, if you don't specify one. You can use a date, or a duration value which +is assumed to be relative to 'now'. The default is blank. + .TP .B uda..default=... @@ -1264,6 +1285,9 @@ will be presented in the order (if any) in which they are selected. This adds a filter to the report X so that only tasks matching the filter criteria are displayed in the generated report. +There is a special case for 'report.timesheet.filter', which may be specified +even though the 'timesheet' report is not very customizable. + .TP .B report.X.dateformat This adds a dateformat to the report X that will be used by the "due date" @@ -1488,12 +1512,12 @@ Default is "NORMAL". See GnuTLS documentation for full details. .RE .SH "CREDITS & COPYRIGHTS" -Copyright (C) 2006 \- 2016 P. Beckingham, F. Hernandez. +Copyright (C) 2006 \- 2020 P. Beckingham, F. Hernandez. This man page was originally written by Federico Hernandez. Taskwarrior is distributed under the MIT license. See -http://www.opensource.org/licenses/mit-license.php for more information. +https://www.opensource.org/licenses/mit-license.php for more information. .SH SEE ALSO .BR task(1), @@ -1504,18 +1528,17 @@ For more information regarding Taskwarrior, see the following: .TP The official site at - + .TP The official code repository at - + .TP You can contact the project by emailing - + .SH REPORTING BUGS .TP Bugs in Taskwarrior may be reported to the issue-tracker at - - + diff --git a/doc/misc/themes/README b/doc/misc/themes/README index aaf1af97b..37a373e58 100644 --- a/doc/misc/themes/README +++ b/doc/misc/themes/README @@ -1,5 +1,8 @@ Themes +These scripts are a way to generate a little sample data, and show the color +themes. It is not intended for general use. + To generate samples of themes, first execute the 'setup' script to generate the sample data. Note that this data may need to be tweaked to include qualities that need to be illustrated in theme sample. diff --git a/doc/rc/dark-16.theme b/doc/rc/dark-16.theme index c23a818a9..540983863 100644 --- a/doc/rc/dark-16.theme +++ b/doc/rc/dark-16.theme @@ -1,6 +1,6 @@ ############################################################################### # -# Copyright 2006 - 2016, Paul Beckingham, Federico Hernandez. +# Copyright 2006 - 2020, 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 @@ -20,7 +20,7 @@ # 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 +# https://www.opensource.org/licenses/mit-license.php # ############################################################################### diff --git a/doc/rc/dark-256.theme b/doc/rc/dark-256.theme index 8f44614b5..2a83ecc76 100644 --- a/doc/rc/dark-256.theme +++ b/doc/rc/dark-256.theme @@ -1,6 +1,6 @@ ############################################################################### # -# Copyright 2006 - 2016, Paul Beckingham, Federico Hernandez. +# Copyright 2006 - 2020, 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 @@ -20,7 +20,7 @@ # 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 +# https://www.opensource.org/licenses/mit-license.php # ############################################################################### diff --git a/doc/rc/dark-blue-256.theme b/doc/rc/dark-blue-256.theme index 7ed86d44e..2d494ec67 100644 --- a/doc/rc/dark-blue-256.theme +++ b/doc/rc/dark-blue-256.theme @@ -1,6 +1,6 @@ ############################################################################### # -# Copyright 2006 - 2016, Paul Beckingham, Federico Hernandez. +# Copyright 2006 - 2020, 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 @@ -20,7 +20,7 @@ # 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 +# https://www.opensource.org/licenses/mit-license.php # ############################################################################### diff --git a/doc/rc/dark-gray-256.theme b/doc/rc/dark-gray-256.theme index 13732186e..fd7f42efd 100644 --- a/doc/rc/dark-gray-256.theme +++ b/doc/rc/dark-gray-256.theme @@ -1,6 +1,6 @@ ############################################################################### # -# Copyright 2006 - 2016, Paul Beckingham, Federico Hernandez. +# Copyright 2006 - 2020, 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 @@ -20,7 +20,7 @@ # 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 +# https://www.opensource.org/licenses/mit-license.php # ############################################################################### diff --git a/doc/rc/dark-gray-blue-256.theme b/doc/rc/dark-gray-blue-256.theme index 1212eb520..2acd71014 100644 --- a/doc/rc/dark-gray-blue-256.theme +++ b/doc/rc/dark-gray-blue-256.theme @@ -1,6 +1,6 @@ ############################################################################### # -# Copyright 2006 - 2016, Paul Beckingham, Federico Hernandez. +# Copyright 2006 - 2020, 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 @@ -20,7 +20,7 @@ # 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 +# https://www.opensource.org/licenses/mit-license.php # ############################################################################### diff --git a/doc/rc/dark-green-256.theme b/doc/rc/dark-green-256.theme index b015f6fa7..643ba3a2d 100644 --- a/doc/rc/dark-green-256.theme +++ b/doc/rc/dark-green-256.theme @@ -1,6 +1,6 @@ ############################################################################### # -# Copyright 2006 - 2016, Paul Beckingham, Federico Hernandez. +# Copyright 2006 - 2020, 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 @@ -20,7 +20,7 @@ # 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 +# https://www.opensource.org/licenses/mit-license.php # ############################################################################### diff --git a/doc/rc/dark-red-256.theme b/doc/rc/dark-red-256.theme index c577986bc..5c0853e41 100644 --- a/doc/rc/dark-red-256.theme +++ b/doc/rc/dark-red-256.theme @@ -1,6 +1,6 @@ ############################################################################### # -# Copyright 2006 - 2016, Paul Beckingham, Federico Hernandez. +# Copyright 2006 - 2020, 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 @@ -20,7 +20,7 @@ # 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 +# https://www.opensource.org/licenses/mit-license.php # ############################################################################### diff --git a/doc/rc/dark-violets-256.theme b/doc/rc/dark-violets-256.theme index 265a94a32..daecafcbd 100644 --- a/doc/rc/dark-violets-256.theme +++ b/doc/rc/dark-violets-256.theme @@ -1,6 +1,6 @@ ############################################################################### # -# Copyright 2006 - 2016, Paul Beckingham, Federico Hernandez. +# Copyright 2006 - 2020, 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 @@ -20,7 +20,7 @@ # 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 +# https://www.opensource.org/licenses/mit-license.php # ############################################################################### diff --git a/doc/rc/dark-yellow-green.theme b/doc/rc/dark-yellow-green.theme index a09d6efef..9a76cf027 100644 --- a/doc/rc/dark-yellow-green.theme +++ b/doc/rc/dark-yellow-green.theme @@ -1,6 +1,6 @@ ############################################################################### # -# Copyright 2006 - 2016, Paul Beckingham, Federico Hernandez. +# Copyright 2006 - 2020, 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 @@ -20,7 +20,7 @@ # 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 +# https://www.opensource.org/licenses/mit-license.php # ############################################################################### diff --git a/doc/rc/holidays.be-BY.rc b/doc/rc/holidays.be-BY.rc deleted file mode 100644 index 92722c970..000000000 --- a/doc/rc/holidays.be-BY.rc +++ /dev/null @@ -1,69 +0,0 @@ -############################################################################### -# International Holiday Data provided by Holidata.net -# http://holidata.net/be-BY/2015.json -# http://holidata.net/be-BY/2016.json -# -# Copyright 2006 - 2016, 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 -# -############################################################################### - -holiday.be-BY1.name=Новы Год -holiday.be-BY1.date=20150101 -holiday.be-BY2.name=Раство Хрыстова(праваслаўнае) -holiday.be-BY2.date=20150107 -holiday.be-BY3.name=Міжнародны жаночы дзень -holiday.be-BY3.date=20150803 -holiday.be-BY4.name=Пасха(праваслаўная) -holiday.be-BY4.date=20150420 -holiday.be-BY5.name=Радуніца -holiday.be-BY5.date=20150421 -holiday.be-BY6.name=Свята працы -holiday.be-BY6.date=20150501 -holiday.be-BY7.name=Дзень Перамогі -holiday.be-BY7.date=20150509 -holiday.be-BY8.name=Дзень незалежнаці -holiday.be-BY8.date=20150703 -holiday.be-BY9.name=Дзень Кастрычніцкай рэвалюцыі -holiday.be-BY9.date=20151107 -holiday.be-BY10.name=Раство Хрыстова(у заходніх хрысціян) -holiday.be-BY10.date=20151225 -holiday.be-BY11.name=Новы Год -holiday.be-BY11.date=20160101 -holiday.be-BY12.name=Раство Хрыстова(праваслаўнае) -holiday.be-BY12.date=20160107 -holiday.be-BY13.name=Міжнародны жаночы дзень -holiday.be-BY13.date=20160803 -holiday.be-BY14.name=Пасха(праваслаўная) -holiday.be-BY14.date=20160327 -holiday.be-BY15.name=Радуніца -holiday.be-BY15.date=20160510 -holiday.be-BY16.name=Свята працы -holiday.be-BY16.date=20160501 -holiday.be-BY17.name=Дзень Перамогі -holiday.be-BY17.date=20160509 -holiday.be-BY18.name=Дзень незалежнаці -holiday.be-BY18.date=20160703 -holiday.be-BY19.name=Дзень Кастрычніцкай рэвалюцыі -holiday.be-BY19.date=20161107 -holiday.be-BY20.name=Раство Хрыстова(у заходніх хрысціян) -holiday.be-BY20.date=20161225 diff --git a/doc/rc/holidays.cs-CZ.rc b/doc/rc/holidays.cs-CZ.rc index 653e80e7f..f898c5961 100644 --- a/doc/rc/holidays.cs-CZ.rc +++ b/doc/rc/holidays.cs-CZ.rc @@ -1,9 +1,9 @@ ############################################################################### # International Holiday Data provided by Holidata.net -# http://holidata.net/cs-CZ/2015.json -# http://holidata.net/cs-CZ/2016.json +# https://holidata.net/cs-CZ/2020.json +# https://holidata.net/cs-CZ/2021.json # -# Copyright 2006 - 2016, Paul Beckingham, Federico Hernandez. +# Copyright 2006 - 2020, 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 @@ -23,59 +23,63 @@ # 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 +# https://www.opensource.org/licenses/mit-license.php # ############################################################################### holiday.cs-CZ1.name=Nový rok -holiday.cs-CZ1.date=20150101 -holiday.cs-CZ2.name=Den obnovy samostatnosti českého státu -holiday.cs-CZ2.date=20150101 -holiday.cs-CZ3.name=Velikonoční pondělí -holiday.cs-CZ3.date=20150406 -holiday.cs-CZ4.name=Svátek práce -holiday.cs-CZ4.date=20150501 -holiday.cs-CZ5.name=Den vítězství -holiday.cs-CZ5.date=20150508 -holiday.cs-CZ6.name=Den slovanských věrozvěstů -holiday.cs-CZ6.date=20150705 -holiday.cs-CZ7.name=Den upálení mistra Jana Husa -holiday.cs-CZ7.date=20150706 -holiday.cs-CZ8.name=Den české státnosti -holiday.cs-CZ8.date=20150928 -holiday.cs-CZ9.name=Den vzniku samostatného československého státu -holiday.cs-CZ9.date=20151028 -holiday.cs-CZ10.name=Den boje za svobodu a demokracii -holiday.cs-CZ10.date=20151117 -holiday.cs-CZ11.name=Štědrý den -holiday.cs-CZ11.date=20151224 -holiday.cs-CZ12.name=1. svátek vánoční -holiday.cs-CZ12.date=20151225 -holiday.cs-CZ13.name=2. svátek vánoční -holiday.cs-CZ13.date=20151226 -holiday.cs-CZ14.name=Nový rok -holiday.cs-CZ14.date=20160101 -holiday.cs-CZ15.name=Den obnovy samostatnosti českého státu -holiday.cs-CZ15.date=20160101 -holiday.cs-CZ16.name=Velikonoční pondělí -holiday.cs-CZ16.date=20160328 -holiday.cs-CZ17.name=Svátek práce -holiday.cs-CZ17.date=20160501 -holiday.cs-CZ18.name=Den vítězství -holiday.cs-CZ18.date=20160508 -holiday.cs-CZ19.name=Den slovanských věrozvěstů -holiday.cs-CZ19.date=20160705 -holiday.cs-CZ20.name=Den upálení mistra Jana Husa -holiday.cs-CZ20.date=20160706 -holiday.cs-CZ21.name=Den české státnosti -holiday.cs-CZ21.date=20160928 -holiday.cs-CZ22.name=Den vzniku samostatného československého státu -holiday.cs-CZ22.date=20161028 -holiday.cs-CZ23.name=Den boje za svobodu a demokracii -holiday.cs-CZ23.date=20161117 -holiday.cs-CZ24.name=Štědrý den -holiday.cs-CZ24.date=20161224 -holiday.cs-CZ25.name=1. svátek vánoční -holiday.cs-CZ25.date=20161225 -holiday.cs-CZ26.name=2. svátek vánoční -holiday.cs-CZ26.date=20161226 +holiday.cs-CZ1.date=20200101 +holiday.cs-CZ2.name=Den obnovy samostatného českého státu +holiday.cs-CZ2.date=20200101 +holiday.cs-CZ3.name=Velký pátek +holiday.cs-CZ3.date=20200410 +holiday.cs-CZ4.name=Velikonoční pondělí +holiday.cs-CZ4.date=20200413 +holiday.cs-CZ5.name=Svátek práce +holiday.cs-CZ5.date=20200501 +holiday.cs-CZ6.name=Den vítězství +holiday.cs-CZ6.date=20200508 +holiday.cs-CZ7.name=Den slovanských věrozvěstů Cyrila a Metoděje +holiday.cs-CZ7.date=20200705 +holiday.cs-CZ8.name=Den upálení mistra Jana Husa +holiday.cs-CZ8.date=20200706 +holiday.cs-CZ9.name=Den české státnosti +holiday.cs-CZ9.date=20200928 +holiday.cs-CZ10.name=Den vzniku samostatného československého státu +holiday.cs-CZ10.date=20201028 +holiday.cs-CZ11.name=Den boje za svobodu a demokracii a Mezinárodní den studentstva +holiday.cs-CZ11.date=20201117 +holiday.cs-CZ12.name=Štědrý den +holiday.cs-CZ12.date=20201224 +holiday.cs-CZ13.name=1. svátek vánoční +holiday.cs-CZ13.date=20201225 +holiday.cs-CZ14.name=2. svátek vánoční +holiday.cs-CZ14.date=20201226 +holiday.cs-CZ15.name=Nový rok +holiday.cs-CZ15.date=20210101 +holiday.cs-CZ16.name=Den obnovy samostatného českého státu +holiday.cs-CZ16.date=20210101 +holiday.cs-CZ17.name=Velký pátek +holiday.cs-CZ17.date=20210402 +holiday.cs-CZ18.name=Velikonoční pondělí +holiday.cs-CZ18.date=20210405 +holiday.cs-CZ19.name=Svátek práce +holiday.cs-CZ19.date=20210501 +holiday.cs-CZ20.name=Den vítězství +holiday.cs-CZ20.date=20210508 +holiday.cs-CZ21.name=Den slovanských věrozvěstů Cyrila a Metoděje +holiday.cs-CZ21.date=20210705 +holiday.cs-CZ22.name=Den upálení mistra Jana Husa +holiday.cs-CZ22.date=20210706 +holiday.cs-CZ23.name=Den české státnosti +holiday.cs-CZ23.date=20210928 +holiday.cs-CZ24.name=Den vzniku samostatného československého státu +holiday.cs-CZ24.date=20211028 +holiday.cs-CZ25.name=Den boje za svobodu a demokracii a Mezinárodní den studentstva +holiday.cs-CZ25.date=20211117 +holiday.cs-CZ26.name=Štědrý den +holiday.cs-CZ26.date=20211224 +holiday.cs-CZ27.name=1. svátek vánoční +holiday.cs-CZ27.date=20211225 +holiday.cs-CZ28.name=2. svátek vánoční +holiday.cs-CZ28.date=20211226 diff --git a/doc/rc/holidays.da-DK.rc b/doc/rc/holidays.da-DK.rc index 86e0ce742..4d2a7cab8 100644 --- a/doc/rc/holidays.da-DK.rc +++ b/doc/rc/holidays.da-DK.rc @@ -1,9 +1,9 @@ ############################################################################### # International Holiday Data provided by Holidata.net -# http://holidata.net/da-DK/2015.json -# http://holidata.net/da-DK/2016.json +# https://holidata.net/da-DK/2020.json +# https://holidata.net/da-DK/2021.json # -# Copyright 2006 - 2016, Paul Beckingham, Federico Hernandez. +# Copyright 2006 - 2020, 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 @@ -23,51 +23,55 @@ # 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 +# https://www.opensource.org/licenses/mit-license.php # ############################################################################### holiday.da-DK1.name=Nytårsdag -holiday.da-DK1.date=20150101 +holiday.da-DK1.date=20200101 holiday.da-DK2.name=Skærtorsdag -holiday.da-DK2.date=20150402 +holiday.da-DK2.date=20200409 holiday.da-DK3.name=Langfredag -holiday.da-DK3.date=20150403 +holiday.da-DK3.date=20200410 holiday.da-DK4.name=Påskedag -holiday.da-DK4.date=20150405 +holiday.da-DK4.date=20200412 holiday.da-DK5.name=Anden påskedag -holiday.da-DK5.date=20150406 -holiday.da-DK6.name=Kristi himmelfartsdag -holiday.da-DK6.date=20150514 -holiday.da-DK7.name=Pinsedag -holiday.da-DK7.date=20150524 -holiday.da-DK8.name=Anden pinsedag -holiday.da-DK8.date=20150525 -holiday.da-DK9.name=Grundlovsdag -holiday.da-DK9.date=20150605 -holiday.da-DK10.name=Juledag -holiday.da-DK10.date=20151225 -holiday.da-DK11.name=Anden juledag -holiday.da-DK11.date=20151226 -holiday.da-DK12.name=Nytårsdag -holiday.da-DK12.date=20160101 -holiday.da-DK13.name=Skærtorsdag -holiday.da-DK13.date=20160324 -holiday.da-DK14.name=Langfredag -holiday.da-DK14.date=20160325 -holiday.da-DK15.name=Påskedag -holiday.da-DK15.date=20160327 -holiday.da-DK16.name=Anden påskedag -holiday.da-DK16.date=20160328 -holiday.da-DK17.name=Kristi himmelfartsdag -holiday.da-DK17.date=20160505 -holiday.da-DK18.name=Pinsedag -holiday.da-DK18.date=20160515 -holiday.da-DK19.name=Anden pinsedag -holiday.da-DK19.date=20160516 -holiday.da-DK20.name=Grundlovsdag -holiday.da-DK20.date=20160605 -holiday.da-DK21.name=Juledag -holiday.da-DK21.date=20161225 -holiday.da-DK22.name=Anden juledag -holiday.da-DK22.date=20161226 +holiday.da-DK5.date=20200413 +holiday.da-DK6.name=Store bededag +holiday.da-DK6.date=20200508 +holiday.da-DK7.name=Kristi himmelfartsdag +holiday.da-DK7.date=20200521 +holiday.da-DK8.name=Pinsedag +holiday.da-DK8.date=20200531 +holiday.da-DK9.name=Anden pinsedag +holiday.da-DK9.date=20200601 +holiday.da-DK10.name=Grundlovsdag +holiday.da-DK10.date=20200605 +holiday.da-DK11.name=Juledag +holiday.da-DK11.date=20201225 +holiday.da-DK12.name=Anden juledag +holiday.da-DK12.date=20201226 +holiday.da-DK13.name=Nytårsdag +holiday.da-DK13.date=20210101 +holiday.da-DK14.name=Skærtorsdag +holiday.da-DK14.date=20210401 +holiday.da-DK15.name=Langfredag +holiday.da-DK15.date=20210402 +holiday.da-DK16.name=Påskedag +holiday.da-DK16.date=20210404 +holiday.da-DK17.name=Anden påskedag +holiday.da-DK17.date=20210405 +holiday.da-DK18.name=Store bededag +holiday.da-DK18.date=20210430 +holiday.da-DK19.name=Kristi himmelfartsdag +holiday.da-DK19.date=20210513 +holiday.da-DK20.name=Pinsedag +holiday.da-DK20.date=20210523 +holiday.da-DK21.name=Anden pinsedag +holiday.da-DK21.date=20210524 +holiday.da-DK22.name=Grundlovsdag +holiday.da-DK22.date=20210605 +holiday.da-DK23.name=Juledag +holiday.da-DK23.date=20211225 +holiday.da-DK24.name=Anden juledag +holiday.da-DK24.date=20211226 diff --git a/doc/rc/holidays.de-AT.rc b/doc/rc/holidays.de-AT.rc index 83c930385..9266bc2a7 100644 --- a/doc/rc/holidays.de-AT.rc +++ b/doc/rc/holidays.de-AT.rc @@ -1,9 +1,9 @@ ############################################################################### # International Holiday Data provided by Holidata.net -# http://holidata.net/de-AT/2015.json -# http://holidata.net/de-AT/2016.json +# https://holidata.net/de-AT/2020.json +# https://holidata.net/de-AT/2021.json # -# Copyright 2006 - 2016, Paul Beckingham, Federico Hernandez. +# Copyright 2006 - 2020, 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 @@ -23,103 +23,103 @@ # 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 +# https://www.opensource.org/licenses/mit-license.php # ############################################################################### holiday.de-AT1.name=Neujahr -holiday.de-AT1.date=20150101 -holiday.de-AT2.name=Heilige drei Könige -holiday.de-AT2.date=20150106 -holiday.de-AT3.name=Josef (K, St, T, V) -holiday.de-AT3.date=20150319 +holiday.de-AT1.date=20200101 +holiday.de-AT2.name=Heilige drei Könige +holiday.de-AT2.date=20200106 +holiday.de-AT3.name=Josef +holiday.de-AT3.date=20200319 holiday.de-AT4.name=Karfreitag -holiday.de-AT4.date=20150403 +holiday.de-AT4.date=20200410 holiday.de-AT5.name=Ostersonntag -holiday.de-AT5.date=20150405 +holiday.de-AT5.date=20200412 holiday.de-AT6.name=Ostermontag -holiday.de-AT6.date=20150406 +holiday.de-AT6.date=20200413 holiday.de-AT7.name=Staatsfeiertag -holiday.de-AT7.date=20150501 -holiday.de-AT8.name=Florian (O) -holiday.de-AT8.date=20150504 +holiday.de-AT7.date=20200501 +holiday.de-AT8.name=Florian +holiday.de-AT8.date=20200504 holiday.de-AT9.name=Christi Himmelfahrt -holiday.de-AT9.date=20150514 +holiday.de-AT9.date=20200521 holiday.de-AT10.name=Pfingstsonntag -holiday.de-AT10.date=20150524 +holiday.de-AT10.date=20200531 holiday.de-AT11.name=Pfingstmontag -holiday.de-AT11.date=20150525 +holiday.de-AT11.date=20200601 holiday.de-AT12.name=Fronleichnam -holiday.de-AT12.date=20150604 +holiday.de-AT12.date=20200611 holiday.de-AT13.name=Mariä Himmelfahrt -holiday.de-AT13.date=20150815 -holiday.de-AT14.name=Rupert (S) -holiday.de-AT14.date=20150924 -holiday.de-AT15.name=Tag der Volksabstimmung (K) -holiday.de-AT15.date=20151010 +holiday.de-AT13.date=20200815 +holiday.de-AT14.name=Rupert +holiday.de-AT14.date=20200924 +holiday.de-AT15.name=Tag der Volksabstimmung +holiday.de-AT15.date=20201010 holiday.de-AT16.name=Nationalfeiertag -holiday.de-AT16.date=20151026 +holiday.de-AT16.date=20201026 holiday.de-AT17.name=Allerheiligen -holiday.de-AT17.date=20151101 -holiday.de-AT18.name=Martin (B) -holiday.de-AT18.date=20151111 -holiday.de-AT19.name=Leopold (W, N) -holiday.de-AT19.date=20151115 +holiday.de-AT17.date=20201101 +holiday.de-AT18.name=Martin +holiday.de-AT18.date=20201111 +holiday.de-AT19.name=Leopold +holiday.de-AT19.date=20201115 holiday.de-AT20.name=Mariä Empfängnis -holiday.de-AT20.date=20151208 +holiday.de-AT20.date=20201208 holiday.de-AT21.name=Heiliger Abend -holiday.de-AT21.date=20151224 +holiday.de-AT21.date=20201224 holiday.de-AT22.name=Christtag -holiday.de-AT22.date=20151225 +holiday.de-AT22.date=20201225 holiday.de-AT23.name=Stefanitag -holiday.de-AT23.date=20151226 +holiday.de-AT23.date=20201226 holiday.de-AT24.name=Silvester -holiday.de-AT24.date=20151231 +holiday.de-AT24.date=20201231 holiday.de-AT25.name=Neujahr -holiday.de-AT25.date=20160101 -holiday.de-AT26.name=Heilige drei Könige -holiday.de-AT26.date=20160106 -holiday.de-AT27.name=Josef (K, St, T, V) -holiday.de-AT27.date=20160319 +holiday.de-AT25.date=20210101 +holiday.de-AT26.name=Heilige drei Könige +holiday.de-AT26.date=20210106 +holiday.de-AT27.name=Josef +holiday.de-AT27.date=20210319 holiday.de-AT28.name=Karfreitag -holiday.de-AT28.date=20160325 +holiday.de-AT28.date=20210402 holiday.de-AT29.name=Ostersonntag -holiday.de-AT29.date=20160327 +holiday.de-AT29.date=20210404 holiday.de-AT30.name=Ostermontag -holiday.de-AT30.date=20160328 +holiday.de-AT30.date=20210405 holiday.de-AT31.name=Staatsfeiertag -holiday.de-AT31.date=20160501 -holiday.de-AT32.name=Florian (O) -holiday.de-AT32.date=20160504 +holiday.de-AT31.date=20210501 +holiday.de-AT32.name=Florian +holiday.de-AT32.date=20210504 holiday.de-AT33.name=Christi Himmelfahrt -holiday.de-AT33.date=20160505 +holiday.de-AT33.date=20210513 holiday.de-AT34.name=Pfingstsonntag -holiday.de-AT34.date=20160515 +holiday.de-AT34.date=20210523 holiday.de-AT35.name=Pfingstmontag -holiday.de-AT35.date=20160516 +holiday.de-AT35.date=20210524 holiday.de-AT36.name=Fronleichnam -holiday.de-AT36.date=20160526 +holiday.de-AT36.date=20210603 holiday.de-AT37.name=Mariä Himmelfahrt -holiday.de-AT37.date=20160815 -holiday.de-AT38.name=Rupert (S) -holiday.de-AT38.date=20160924 -holiday.de-AT39.name=Tag der Volksabstimmung (K) -holiday.de-AT39.date=20161010 +holiday.de-AT37.date=20210815 +holiday.de-AT38.name=Rupert +holiday.de-AT38.date=20210924 +holiday.de-AT39.name=Tag der Volksabstimmung +holiday.de-AT39.date=20211010 holiday.de-AT40.name=Nationalfeiertag -holiday.de-AT40.date=20161026 +holiday.de-AT40.date=20211026 holiday.de-AT41.name=Allerheiligen -holiday.de-AT41.date=20161101 -holiday.de-AT42.name=Martin (B) -holiday.de-AT42.date=20161111 -holiday.de-AT43.name=Leopold (W, N) -holiday.de-AT43.date=20161115 +holiday.de-AT41.date=20211101 +holiday.de-AT42.name=Martin +holiday.de-AT42.date=20211111 +holiday.de-AT43.name=Leopold +holiday.de-AT43.date=20211115 holiday.de-AT44.name=Mariä Empfängnis -holiday.de-AT44.date=20161208 +holiday.de-AT44.date=20211208 holiday.de-AT45.name=Heiliger Abend -holiday.de-AT45.date=20161224 +holiday.de-AT45.date=20211224 holiday.de-AT46.name=Christtag -holiday.de-AT46.date=20161225 +holiday.de-AT46.date=20211225 holiday.de-AT47.name=Stefanitag -holiday.de-AT47.date=20161226 +holiday.de-AT47.date=20211226 holiday.de-AT48.name=Silvester -holiday.de-AT48.date=20161231 +holiday.de-AT48.date=20211231 diff --git a/doc/rc/holidays.de-BE.rc b/doc/rc/holidays.de-BE.rc index f5ca4a8fc..d1c8440f5 100644 --- a/doc/rc/holidays.de-BE.rc +++ b/doc/rc/holidays.de-BE.rc @@ -1,9 +1,9 @@ ############################################################################### # International Holiday Data provided by Holidata.net -# http://holidata.net/de-BE/2015.json -# http://holidata.net/de-BE/2016.json +# https://holidata.net/de-BE/2020.json +# https://holidata.net/de-BE/2021.json # -# Copyright 2006 - 2016, Paul Beckingham, Federico Hernandez. +# Copyright 2006 - 2020, 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 @@ -23,55 +23,55 @@ # 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 +# https://www.opensource.org/licenses/mit-license.php # ############################################################################### holiday.de-BE1.name=Neujahr -holiday.de-BE1.date=20150101 +holiday.de-BE1.date=20200101 holiday.de-BE2.name=Ostern -holiday.de-BE2.date=20150405 +holiday.de-BE2.date=20200412 holiday.de-BE3.name=Ostermontag -holiday.de-BE3.date=20150406 +holiday.de-BE3.date=20200413 holiday.de-BE4.name=Tag der Arbeit -holiday.de-BE4.date=20150501 +holiday.de-BE4.date=20200501 holiday.de-BE5.name=Christi Himmelfahrt -holiday.de-BE5.date=20150514 +holiday.de-BE5.date=20200521 holiday.de-BE6.name=Pfingsten -holiday.de-BE6.date=20150524 +holiday.de-BE6.date=20200531 holiday.de-BE7.name=Pfingstmontag -holiday.de-BE7.date=20150525 +holiday.de-BE7.date=20200601 holiday.de-BE8.name=Nationalfeiertag -holiday.de-BE8.date=20150721 +holiday.de-BE8.date=20200721 holiday.de-BE9.name=Mariä Himmelfahrt -holiday.de-BE9.date=20150815 +holiday.de-BE9.date=20200815 holiday.de-BE10.name=Allerheiligen -holiday.de-BE10.date=20151101 +holiday.de-BE10.date=20201101 holiday.de-BE11.name=Waffenstillstand -holiday.de-BE11.date=20151111 +holiday.de-BE11.date=20201111 holiday.de-BE12.name=Weihnacht -holiday.de-BE12.date=20151225 +holiday.de-BE12.date=20201225 holiday.de-BE13.name=Neujahr -holiday.de-BE13.date=20160101 +holiday.de-BE13.date=20210101 holiday.de-BE14.name=Ostern -holiday.de-BE14.date=20160527 +holiday.de-BE14.date=20210404 holiday.de-BE15.name=Ostermontag -holiday.de-BE15.date=20160528 +holiday.de-BE15.date=20210405 holiday.de-BE16.name=Tag der Arbeit -holiday.de-BE16.date=20160501 +holiday.de-BE16.date=20210501 holiday.de-BE17.name=Christi Himmelfahrt -holiday.de-BE17.date=20160505 +holiday.de-BE17.date=20210513 holiday.de-BE18.name=Pfingsten -holiday.de-BE18.date=20160515 +holiday.de-BE18.date=20210523 holiday.de-BE19.name=Pfingstmontag -holiday.de-BE19.date=20160516 +holiday.de-BE19.date=20210524 holiday.de-BE20.name=Nationalfeiertag -holiday.de-BE20.date=20160721 +holiday.de-BE20.date=20210721 holiday.de-BE21.name=Mariä Himmelfahrt -holiday.de-BE21.date=20160815 +holiday.de-BE21.date=20210815 holiday.de-BE22.name=Allerheiligen -holiday.de-BE22.date=20161101 +holiday.de-BE22.date=20211101 holiday.de-BE23.name=Waffenstillstand -holiday.de-BE23.date=20161111 +holiday.de-BE23.date=20211111 holiday.de-BE24.name=Weihnacht -holiday.de-BE24.date=20161225 +holiday.de-BE24.date=20211225 diff --git a/doc/rc/holidays.de-CH.rc b/doc/rc/holidays.de-CH.rc index 76df9ccca..22cabddc5 100644 --- a/doc/rc/holidays.de-CH.rc +++ b/doc/rc/holidays.de-CH.rc @@ -1,9 +1,9 @@ ############################################################################### # International Holiday Data provided by Holidata.net -# http://holidata.net/de-CH/2015.json -# http://holidata.net/de-CH/2016.json +# https://holidata.net/de-CH/2020.json +# https://holidata.net/de-CH/2021.json # -# Copyright 2006 - 2016, Paul Beckingham, Federico Hernandez. +# Copyright 2006 - 2020, 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 @@ -23,79 +23,79 @@ # 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 +# https://www.opensource.org/licenses/mit-license.php # ############################################################################### holiday.de-CH1.name=Neujahrstag -holiday.de-CH1.date=20150101 +holiday.de-CH1.date=20200101 holiday.de-CH2.name=Berchtoldstag -holiday.de-CH2.date=20150102 +holiday.de-CH2.date=20200102 holiday.de-CH3.name=Heilige Drei Könige -holiday.de-CH3.date=20150106 +holiday.de-CH3.date=20200106 holiday.de-CH4.name=Josefstag -holiday.de-CH4.date=20150319 +holiday.de-CH4.date=20200319 holiday.de-CH5.name=Karfreitag -holiday.de-CH5.date=20150403 +holiday.de-CH5.date=20200410 holiday.de-CH6.name=Ostersonntag -holiday.de-CH6.date=20150405 +holiday.de-CH6.date=20200412 holiday.de-CH7.name=Ostermontag -holiday.de-CH7.date=20150406 +holiday.de-CH7.date=20200413 holiday.de-CH8.name=Tag der Arbeit -holiday.de-CH8.date=20150501 +holiday.de-CH8.date=20200501 holiday.de-CH9.name=Auffahrt -holiday.de-CH9.date=20150514 +holiday.de-CH9.date=20200521 holiday.de-CH10.name=Pfingstsonntag -holiday.de-CH10.date=20150524 +holiday.de-CH10.date=20200531 holiday.de-CH11.name=Pfingstmontag -holiday.de-CH11.date=20150525 +holiday.de-CH11.date=20200601 holiday.de-CH12.name=Fronleichnam -holiday.de-CH12.date=20150604 +holiday.de-CH12.date=20200611 holiday.de-CH13.name=Bundesfeier -holiday.de-CH13.date=20150801 +holiday.de-CH13.date=20200801 holiday.de-CH14.name=Mariä Himmelfahrt -holiday.de-CH14.date=20150815 +holiday.de-CH14.date=20200815 holiday.de-CH15.name=Allerheiligen -holiday.de-CH15.date=20151101 +holiday.de-CH15.date=20201101 holiday.de-CH16.name=Mariä Empfängnis -holiday.de-CH16.date=20151208 +holiday.de-CH16.date=20201208 holiday.de-CH17.name=Weihnachtstag -holiday.de-CH17.date=20151225 +holiday.de-CH17.date=20201225 holiday.de-CH18.name=Stephanstag -holiday.de-CH18.date=20151226 +holiday.de-CH18.date=20201226 holiday.de-CH19.name=Neujahrstag -holiday.de-CH19.date=20160101 +holiday.de-CH19.date=20210101 holiday.de-CH20.name=Berchtoldstag -holiday.de-CH20.date=20160102 +holiday.de-CH20.date=20210102 holiday.de-CH21.name=Heilige Drei Könige -holiday.de-CH21.date=20160106 +holiday.de-CH21.date=20210106 holiday.de-CH22.name=Josefstag -holiday.de-CH22.date=20160319 +holiday.de-CH22.date=20210319 holiday.de-CH23.name=Karfreitag -holiday.de-CH23.date=20160325 +holiday.de-CH23.date=20210402 holiday.de-CH24.name=Ostersonntag -holiday.de-CH24.date=20160327 +holiday.de-CH24.date=20210404 holiday.de-CH25.name=Ostermontag -holiday.de-CH25.date=20160328 +holiday.de-CH25.date=20210405 holiday.de-CH26.name=Tag der Arbeit -holiday.de-CH26.date=20160501 +holiday.de-CH26.date=20210501 holiday.de-CH27.name=Auffahrt -holiday.de-CH27.date=20160505 +holiday.de-CH27.date=20210513 holiday.de-CH28.name=Pfingstsonntag -holiday.de-CH28.date=20160515 +holiday.de-CH28.date=20210523 holiday.de-CH29.name=Pfingstmontag -holiday.de-CH29.date=20160516 +holiday.de-CH29.date=20210524 holiday.de-CH30.name=Fronleichnam -holiday.de-CH30.date=20160526 +holiday.de-CH30.date=20210603 holiday.de-CH31.name=Bundesfeier -holiday.de-CH31.date=20160801 +holiday.de-CH31.date=20210801 holiday.de-CH32.name=Mariä Himmelfahrt -holiday.de-CH32.date=20160815 +holiday.de-CH32.date=20210815 holiday.de-CH33.name=Allerheiligen -holiday.de-CH33.date=20161101 +holiday.de-CH33.date=20211101 holiday.de-CH34.name=Mariä Empfängnis -holiday.de-CH34.date=20161208 +holiday.de-CH34.date=20211208 holiday.de-CH35.name=Weihnachtstag -holiday.de-CH35.date=20161225 +holiday.de-CH35.date=20211225 holiday.de-CH36.name=Stephanstag -holiday.de-CH36.date=20161226 +holiday.de-CH36.date=20211226 diff --git a/doc/rc/holidays.de-DE.rc b/doc/rc/holidays.de-DE.rc index 012cc9664..bc5a3f1c4 100644 --- a/doc/rc/holidays.de-DE.rc +++ b/doc/rc/holidays.de-DE.rc @@ -1,9 +1,9 @@ ############################################################################### # International Holiday Data provided by Holidata.net -# http://holidata.net/de-DE/2015.json -# http://holidata.net/de-DE/2016.json +# https://holidata.net/de-DE/2020.json +# https://holidata.net/de-DE/2021.json # -# Copyright 2006 - 2016, Paul Beckingham, Federico Hernandez. +# Copyright 2006 - 2020, 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 @@ -23,83 +23,89 @@ # 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 +# https://www.opensource.org/licenses/mit-license.php # ############################################################################### holiday.de-DE1.name=Neujahr -holiday.de-DE1.date=20150101 +holiday.de-DE1.date=20200101 holiday.de-DE2.name=Heilige drei Könige -holiday.de-DE2.date=20150106 -holiday.de-DE3.name=Karfreitag -holiday.de-DE3.date=20150403 -holiday.de-DE4.name=Ostern -holiday.de-DE4.date=20150405 -holiday.de-DE5.name=Ostermontag -holiday.de-DE5.date=20150406 -holiday.de-DE6.name=Erster Maifeiertag -holiday.de-DE6.date=20150501 -holiday.de-DE7.name=Christi Himmelfahrt -holiday.de-DE7.date=20150514 -holiday.de-DE8.name=Pfingstsonntag -holiday.de-DE8.date=20150524 -holiday.de-DE9.name=Pfingstmontag -holiday.de-DE9.date=20150525 -holiday.de-DE10.name=Fronleichnam -holiday.de-DE10.date=20150604 -holiday.de-DE11.name=Mariä Himmelfahrt -holiday.de-DE11.date=20150815 -holiday.de-DE12.name=Tag der Deutschen Einheit -holiday.de-DE12.date=20151003 -holiday.de-DE13.name=Reformationstag -holiday.de-DE13.date=20151031 -holiday.de-DE14.name=Allerheiligen -holiday.de-DE14.date=20151101 -holiday.de-DE15.name=Buß- und Bettag -holiday.de-DE15.date=20151118 -holiday.de-DE16.name=Heilig Abend -holiday.de-DE16.date=20151224 -holiday.de-DE17.name=Weihnachtstag -holiday.de-DE17.date=20151225 -holiday.de-DE18.name=Zweiter Weihnachtstag -holiday.de-DE18.date=20151226 -holiday.de-DE19.name=Silvester -holiday.de-DE19.date=20151231 -holiday.de-DE20.name=Neujahr -holiday.de-DE20.date=20160101 -holiday.de-DE21.name=Heilige drei Könige -holiday.de-DE21.date=20160106 -holiday.de-DE22.name=Karfreitag -holiday.de-DE22.date=20160325 -holiday.de-DE23.name=Ostern -holiday.de-DE23.date=20160327 -holiday.de-DE24.name=Ostermontag -holiday.de-DE24.date=20160328 -holiday.de-DE25.name=Erster Maifeiertag -holiday.de-DE25.date=20160501 -holiday.de-DE26.name=Christi Himmelfahrt -holiday.de-DE26.date=20160505 -holiday.de-DE27.name=Pfingstsonntag -holiday.de-DE27.date=20160515 -holiday.de-DE28.name=Pfingstmontag -holiday.de-DE28.date=20160516 -holiday.de-DE29.name=Fronleichnam -holiday.de-DE29.date=20160526 -holiday.de-DE30.name=Mariä Himmelfahrt -holiday.de-DE30.date=20160815 -holiday.de-DE31.name=Tag der Deutschen Einheit -holiday.de-DE31.date=20161003 -holiday.de-DE32.name=Reformationstag -holiday.de-DE32.date=20161031 -holiday.de-DE33.name=Allerheiligen -holiday.de-DE33.date=20161101 -holiday.de-DE34.name=Buß- und Bettag -holiday.de-DE34.date=20161116 -holiday.de-DE35.name=Heilig Abend -holiday.de-DE35.date=20161224 -holiday.de-DE36.name=Weihnachtstag -holiday.de-DE36.date=20161225 -holiday.de-DE37.name=Zweiter Weihnachtstag -holiday.de-DE37.date=20161226 -holiday.de-DE38.name=Silvester -holiday.de-DE38.date=20161231 +holiday.de-DE2.date=20200106 +holiday.de-DE3.name=Internationaler Frauentag +holiday.de-DE3.date=20200308 +holiday.de-DE4.name=Karfreitag +holiday.de-DE4.date=20200410 +holiday.de-DE5.name=Ostern +holiday.de-DE5.date=20200412 +holiday.de-DE6.name=Ostermontag +holiday.de-DE6.date=20200413 +holiday.de-DE7.name=Erster Maifeiertag +holiday.de-DE7.date=20200501 +holiday.de-DE8.name=75. Jahrestag der Befreiung vom Nationalsozialismus und der Beendigung des Zweiten Weltkrieges in Europa +holiday.de-DE8.date=20200508 +holiday.de-DE9.name=Christi Himmelfahrt +holiday.de-DE9.date=20200521 +holiday.de-DE10.name=Pfingstsonntag +holiday.de-DE10.date=20200531 +holiday.de-DE11.name=Pfingstmontag +holiday.de-DE11.date=20200601 +holiday.de-DE12.name=Fronleichnam +holiday.de-DE12.date=20200611 +holiday.de-DE13.name=Mariä Himmelfahrt +holiday.de-DE13.date=20200815 +holiday.de-DE14.name=Tag der Deutschen Einheit +holiday.de-DE14.date=20201003 +holiday.de-DE15.name=Reformationstag +holiday.de-DE15.date=20201031 +holiday.de-DE16.name=Allerheiligen +holiday.de-DE16.date=20201101 +holiday.de-DE17.name=Buß- und Bettag +holiday.de-DE17.date=20201118 +holiday.de-DE18.name=Heilig Abend +holiday.de-DE18.date=20201224 +holiday.de-DE19.name=Weihnachtstag +holiday.de-DE19.date=20201225 +holiday.de-DE20.name=Zweiter Weihnachtstag +holiday.de-DE20.date=20201226 +holiday.de-DE21.name=Silvester +holiday.de-DE21.date=20201231 +holiday.de-DE22.name=Neujahr +holiday.de-DE22.date=20210101 +holiday.de-DE23.name=Heilige drei Könige +holiday.de-DE23.date=20210106 +holiday.de-DE24.name=Internationaler Frauentag +holiday.de-DE24.date=20210308 +holiday.de-DE25.name=Karfreitag +holiday.de-DE25.date=20210402 +holiday.de-DE26.name=Ostern +holiday.de-DE26.date=20210404 +holiday.de-DE27.name=Ostermontag +holiday.de-DE27.date=20210405 +holiday.de-DE28.name=Erster Maifeiertag +holiday.de-DE28.date=20210501 +holiday.de-DE29.name=Christi Himmelfahrt +holiday.de-DE29.date=20210513 +holiday.de-DE30.name=Pfingstsonntag +holiday.de-DE30.date=20210523 +holiday.de-DE31.name=Pfingstmontag +holiday.de-DE31.date=20210524 +holiday.de-DE32.name=Fronleichnam +holiday.de-DE32.date=20210603 +holiday.de-DE33.name=Mariä Himmelfahrt +holiday.de-DE33.date=20210815 +holiday.de-DE34.name=Tag der Deutschen Einheit +holiday.de-DE34.date=20211003 +holiday.de-DE35.name=Reformationstag +holiday.de-DE35.date=20211031 +holiday.de-DE36.name=Allerheiligen +holiday.de-DE36.date=20211101 +holiday.de-DE37.name=Buß- und Bettag +holiday.de-DE37.date=20211117 +holiday.de-DE38.name=Heilig Abend +holiday.de-DE38.date=20211224 +holiday.de-DE39.name=Weihnachtstag +holiday.de-DE39.date=20211225 +holiday.de-DE40.name=Zweiter Weihnachtstag +holiday.de-DE40.date=20211226 +holiday.de-DE41.name=Silvester +holiday.de-DE41.date=20211231 diff --git a/doc/rc/holidays.el-GR.rc b/doc/rc/holidays.el-GR.rc index 93b1481bb..e5ccbee73 100644 --- a/doc/rc/holidays.el-GR.rc +++ b/doc/rc/holidays.el-GR.rc @@ -1,9 +1,9 @@ ############################################################################### # International Holiday Data provided by Holidata.net -# http://holidata.net/el-GR/2015.json -# http://holidata.net/el-GR/2016.json +# https://holidata.net/el-GR/2020.json +# https://holidata.net/el-GR/2021.json # -# Copyright 2006 - 2016, Paul Beckingham, Federico Hernandez. +# Copyright 2006 - 2020, 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 @@ -23,63 +23,63 @@ # 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 +# https://www.opensource.org/licenses/mit-license.php # ############################################################################### holiday.el-GR1.name=Πρωτοχρονιά -holiday.el-GR1.date=20150101 +holiday.el-GR1.date=20200101 holiday.el-GR2.name=Θεοφάνεια -holiday.el-GR2.date=20150106 +holiday.el-GR2.date=20200106 holiday.el-GR3.name=Καθαρά Δευτέρα -holiday.el-GR3.date=20150223 +holiday.el-GR3.date=20200302 holiday.el-GR4.name=Ευαγγελισμός της Θεοτόκου και Εθνική Ημέρα Ανεξαρτησίας της Ελλάδας -holiday.el-GR4.date=20150325 -holiday.el-GR5.name=Πρωτομαγιά -holiday.el-GR5.date=20150418 -holiday.el-GR6.name=Μεγάλη Παρασκευή -holiday.el-GR6.date=20150410 -holiday.el-GR7.name=Μεγάλο Σάββατο -holiday.el-GR7.date=20150411 -holiday.el-GR8.name=Πάσχα -holiday.el-GR8.date=20150412 -holiday.el-GR9.name=Δευτέρα του Πάσχα -holiday.el-GR9.date=20150413 +holiday.el-GR4.date=20200325 +holiday.el-GR5.name=Μεγάλη Παρασκευή +holiday.el-GR5.date=20200417 +holiday.el-GR6.name=Μεγάλο Σάββατο +holiday.el-GR6.date=20200418 +holiday.el-GR7.name=Πάσχα +holiday.el-GR7.date=20200419 +holiday.el-GR8.name=Δευτέρα του Πάσχα +holiday.el-GR8.date=20200420 +holiday.el-GR9.name=Πρωτομαγιά +holiday.el-GR9.date=20200501 holiday.el-GR10.name=Δευτέρα του Αγίου Πνεύματος -holiday.el-GR10.date=20150601 +holiday.el-GR10.date=20200608 holiday.el-GR11.name=Κοίμηση της Θεοτόκου -holiday.el-GR11.date=20150815 +holiday.el-GR11.date=20200815 holiday.el-GR12.name=Ημέρα του ΌΧΙ -holiday.el-GR12.date=20151028 +holiday.el-GR12.date=20201028 holiday.el-GR13.name=Χριστούγεννα -holiday.el-GR13.date=20151225 +holiday.el-GR13.date=20201225 holiday.el-GR14.name=Επόμενη ημέρα Χριστουγέννων -holiday.el-GR14.date=20151226 +holiday.el-GR14.date=20201226 holiday.el-GR15.name=Πρωτοχρονιά -holiday.el-GR15.date=20160101 +holiday.el-GR15.date=20210101 holiday.el-GR16.name=Θεοφάνεια -holiday.el-GR16.date=20160106 +holiday.el-GR16.date=20210106 holiday.el-GR17.name=Καθαρά Δευτέρα -holiday.el-GR17.date=20160314 +holiday.el-GR17.date=20210315 holiday.el-GR18.name=Ευαγγελισμός της Θεοτόκου και Εθνική Ημέρα Ανεξαρτησίας της Ελλάδας -holiday.el-GR18.date=20160325 -holiday.el-GR19.name=Πρωτομαγιά -holiday.el-GR19.date=20160418 -holiday.el-GR20.name=Μεγάλη Παρασκευή -holiday.el-GR20.date=20160429 -holiday.el-GR21.name=Μεγάλο Σάββατο -holiday.el-GR21.date=20160430 +holiday.el-GR18.date=20210325 +holiday.el-GR19.name=Μεγάλη Παρασκευή +holiday.el-GR19.date=20210430 +holiday.el-GR20.name=Μεγάλο Σάββατο +holiday.el-GR20.date=20210501 +holiday.el-GR21.name=Πρωτομαγιά +holiday.el-GR21.date=20210501 holiday.el-GR22.name=Πάσχα -holiday.el-GR22.date=20160501 +holiday.el-GR22.date=20210502 holiday.el-GR23.name=Δευτέρα του Πάσχα -holiday.el-GR23.date=20160502 +holiday.el-GR23.date=20210503 holiday.el-GR24.name=Δευτέρα του Αγίου Πνεύματος -holiday.el-GR24.date=20160620 +holiday.el-GR24.date=20210621 holiday.el-GR25.name=Κοίμηση της Θεοτόκου -holiday.el-GR25.date=20160815 +holiday.el-GR25.date=20210815 holiday.el-GR26.name=Ημέρα του ΌΧΙ -holiday.el-GR26.date=20161028 +holiday.el-GR26.date=20211028 holiday.el-GR27.name=Χριστούγεννα -holiday.el-GR27.date=20161225 +holiday.el-GR27.date=20211225 holiday.el-GR28.name=Επόμενη ημέρα Χριστουγέννων -holiday.el-GR28.date=20161226 +holiday.el-GR28.date=20211226 diff --git a/doc/rc/holidays.en-AU.rc b/doc/rc/holidays.en-AU.rc deleted file mode 100644 index 90bd939a9..000000000 --- a/doc/rc/holidays.en-AU.rc +++ /dev/null @@ -1,119 +0,0 @@ -############################################################################### -# International Holiday Data provided by Holidata.net -# http://holidata.net/en-AU/2015.json -# http://holidata.net/en-AU/2016.json -# -# Copyright 2006 - 2016, 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 -# -############################################################################### - -holiday.en-AU1.name=New Year's Day -holiday.en-AU1.date=20150101 -holiday.en-AU2.name=Australia Day -holiday.en-AU2.date=20150126 -holiday.en-AU3.name=Royal Hobart Regatta -holiday.en-AU3.date=20150209 -holiday.en-AU4.name=Labour Day -holiday.en-AU4.date=20150302 -holiday.en-AU5.name=Labour Day -holiday.en-AU5.date=20150309 -holiday.en-AU6.name=Canberra Day -holiday.en-AU6.date=20150309 -holiday.en-AU7.name=Eight Hours Day -holiday.en-AU7.date=20150309 -holiday.en-AU8.name=Good Friday -holiday.en-AU8.date=20150403 -holiday.en-AU9.name=Easter Saturday -holiday.en-AU9.date=20150404 -holiday.en-AU10.name=Easter Sunday -holiday.en-AU10.date=20150405 -holiday.en-AU11.name=Easter Monday -holiday.en-AU11.date=20150406 -holiday.en-AU12.name=Anzac Day -holiday.en-AU12.date=20150425 -holiday.en-AU13.name=May Day -holiday.en-AU13.date=20150504 -holiday.en-AU14.name=Foundation Day -holiday.en-AU14.date=20150601 -holiday.en-AU15.name=Queen's Birthday -holiday.en-AU15.date=20150608 -holiday.en-AU16.name=Picnic Day -holiday.en-AU16.date=20150803 -holiday.en-AU17.name=Bank Holiday -holiday.en-AU17.date=20150803 -holiday.en-AU18.name=Queen's Birthday -holiday.en-AU18.date=20150928 -holiday.en-AU19.name=Labour Day -holiday.en-AU19.date=20151005 -holiday.en-AU20.name=Recreation Day -holiday.en-AU20.date=20151102 -holiday.en-AU21.name=Christmas Day -holiday.en-AU21.date=20151225 -holiday.en-AU22.name=Boxing Day -holiday.en-AU22.date=20151226 -holiday.en-AU23.name=Proclamation Day -holiday.en-AU23.date=20151226 -holiday.en-AU24.name=New Year's Day -holiday.en-AU24.date=20160101 -holiday.en-AU25.name=Australia Day -holiday.en-AU25.date=20160126 -holiday.en-AU26.name=Royal Hobart Regatta -holiday.en-AU26.date=20160208 -holiday.en-AU27.name=Labour Day -holiday.en-AU27.date=20160307 -holiday.en-AU28.name=Labour Day -holiday.en-AU28.date=20160314 -holiday.en-AU29.name=Canberra Day -holiday.en-AU29.date=20160314 -holiday.en-AU30.name=Eight Hours Day -holiday.en-AU30.date=20160314 -holiday.en-AU31.name=Good Friday -holiday.en-AU31.date=20160325 -holiday.en-AU32.name=Easter Saturday -holiday.en-AU32.date=20160326 -holiday.en-AU33.name=Easter Monday -holiday.en-AU33.date=20160327 -holiday.en-AU34.name=Anzac Day -holiday.en-AU34.date=20160425 -holiday.en-AU35.name=May Day -holiday.en-AU35.date=20160502 -holiday.en-AU36.name=Foundation Day -holiday.en-AU36.date=20160603 -holiday.en-AU37.name=Queen's Birthday -holiday.en-AU37.date=20160613 -holiday.en-AU38.name=Picnic Day -holiday.en-AU38.date=20160801 -holiday.en-AU39.name=Bank Holiday -holiday.en-AU39.date=20160801 -holiday.en-AU40.name=Queen's Birthday -holiday.en-AU40.date=20160926 -holiday.en-AU41.name=Labour Day -holiday.en-AU41.date=20161003 -holiday.en-AU42.name=Recreation Day -holiday.en-AU42.date=20161107 -holiday.en-AU43.name=Christmas Day -holiday.en-AU43.date=20161225 -holiday.en-AU44.name=Boxing Day -holiday.en-AU44.date=20161226 -holiday.en-AU45.name=Proclamation Day -holiday.en-AU45.date=20161226 diff --git a/doc/rc/holidays.en-CA.rc b/doc/rc/holidays.en-CA.rc index 8f4fda34c..cb8784a81 100644 --- a/doc/rc/holidays.en-CA.rc +++ b/doc/rc/holidays.en-CA.rc @@ -1,9 +1,9 @@ ############################################################################### # International Holiday Data provided by Holidata.net -# http://holidata.net/en-CA/2015.json -# http://holidata.net/en-CA/2016.json +# https://holidata.net/en-CA/2020.json +# https://holidata.net/en-CA/2021.json # -# Copyright 2006 - 2016, Paul Beckingham, Federico Hernandez. +# Copyright 2006 - 2020, 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 @@ -23,55 +23,83 @@ # 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 +# https://www.opensource.org/licenses/mit-license.php # ############################################################################### holiday.en-CA1.name=New Year's Day -holiday.en-CA1.date=20150101 +holiday.en-CA1.date=20200101 holiday.en-CA2.name=Family Day -holiday.en-CA2.date=20150209 -holiday.en-CA3.name=Good Friday -holiday.en-CA3.date=20150403 -holiday.en-CA4.name=Easter Monday -holiday.en-CA4.date=20150406 -holiday.en-CA5.name=Victoria Day -holiday.en-CA5.date=20150518 -holiday.en-CA6.name=Canada Day -holiday.en-CA6.date=20150701 -holiday.en-CA7.name=First Monday of August -holiday.en-CA7.date=20150803 -holiday.en-CA8.name=Labour Day -holiday.en-CA8.date=20150907 -holiday.en-CA9.name=Thanksgiving Day -holiday.en-CA9.date=20151012 -holiday.en-CA10.name=Remembrance Day -holiday.en-CA10.date=20151111 -holiday.en-CA11.name=Christmas Day -holiday.en-CA11.date=20151225 -holiday.en-CA12.name=Boxing Day -holiday.en-CA12.date=20151226 -holiday.en-CA13.name=New Year's Day -holiday.en-CA13.date=20160101 -holiday.en-CA14.name=Family Day -holiday.en-CA14.date=20160208 -holiday.en-CA15.name=Good Friday -holiday.en-CA15.date=20160325 -holiday.en-CA16.name=Easter Monday -holiday.en-CA16.date=20160328 -holiday.en-CA17.name=Victoria Day -holiday.en-CA17.date=20160523 -holiday.en-CA18.name=Canada Day -holiday.en-CA18.date=20160701 -holiday.en-CA19.name=First Monday of August -holiday.en-CA19.date=20160801 -holiday.en-CA20.name=Labour Day -holiday.en-CA20.date=20160905 -holiday.en-CA21.name=Thanksgiving Day -holiday.en-CA21.date=20161010 -holiday.en-CA22.name=Remembrance Day -holiday.en-CA22.date=20161111 -holiday.en-CA23.name=Christmas Day -holiday.en-CA23.date=20161225 -holiday.en-CA24.name=Boxing Day -holiday.en-CA24.date=20161226 +holiday.en-CA2.date=20200217 +holiday.en-CA3.name=Louis Riel Day +holiday.en-CA3.date=20200217 +holiday.en-CA4.name=Islander Day +holiday.en-CA4.date=20200217 +holiday.en-CA5.name=Good Friday +holiday.en-CA5.date=20200410 +holiday.en-CA6.name=Easter Monday +holiday.en-CA6.date=20200413 +holiday.en-CA7.name=National Patriots' Day +holiday.en-CA7.date=20200518 +holiday.en-CA8.name=Victoria Day +holiday.en-CA8.date=20200518 +holiday.en-CA9.name=National Holiday +holiday.en-CA9.date=20200624 +holiday.en-CA10.name=Canada Day +holiday.en-CA10.date=20200701 +holiday.en-CA11.name=August Civic Holiday +holiday.en-CA11.date=20200803 +holiday.en-CA12.name=Saskatchewan Day +holiday.en-CA12.date=20200803 +holiday.en-CA13.name=Heritage Day +holiday.en-CA13.date=20200803 +holiday.en-CA14.name=New Brunswick Day +holiday.en-CA14.date=20200803 +holiday.en-CA15.name=Labour Day +holiday.en-CA15.date=20200907 +holiday.en-CA16.name=Thanksgiving Day +holiday.en-CA16.date=20201012 +holiday.en-CA17.name=Remembrance Day +holiday.en-CA17.date=20201111 +holiday.en-CA18.name=Christmas Day +holiday.en-CA18.date=20201225 +holiday.en-CA19.name=Boxing Day +holiday.en-CA19.date=20201226 +holiday.en-CA20.name=New Year's Day +holiday.en-CA20.date=20210101 +holiday.en-CA21.name=Family Day +holiday.en-CA21.date=20210215 +holiday.en-CA22.name=Louis Riel Day +holiday.en-CA22.date=20210215 +holiday.en-CA23.name=Islander Day +holiday.en-CA23.date=20210215 +holiday.en-CA24.name=Good Friday +holiday.en-CA24.date=20210402 +holiday.en-CA25.name=Easter Monday +holiday.en-CA25.date=20210405 +holiday.en-CA26.name=National Patriots' Day +holiday.en-CA26.date=20210524 +holiday.en-CA27.name=Victoria Day +holiday.en-CA27.date=20210524 +holiday.en-CA28.name=National Holiday +holiday.en-CA28.date=20210624 +holiday.en-CA29.name=Canada Day +holiday.en-CA29.date=20210701 +holiday.en-CA30.name=August Civic Holiday +holiday.en-CA30.date=20210802 +holiday.en-CA31.name=Saskatchewan Day +holiday.en-CA31.date=20210802 +holiday.en-CA32.name=Heritage Day +holiday.en-CA32.date=20210802 +holiday.en-CA33.name=New Brunswick Day +holiday.en-CA33.date=20210802 +holiday.en-CA34.name=Labour Day +holiday.en-CA34.date=20210906 +holiday.en-CA35.name=Thanksgiving Day +holiday.en-CA35.date=20211011 +holiday.en-CA36.name=Remembrance Day +holiday.en-CA36.date=20211111 +holiday.en-CA37.name=Christmas Day +holiday.en-CA37.date=20211225 +holiday.en-CA38.name=Boxing Day +holiday.en-CA38.date=20211226 diff --git a/doc/rc/holidays.en-GB.rc b/doc/rc/holidays.en-GB.rc index 40278b73a..b6e30ea99 100644 --- a/doc/rc/holidays.en-GB.rc +++ b/doc/rc/holidays.en-GB.rc @@ -1,9 +1,9 @@ ############################################################################### # International Holiday Data provided by Holidata.net -# http://holidata.net/en-GB/2015.json -# http://holidata.net/en-GB/2016.json +# https://holidata.net/en-GB/2020.json +# https://holidata.net/en-GB/2021.json # -# Copyright 2006 - 2016, Paul Beckingham, Federico Hernandez. +# Copyright 2006 - 2020, 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 @@ -23,39 +23,45 @@ # 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 +# https://www.opensource.org/licenses/mit-license.php # ############################################################################### holiday.en-GB1.name=New Year's Day -holiday.en-GB1.date=20150101 +holiday.en-GB1.date=20200101 holiday.en-GB2.name=Good Friday -holiday.en-GB2.date=20150403 +holiday.en-GB2.date=20200410 holiday.en-GB3.name=Easter Monday -holiday.en-GB3.date=20150406 +holiday.en-GB3.date=20200413 holiday.en-GB4.name=Early May Bank Holiday -holiday.en-GB4.date=20150504 +holiday.en-GB4.date=20200504 holiday.en-GB5.name=Spring Bank Holiday -holiday.en-GB5.date=20150525 +holiday.en-GB5.date=20200525 holiday.en-GB6.name=August Bank Holiday -holiday.en-GB6.date=20150831 +holiday.en-GB6.date=20200831 holiday.en-GB7.name=Christmas Day -holiday.en-GB7.date=20151225 +holiday.en-GB7.date=20201225 holiday.en-GB8.name=Boxing Day -holiday.en-GB8.date=20151226 -holiday.en-GB9.name=New Year's Day -holiday.en-GB9.date=20160101 -holiday.en-GB10.name=Good Friday -holiday.en-GB10.date=20160325 -holiday.en-GB11.name=Easter Monday -holiday.en-GB11.date=20160328 -holiday.en-GB12.name=Early May Bank Holiday -holiday.en-GB12.date=20160502 -holiday.en-GB13.name=Spring Bank Holiday -holiday.en-GB13.date=20160530 -holiday.en-GB14.name=August Bank Holiday -holiday.en-GB14.date=20160829 -holiday.en-GB15.name=Christmas Day -holiday.en-GB15.date=20161225 -holiday.en-GB16.name=Boxing Day -holiday.en-GB16.date=20161226 +holiday.en-GB8.date=20201226 +holiday.en-GB9.name=Boxing Day (observed) +holiday.en-GB9.date=20201228 +holiday.en-GB10.name=New Year's Day +holiday.en-GB10.date=20210101 +holiday.en-GB11.name=Good Friday +holiday.en-GB11.date=20210402 +holiday.en-GB12.name=Easter Monday +holiday.en-GB12.date=20210405 +holiday.en-GB13.name=Early May Bank Holiday +holiday.en-GB13.date=20210503 +holiday.en-GB14.name=Spring Bank Holiday +holiday.en-GB14.date=20210531 +holiday.en-GB15.name=August Bank Holiday +holiday.en-GB15.date=20210830 +holiday.en-GB16.name=Christmas Day +holiday.en-GB16.date=20211225 +holiday.en-GB17.name=Boxing Day +holiday.en-GB17.date=20211226 +holiday.en-GB18.name=Christmas Day (observed) +holiday.en-GB18.date=20211227 +holiday.en-GB19.name=Boxing Day (observed) +holiday.en-GB19.date=20211228 diff --git a/doc/rc/holidays.en-GL.rc b/doc/rc/holidays.en-GL.rc deleted file mode 100644 index c66c7d7b3..000000000 --- a/doc/rc/holidays.en-GL.rc +++ /dev/null @@ -1,81 +0,0 @@ -############################################################################### -# International Holiday Data provided by Holidata.net -# http://holidata.net/en-GL/2015.json -# http://holidata.net/en-GL/2016.json -# -# Copyright 2006 - 2016, 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 -# -############################################################################### - -holiday.en-GL1.name=New Year's Day -holiday.en-GL1.date=20150101 -holiday.en-GL2.name=Epiphany -holiday.en-GL2.date=20150106 -holiday.en-GL3.name=Maundy Thursday -holiday.en-GL3.date=20150402 -holiday.en-GL4.name=Good Friday -holiday.en-GL4.date=20150303 -holiday.en-GL5.name=Easter Monday -holiday.en-GL5.date=20150406 -holiday.en-GL6.name=General Prayer Day -holiday.en-GL6.date=20150501 -holiday.en-GL7.name=Ascension -holiday.en-GL7.date=20150514 -holiday.en-GL8.name=Whit Monday -holiday.en-GL8.date=20150525 -holiday.en-GL9.name=Ullortuneq -holiday.en-GL9.date=20150621 -holiday.en-GL10.name=Christmas Eve -holiday.en-GL10.date=20151224 -holiday.en-GL11.name=Christmas Day -holiday.en-GL11.date=20151225 -holiday.en-GL12.name=St Stephen's Day -holiday.en-GL12.date=20151226 -holiday.en-GL13.name=New Year's Eve -holiday.en-GL13.date=20151231 -holiday.en-GL14.name=New Year's Day -holiday.en-GL14.date=20160101 -holiday.en-GL15.name=Epiphany -holiday.en-GL15.date=20160106 -holiday.en-GL16.name=Maundy Thursday -holiday.en-GL16.date=20160324 -holiday.en-GL17.name=Good Friday -holiday.en-GL17.date=20160325 -holiday.en-GL18.name=Easter Monday -holiday.en-GL18.date=20160428 -holiday.en-GL19.name=General Prayer Day -holiday.en-GL19.date=20160422 -holiday.en-GL20.name=Ascension -holiday.en-GL20.date=20160505 -holiday.en-GL21.name=Whit Monday -holiday.en-GL21.date=20160516 -holiday.en-GL22.name=Ullortuneq -holiday.en-GL22.date=20160621 -holiday.en-GL23.name=Christmas Eve -holiday.en-GL23.date=20161224 -holiday.en-GL24.name=Christmas Day -holiday.en-GL24.date=20161225 -holiday.en-GL25.name=St Stephen's Day -holiday.en-GL25.date=20161226 -holiday.en-GL26.name=New Year's Eve -holiday.en-GL26.date=20161231 diff --git a/doc/rc/holidays.en-HK.rc b/doc/rc/holidays.en-HK.rc deleted file mode 100644 index 64de53b30..000000000 --- a/doc/rc/holidays.en-HK.rc +++ /dev/null @@ -1,95 +0,0 @@ -############################################################################### -# International Holiday Data provided by Holidata.net -# http://holidata.net/en-HK/2015.json -# http://holidata.net/en-HK/2016.json -# -# Copyright 2006 - 2016, 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 -# -############################################################################### - -holiday.en-HK1.name=The first day of January -holiday.en-HK1.date=20150101 -holiday.en-HK2.name=Lunar New Year’s Day -holiday.en-HK2.date=20150219 -holiday.en-HK3.name=The second day of Lunar New Year -holiday.en-HK3.date=20150220 -holiday.en-HK4.name=The third day of Lunar New Year -holiday.en-HK4.date=20150221 -holiday.en-HK5.name=Good Friday -holiday.en-HK5.date=20150403 -holiday.en-HK6.name=The day following Good Friday -holiday.en-HK6.date=20150404 -holiday.en-HK7.name=The day following Ching Ming Festival -holiday.en-HK7.date=20150406 -holiday.en-HK8.name=The day following Easter Monday -holiday.en-HK8.date=20150407 -holiday.en-HK9.name=Labour Day -holiday.en-HK9.date=20150501 -holiday.en-HK10.name=The Birthday of the Buddha -holiday.en-HK10.date=20150525 -holiday.en-HK11.name=Tuen Ng Festival -holiday.en-HK11.date=20150620 -holiday.en-HK12.name=Hong Kong Special Administrative Region Establishment Day -holiday.en-HK12.date=20150701 -holiday.en-HK13.name=The day following the Chinese Mid-Autumn Festival -holiday.en-HK13.date=20150928 -holiday.en-HK14.name=National Day -holiday.en-HK14.date=20151001 -holiday.en-HK15.name=Chung Yeung Festival -holiday.en-HK15.date=20151021 -holiday.en-HK16.name=Christmas Day -holiday.en-HK16.date=20151225 -holiday.en-HK17.name=The first weekday after Christmas Day -holiday.en-HK17.date=20151226 -holiday.en-HK18.name=The first day of January -holiday.en-HK18.date=20160101 -holiday.en-HK19.name=Lunar New Year’s Day -holiday.en-HK19.date=20160208 -holiday.en-HK20.name=The second day of Lunar New Year -holiday.en-HK20.date=20160209 -holiday.en-HK21.name=The third day of Lunar New Year -holiday.en-HK21.date=20160210 -holiday.en-HK22.name=Good Friday -holiday.en-HK22.date=20160325 -holiday.en-HK23.name=The day following Good Friday -holiday.en-HK23.date=20160326 -holiday.en-HK24.name=Ching Ming Festival -holiday.en-HK24.date=20160404 -holiday.en-HK25.name=Labour Day -holiday.en-HK25.date=20160501 -holiday.en-HK26.name=The Birthday of the Buddha -holiday.en-HK26.date=20160514 -holiday.en-HK27.name=Tuen Ng Festival -holiday.en-HK27.date=20160609 -holiday.en-HK28.name=Hong Kong Special Administrative Region Establishment Day -holiday.en-HK28.date=20160701 -holiday.en-HK29.name=The day following the Chinese Mid-Autumn Festival -holiday.en-HK29.date=20160916 -holiday.en-HK30.name=National Day -holiday.en-HK30.date=20161001 -holiday.en-HK31.name=Chung Yeung Festival -holiday.en-HK31.date=20161010 -holiday.en-HK32.name=Christmas Day -holiday.en-HK32.date=20161225 -holiday.en-HK33.name=The first weekday after Christmas Day -holiday.en-HK33.date=20161226 diff --git a/doc/rc/holidays.en-IN.rc b/doc/rc/holidays.en-IN.rc deleted file mode 100644 index 561b40ae0..000000000 --- a/doc/rc/holidays.en-IN.rc +++ /dev/null @@ -1,103 +0,0 @@ -############################################################################### -# International Holiday Data provided by Holidata.net -# http://holidata.net/en-IN/2015.json -# http://holidata.net/en-IN/2016.json -# -# Copyright 2006 - 2016, 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 -# -############################################################################### - -holiday.en-IN1.name=New Year's Day -holiday.en-IN1.date=20160101 -holiday.en-IN2.name=Lohri -holiday.en-IN2.date=20160114 -holiday.en-IN3.name=Pongal, Makar Sankranti -holiday.en-IN3.date=20160115 -holiday.en-IN4.name=Guru Gobind Singh Jayanti -holiday.en-IN4.date=20160116 -holiday.en-IN5.name=Republic Day -holiday.en-IN5.date=20160126 -holiday.en-IN6.name=Vasant Panchami -holiday.en-IN6.date=20160212 -holiday.en-IN7.name=Guru Ravidas Jayanti -holiday.en-IN7.date=20160222 -holiday.en-IN8.name=Maha Shivaratri -holiday.en-IN8.date=20160307 -holiday.en-IN9.name=Chhoti Holi, Holika Dahan -holiday.en-IN9.date=20160323 -holiday.en-IN10.name=Holi -holiday.en-IN10.date=20160324 -holiday.en-IN11.name=Good Friday -holiday.en-IN11.date=20160325 -holiday.en-IN12.name=Easter -holiday.en-IN12.date=20160327 -holiday.en-IN13.name=Gudi Padwa, Ugadi -holiday.en-IN13.date=20160408 -holiday.en-IN14.name=Solar New Year, Baisakhi -holiday.en-IN14.date=20160413 -holiday.en-IN15.name=Rama Navami -holiday.en-IN15.date=20160415 -holiday.en-IN16.name=Hazarat Ali's Birthday -holiday.en-IN16.date=20160421 -holiday.en-IN17.name=Buddha Purnima -holiday.en-IN17.date=20160521 -holiday.en-IN18.name=Eid al-Fitr , Ramadan -holiday.en-IN18.date=20160707 -holiday.en-IN19.name=Independence Day -holiday.en-IN19.date=20160815 -holiday.en-IN20.name=Rakhi, Raksha Bandhan -holiday.en-IN20.date=20160818 -holiday.en-IN21.name=Krishna Janmashtami -holiday.en-IN21.date=20160825 -holiday.en-IN22.name=Ganesh Chaturthi -holiday.en-IN22.date=20160905 -holiday.en-IN23.name=Onam, Eid al-Adha, Bakrid -holiday.en-IN23.date=20160913 -holiday.en-IN24.name=Gandhi Jayanti -holiday.en-IN24.date=20161002 -holiday.en-IN25.name=Durga Ashtami -holiday.en-IN25.date=20161009 -holiday.en-IN26.name=Maha Navami -holiday.en-IN26.date=20161010 -holiday.en-IN27.name=Dussehra, Madhvacharya Jayanti -holiday.en-IN27.date=20161011 -holiday.en-IN28.name=Muharram -holiday.en-IN28.date=20161012 -holiday.en-IN29.name=Valmiki Jayanti -holiday.en-IN29.date=20161016 -holiday.en-IN30.name=Karwa Chauth -holiday.en-IN30.date=20161019 -holiday.en-IN31.name=Diwali, Lakshmi Puja -holiday.en-IN31.date=20161030 -holiday.en-IN32.name=Gowardhan Puja -holiday.en-IN32.date=20161031 -holiday.en-IN33.name=Bhaiya Dooj -holiday.en-IN33.date=20161101 -holiday.en-IN34.name=Chhath Puja -holiday.en-IN34.date=20161106 -holiday.en-IN35.name=Guru Nanak Jayanti, Nehru Jayanti -holiday.en-IN35.date=20161114 -holiday.en-IN36.name=Milad an-Nabi, Id-e-Milad -holiday.en-IN36.date=20161212 -holiday.en-IN37.name=Christmas -holiday.en-IN37.date=20161225 diff --git a/doc/rc/holidays.en-NZ.rc b/doc/rc/holidays.en-NZ.rc index 7a05018d2..622908af1 100644 --- a/doc/rc/holidays.en-NZ.rc +++ b/doc/rc/holidays.en-NZ.rc @@ -1,9 +1,9 @@ ############################################################################### # International Holiday Data provided by Holidata.net -# http://holidata.net/en-NZ/2015.json -# http://holidata.net/en-NZ/2016.json +# https://holidata.net/en-NZ/2020.json +# https://holidata.net/en-NZ/2021.json # -# Copyright 2006 - 2016, Paul Beckingham, Federico Hernandez. +# Copyright 2006 - 2020, 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 @@ -23,47 +23,59 @@ # 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 +# https://www.opensource.org/licenses/mit-license.php # ############################################################################### holiday.en-NZ1.name=New Year's Day -holiday.en-NZ1.date=20150101 -holiday.en-NZ2.name=Day after New Years Day -holiday.en-NZ2.date=20150102 +holiday.en-NZ1.date=20200101 +holiday.en-NZ2.name=Day after New Year's Day +holiday.en-NZ2.date=20200102 holiday.en-NZ3.name=Waitangi Day -holiday.en-NZ3.date=20150206 +holiday.en-NZ3.date=20200206 holiday.en-NZ4.name=Good Friday -holiday.en-NZ4.date=20150403 +holiday.en-NZ4.date=20200410 holiday.en-NZ5.name=Easter Monday -holiday.en-NZ5.date=20150406 +holiday.en-NZ5.date=20200413 holiday.en-NZ6.name=ANZAC Day -holiday.en-NZ6.date=20150425 -holiday.en-NZ7.name=Queen's Birthday -holiday.en-NZ7.date=20150601 -holiday.en-NZ8.name=Labour Day -holiday.en-NZ8.date=20151026 -holiday.en-NZ9.name=Christmas Day -holiday.en-NZ9.date=20151225 -holiday.en-NZ10.name=Boxing Day -holiday.en-NZ10.date=20151226 -holiday.en-NZ11.name=New Year's Day -holiday.en-NZ11.date=20160101 -holiday.en-NZ12.name=Day after New Years Day -holiday.en-NZ12.date=20160104 -holiday.en-NZ13.name=Waitangi Day -holiday.en-NZ13.date=20160206 -holiday.en-NZ14.name=Good Friday -holiday.en-NZ14.date=20160325 -holiday.en-NZ15.name=Easter Monday -holiday.en-NZ15.date=20160328 -holiday.en-NZ16.name=ANZAC Day -holiday.en-NZ16.date=20160425 -holiday.en-NZ17.name=Queen's Birthday -holiday.en-NZ17.date=20160606 -holiday.en-NZ18.name=Labour Day -holiday.en-NZ18.date=20161024 -holiday.en-NZ19.name=Christmas Day -holiday.en-NZ19.date=20161225 -holiday.en-NZ20.name=Boxing Day -holiday.en-NZ20.date=20161226 +holiday.en-NZ6.date=20200425 +holiday.en-NZ7.name=ANZAC Day (observed) +holiday.en-NZ7.date=20200427 +holiday.en-NZ8.name=Queen's Birthday +holiday.en-NZ8.date=20200601 +holiday.en-NZ9.name=Labour Day +holiday.en-NZ9.date=20201026 +holiday.en-NZ10.name=Christmas Day +holiday.en-NZ10.date=20201225 +holiday.en-NZ11.name=Boxing Day +holiday.en-NZ11.date=20201226 +holiday.en-NZ12.name=Boxing Day (observed) +holiday.en-NZ12.date=20201228 +holiday.en-NZ13.name=New Year's Day +holiday.en-NZ13.date=20210101 +holiday.en-NZ14.name=Day after New Year's Day +holiday.en-NZ14.date=20210104 +holiday.en-NZ15.name=Waitangi Day +holiday.en-NZ15.date=20210206 +holiday.en-NZ16.name=Waitangi Day (observed) +holiday.en-NZ16.date=20210208 +holiday.en-NZ17.name=Good Friday +holiday.en-NZ17.date=20210402 +holiday.en-NZ18.name=Easter Monday +holiday.en-NZ18.date=20210405 +holiday.en-NZ19.name=ANZAC Day +holiday.en-NZ19.date=20210425 +holiday.en-NZ20.name=ANZAC Day (observed) +holiday.en-NZ20.date=20210426 +holiday.en-NZ21.name=Queen's Birthday +holiday.en-NZ21.date=20210607 +holiday.en-NZ22.name=Labour Day +holiday.en-NZ22.date=20211025 +holiday.en-NZ23.name=Christmas Day +holiday.en-NZ23.date=20211225 +holiday.en-NZ24.name=Boxing Day +holiday.en-NZ24.date=20211226 +holiday.en-NZ25.name=Christmas Day (observed) +holiday.en-NZ25.date=20211227 +holiday.en-NZ26.name=Boxing Day (observed) +holiday.en-NZ26.date=20211228 diff --git a/doc/rc/holidays.en-US.rc b/doc/rc/holidays.en-US.rc index cb0587e87..8a07c0341 100644 --- a/doc/rc/holidays.en-US.rc +++ b/doc/rc/holidays.en-US.rc @@ -1,9 +1,9 @@ ############################################################################### # International Holiday Data provided by Holidata.net -# http://holidata.net/en-US/2015.json -# http://holidata.net/en-US/2016.json +# https://holidata.net/en-US/2020.json +# https://holidata.net/en-US/2021.json # -# Copyright 2006 - 2016, Paul Beckingham, Federico Hernandez. +# Copyright 2006 - 2020, 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 @@ -23,51 +23,55 @@ # 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 +# https://www.opensource.org/licenses/mit-license.php # ############################################################################### holiday.en-US1.name=New Year's Day -holiday.en-US1.date=20150101 +holiday.en-US1.date=20200101 holiday.en-US2.name=Birthday of Martin Luther King, Jr. -holiday.en-US2.date=20150119 +holiday.en-US2.date=20200120 holiday.en-US3.name=Washington's Birthday -holiday.en-US3.date=20150216 +holiday.en-US3.date=20200217 holiday.en-US4.name=Patriots' Day -holiday.en-US4.date=20150420 +holiday.en-US4.date=20200420 holiday.en-US5.name=Memorial Day -holiday.en-US5.date=20150525 +holiday.en-US5.date=20200525 holiday.en-US6.name=Independence Day -holiday.en-US6.date=20150704 +holiday.en-US6.date=20200704 holiday.en-US7.name=Labor Day -holiday.en-US7.date=20150907 +holiday.en-US7.date=20200907 holiday.en-US8.name=Columbus Day -holiday.en-US8.date=20151012 +holiday.en-US8.date=20201012 holiday.en-US9.name=Veterans Day -holiday.en-US9.date=20151111 +holiday.en-US9.date=20201111 holiday.en-US10.name=Thanksgiving Day -holiday.en-US10.date=20151126 -holiday.en-US11.name=Christmas Day -holiday.en-US11.date=20151225 -holiday.en-US12.name=New Year's Day -holiday.en-US12.date=20160101 -holiday.en-US13.name=Birthday of Martin Luther King, Jr. -holiday.en-US13.date=20160118 -holiday.en-US14.name=Washington's Birthday -holiday.en-US14.date=20160215 -holiday.en-US15.name=Patriots' Day -holiday.en-US15.date=20160418 -holiday.en-US16.name=Memorial Day -holiday.en-US16.date=20160530 -holiday.en-US17.name=Independence Day -holiday.en-US17.date=20160704 -holiday.en-US18.name=Labor Day -holiday.en-US18.date=20160905 -holiday.en-US19.name=Columbus Day -holiday.en-US19.date=20161010 -holiday.en-US20.name=Veterans Day -holiday.en-US20.date=20161111 -holiday.en-US21.name=Thanksgiving Day -holiday.en-US21.date=20161124 -holiday.en-US22.name=Christmas Day -holiday.en-US22.date=20161225 +holiday.en-US10.date=20201126 +holiday.en-US11.name=Day after Thanksgiving +holiday.en-US11.date=20201127 +holiday.en-US12.name=Christmas Eve +holiday.en-US12.date=20201224 +holiday.en-US13.name=Christmas Day +holiday.en-US13.date=20201225 +holiday.en-US14.name=New Year's Day +holiday.en-US14.date=20210101 +holiday.en-US15.name=Birthday of Martin Luther King, Jr. +holiday.en-US15.date=20210118 +holiday.en-US16.name=Washington's Birthday +holiday.en-US16.date=20210215 +holiday.en-US17.name=Patriots' Day +holiday.en-US17.date=20210419 +holiday.en-US18.name=Memorial Day +holiday.en-US18.date=20210531 +holiday.en-US19.name=Independence Day +holiday.en-US19.date=20210704 +holiday.en-US20.name=Labor Day +holiday.en-US20.date=20210906 +holiday.en-US21.name=Columbus Day +holiday.en-US21.date=20211011 +holiday.en-US22.name=Veterans Day +holiday.en-US22.date=20211111 +holiday.en-US23.name=Thanksgiving Day +holiday.en-US23.date=20211125 +holiday.en-US24.name=Christmas Day +holiday.en-US24.date=20211225 diff --git a/doc/rc/holidays.en-ZA.rc b/doc/rc/holidays.en-ZA.rc deleted file mode 100644 index 2386a158e..000000000 --- a/doc/rc/holidays.en-ZA.rc +++ /dev/null @@ -1,77 +0,0 @@ -############################################################################### -# International Holiday Data provided by Holidata.net -# http://holidata.net/en-ZA/2015.json -# http://holidata.net/en-ZA/2016.json -# -# Copyright 2006 - 2016, 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 -# -############################################################################### - -holiday.en-ZA1.name=New Year's Day -holiday.en-ZA1.date=20150101 -holiday.en-ZA2.name=Human Rights Day -holiday.en-ZA2.date=20150321 -holiday.en-ZA3.name=Good Friday -holiday.en-ZA3.date=20150403 -holiday.en-ZA4.name=Family Day -holiday.en-ZA4.date=20150406 -holiday.en-ZA5.name=Freedom Day -holiday.en-ZA5.date=20150427 -holiday.en-ZA6.name=Workers' Day -holiday.en-ZA6.date=20150501 -holiday.en-ZA7.name=Youth Day -holiday.en-ZA7.date=20150616 -holiday.en-ZA8.name=National Women's Day -holiday.en-ZA8.date=20150809 -holiday.en-ZA9.name=Heritage Day -holiday.en-ZA9.date=20150924 -holiday.en-ZA10.name=Day of Reconciliation -holiday.en-ZA10.date=20151217 -holiday.en-ZA11.name=Christmas Day -holiday.en-ZA11.date=20151225 -holiday.en-ZA12.name=Day of Goodwill -holiday.en-ZA12.date=20151226 -holiday.en-ZA13.name=New Year's Day -holiday.en-ZA13.date=20160101 -holiday.en-ZA14.name=Human Rights Day -holiday.en-ZA14.date=20160321 -holiday.en-ZA15.name=Good Friday -holiday.en-ZA15.date=20160325 -holiday.en-ZA16.name=Family Day -holiday.en-ZA16.date=20160328 -holiday.en-ZA17.name=Freedom Day -holiday.en-ZA17.date=20160427 -holiday.en-ZA18.name=Workers' Day -holiday.en-ZA18.date=20160501 -holiday.en-ZA19.name=Youth Day -holiday.en-ZA19.date=20160616 -holiday.en-ZA20.name=National Women's Day -holiday.en-ZA20.date=20160809 -holiday.en-ZA21.name=Heritage Day -holiday.en-ZA21.date=20160924 -holiday.en-ZA22.name=Day of Reconciliation -holiday.en-ZA22.date=20161217 -holiday.en-ZA23.name=Christmas Day -holiday.en-ZA23.date=20161225 -holiday.en-ZA24.name=Day of Goodwill -holiday.en-ZA24.date=20161226 diff --git a/doc/rc/holidays.es-CO.rc b/doc/rc/holidays.es-CO.rc index 659b93037..4e9f4ae87 100644 --- a/doc/rc/holidays.es-CO.rc +++ b/doc/rc/holidays.es-CO.rc @@ -1,9 +1,9 @@ ############################################################################### # International Holiday Data provided by Holidata.net -# http://holidata.net/es-CO/2015.json -# http://holidata.net/es-CO/2016.json +# https://holidata.net/es-CO/2020.json +# https://holidata.net/es-CO/2021.json # -# Copyright 2006 - 2016, Paul Beckingham, Federico Hernandez. +# Copyright 2006 - 2020, 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 @@ -23,83 +23,83 @@ # 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 +# https://www.opensource.org/licenses/mit-license.php # ############################################################################### holiday.es-CO1.name=Año Nuevo -holiday.es-CO1.date=20150101 +holiday.es-CO1.date=20200101 holiday.es-CO2.name=Día de los Reyes Magos -holiday.es-CO2.date=20150112 +holiday.es-CO2.date=20200106 holiday.es-CO3.name=Día de San José -holiday.es-CO3.date=20150323 +holiday.es-CO3.date=20200323 holiday.es-CO4.name=Jueves Santo -holiday.es-CO4.date=20150402 +holiday.es-CO4.date=20200409 holiday.es-CO5.name=Viernes Santo -holiday.es-CO5.date=20150403 +holiday.es-CO5.date=20200410 holiday.es-CO6.name=Domingo de Pascua -holiday.es-CO6.date=20150405 +holiday.es-CO6.date=20200412 holiday.es-CO7.name=Día del Trabajo -holiday.es-CO7.date=20150501 +holiday.es-CO7.date=20200501 holiday.es-CO8.name=La Ascensión del Señor -holiday.es-CO8.date=20150518 +holiday.es-CO8.date=20200525 holiday.es-CO9.name=Corpus Christi -holiday.es-CO9.date=20150608 +holiday.es-CO9.date=20200615 holiday.es-CO10.name=El Sagrado Corazón de Jesús -holiday.es-CO10.date=20150615 +holiday.es-CO10.date=20200622 holiday.es-CO11.name=San Pedro y San Pablo -holiday.es-CO11.date=20150629 +holiday.es-CO11.date=20200629 holiday.es-CO12.name=Grito de Independencia -holiday.es-CO12.date=20150720 +holiday.es-CO12.date=20200720 holiday.es-CO13.name=Batalla de Boyacá -holiday.es-CO13.date=20150807 +holiday.es-CO13.date=20200807 holiday.es-CO14.name=Asunción de la Virgen -holiday.es-CO14.date=20150817 +holiday.es-CO14.date=20200817 holiday.es-CO15.name=Día de la Raza -holiday.es-CO15.date=20151012 +holiday.es-CO15.date=20201012 holiday.es-CO16.name=Todos los Santos -holiday.es-CO16.date=20151102 +holiday.es-CO16.date=20201102 holiday.es-CO17.name=Independencia de Cartagena -holiday.es-CO17.date=20151116 +holiday.es-CO17.date=20201116 holiday.es-CO18.name=Inmaculada Concepción -holiday.es-CO18.date=20151208 +holiday.es-CO18.date=20201208 holiday.es-CO19.name=Navidad -holiday.es-CO19.date=20151225 +holiday.es-CO19.date=20201225 holiday.es-CO20.name=Año Nuevo -holiday.es-CO20.date=20160101 +holiday.es-CO20.date=20210101 holiday.es-CO21.name=Día de los Reyes Magos -holiday.es-CO21.date=20160111 +holiday.es-CO21.date=20210111 holiday.es-CO22.name=Día de San José -holiday.es-CO22.date=20160321 +holiday.es-CO22.date=20210322 holiday.es-CO23.name=Jueves Santo -holiday.es-CO23.date=20160324 +holiday.es-CO23.date=20210401 holiday.es-CO24.name=Viernes Santo -holiday.es-CO24.date=20160325 +holiday.es-CO24.date=20210402 holiday.es-CO25.name=Domingo de Pascua -holiday.es-CO25.date=20160326 +holiday.es-CO25.date=20210404 holiday.es-CO26.name=Día del Trabajo -holiday.es-CO26.date=20160501 +holiday.es-CO26.date=20210501 holiday.es-CO27.name=La Ascensión del Señor -holiday.es-CO27.date=20160509 +holiday.es-CO27.date=20210517 holiday.es-CO28.name=Corpus Christi -holiday.es-CO28.date=20160530 +holiday.es-CO28.date=20210607 holiday.es-CO29.name=El Sagrado Corazón de Jesús -holiday.es-CO29.date=20160606 +holiday.es-CO29.date=20210614 holiday.es-CO30.name=San Pedro y San Pablo -holiday.es-CO30.date=20160704 +holiday.es-CO30.date=20210705 holiday.es-CO31.name=Grito de Independencia -holiday.es-CO31.date=20160720 +holiday.es-CO31.date=20210720 holiday.es-CO32.name=Batalla de Boyacá -holiday.es-CO32.date=20160807 +holiday.es-CO32.date=20210807 holiday.es-CO33.name=Asunción de la Virgen -holiday.es-CO33.date=20160815 +holiday.es-CO33.date=20210816 holiday.es-CO34.name=Día de la Raza -holiday.es-CO34.date=20161017 +holiday.es-CO34.date=20211018 holiday.es-CO35.name=Todos los Santos -holiday.es-CO35.date=20161107 +holiday.es-CO35.date=20211101 holiday.es-CO36.name=Independencia de Cartagena -holiday.es-CO36.date=20161114 +holiday.es-CO36.date=20211115 holiday.es-CO37.name=Inmaculada Concepción -holiday.es-CO37.date=20161208 +holiday.es-CO37.date=20211208 holiday.es-CO38.name=Navidad -holiday.es-CO38.date=20161225 +holiday.es-CO38.date=20211225 diff --git a/doc/rc/holidays.es-EC.rc b/doc/rc/holidays.es-EC.rc deleted file mode 100644 index 2643098b3..000000000 --- a/doc/rc/holidays.es-EC.rc +++ /dev/null @@ -1,75 +0,0 @@ -############################################################################### -# International Holiday Data provided by Holidata.net -# http://holidata.net/es-EC/2015.json -# http://holidata.net/es-EC/2016.json -# -# Copyright 2006 - 2016, 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 -# -############################################################################### - -holiday.es-EC1.name=Año Nuevo -holiday.es-EC1.date=20150101 -holiday.es-EC2.name=Año Nuevo -holiday.es-EC2.date=20150102 -holiday.es-EC3.name=Carnaval -holiday.es-EC3.date=20150216 -holiday.es-EC4.name=Carnaval -holiday.es-EC4.date=20150217 -holiday.es-EC5.name=Viernes Santo -holiday.es-EC5.date=20150403 -holiday.es-EC6.name=Día del Trabajo -holiday.es-EC6.date=20150501 -holiday.es-EC7.name=Batalla del Pichincha -holiday.es-EC7.date=20150524 -holiday.es-EC8.name=Primer Grito de Independencia -holiday.es-EC8.date=20150810 -holiday.es-EC9.name=Independencia de Guayaquil -holiday.es-EC9.date=20151009 -holiday.es-EC10.name=Día de Difuntos -holiday.es-EC10.date=20151102 -holiday.es-EC11.name=Independencia de Cuenca -holiday.es-EC11.date=20151103 -holiday.es-EC12.name=Navidad -holiday.es-EC12.date=20151225 -holiday.es-EC13.name=Año Nuevo -holiday.es-EC13.date=20160101 -holiday.es-EC14.name=Carnaval -holiday.es-EC14.date=20160208 -holiday.es-EC15.name=Carnaval -holiday.es-EC15.date=20160209 -holiday.es-EC16.name=Viernes Santo -holiday.es-EC16.date=20160325 -holiday.es-EC17.name=Día del Trabajo -holiday.es-EC17.date=20160501 -holiday.es-EC18.name=Batalla del Pichincha -holiday.es-EC18.date=20160524 -holiday.es-EC19.name=Primer Grito de Independencia -holiday.es-EC19.date=20160810 -holiday.es-EC20.name=Independencia de Guayaquil -holiday.es-EC20.date=20161009 -holiday.es-EC21.name=Día de Difuntos -holiday.es-EC21.date=20161102 -holiday.es-EC22.name=Independencia de Cuenca -holiday.es-EC22.date=20161103 -holiday.es-EC23.name=Navidad -holiday.es-EC23.date=20161225 diff --git a/doc/rc/holidays.es-ES.rc b/doc/rc/holidays.es-ES.rc index 4044eecd0..ede40d114 100644 --- a/doc/rc/holidays.es-ES.rc +++ b/doc/rc/holidays.es-ES.rc @@ -1,9 +1,9 @@ ############################################################################### # International Holiday Data provided by Holidata.net -# http://holidata.net/es-ES/2015.json -# http://holidata.net/es-ES/2016.json +# https://holidata.net/es-ES/2020.json +# https://holidata.net/es-ES/2021.json # -# Copyright 2006 - 2016, Paul Beckingham, Federico Hernandez. +# Copyright 2006 - 2020, 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 @@ -23,59 +23,59 @@ # 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 +# https://www.opensource.org/licenses/mit-license.php # ############################################################################### holiday.es-ES1.name=Año Nuevo -holiday.es-ES1.date=20150101 +holiday.es-ES1.date=20200101 holiday.es-ES2.name=Día de los Reyes -holiday.es-ES2.date=20150106 +holiday.es-ES2.date=20200106 holiday.es-ES3.name=Viernes Santo -holiday.es-ES3.date=20150403 +holiday.es-ES3.date=20200410 holiday.es-ES4.name=Pascua -holiday.es-ES4.date=20150405 +holiday.es-ES4.date=20200412 holiday.es-ES5.name=Fiesta del Trabajo -holiday.es-ES5.date=20150501 +holiday.es-ES5.date=20200501 holiday.es-ES6.name=Asunción de la Virgen -holiday.es-ES6.date=20150815 +holiday.es-ES6.date=20200815 holiday.es-ES7.name=Fiesta Nacional de España -holiday.es-ES7.date=20151012 +holiday.es-ES7.date=20201012 holiday.es-ES8.name=Dia de todos los Santos -holiday.es-ES8.date=20151101 +holiday.es-ES8.date=20201101 holiday.es-ES9.name=Dia de la Constitución -holiday.es-ES9.date=20151206 +holiday.es-ES9.date=20201206 holiday.es-ES10.name=Inmaculada Concepción -holiday.es-ES10.date=20151208 +holiday.es-ES10.date=20201208 holiday.es-ES11.name=Noche Buena -holiday.es-ES11.date=20151224 +holiday.es-ES11.date=20201224 holiday.es-ES12.name=Navidad -holiday.es-ES12.date=20151225 +holiday.es-ES12.date=20201225 holiday.es-ES13.name=Noche Vieja -holiday.es-ES13.date=20151231 +holiday.es-ES13.date=20201231 holiday.es-ES14.name=Año Nuevo -holiday.es-ES14.date=20160101 +holiday.es-ES14.date=20210101 holiday.es-ES15.name=Día de los Reyes -holiday.es-ES15.date=20160106 +holiday.es-ES15.date=20210106 holiday.es-ES16.name=Viernes Santo -holiday.es-ES16.date=20160325 +holiday.es-ES16.date=20210402 holiday.es-ES17.name=Pascua -holiday.es-ES17.date=20160327 +holiday.es-ES17.date=20210404 holiday.es-ES18.name=Fiesta del Trabajo -holiday.es-ES18.date=20160501 +holiday.es-ES18.date=20210501 holiday.es-ES19.name=Asunción de la Virgen -holiday.es-ES19.date=20160815 +holiday.es-ES19.date=20210815 holiday.es-ES20.name=Fiesta Nacional de España -holiday.es-ES20.date=20161012 +holiday.es-ES20.date=20211012 holiday.es-ES21.name=Dia de todos los Santos -holiday.es-ES21.date=20161101 +holiday.es-ES21.date=20211101 holiday.es-ES22.name=Dia de la Constitución -holiday.es-ES22.date=20161206 +holiday.es-ES22.date=20211206 holiday.es-ES23.name=Inmaculada Concepción -holiday.es-ES23.date=20161208 +holiday.es-ES23.date=20211208 holiday.es-ES24.name=Noche Buena -holiday.es-ES24.date=20161224 +holiday.es-ES24.date=20211224 holiday.es-ES25.name=Navidad -holiday.es-ES25.date=20161225 +holiday.es-ES25.date=20211225 holiday.es-ES26.name=Noche Vieja -holiday.es-ES26.date=20161231 +holiday.es-ES26.date=20211231 diff --git a/doc/rc/holidays.es-MX.rc b/doc/rc/holidays.es-MX.rc deleted file mode 100644 index 322e80dee..000000000 --- a/doc/rc/holidays.es-MX.rc +++ /dev/null @@ -1,69 +0,0 @@ -############################################################################### -# International Holiday Data provided by Holidata.net -# http://holidata.net/es-MX/2015.json -# http://holidata.net/es-MX/2016.json -# -# Copyright 2006 - 2016, 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 -# -############################################################################### - -holiday.es-MX1.name=Año Nuevo -holiday.es-MX1.date=20150101 -holiday.es-MX2.name=Día de la Constitución -holiday.es-MX2.date=20150202 -holiday.es-MX3.name=Natalicio de Benito Juárez -holiday.es-MX3.date=20150316 -holiday.es-MX4.name=Jueves Santo -holiday.es-MX4.date=20150402 -holiday.es-MX5.name=Viernes Santo -holiday.es-MX5.date=20150403 -holiday.es-MX6.name=Día del Trabajo -holiday.es-MX6.date=20150501 -holiday.es-MX7.name=Día de la Independencia -holiday.es-MX7.date=20150916 -holiday.es-MX8.name=Día de la Revolución -holiday.es-MX8.date=20151116 -holiday.es-MX9.name=Nuestra Señora de Guadalupe -holiday.es-MX9.date=20151212 -holiday.es-MX10.name=Navidad -holiday.es-MX10.date=20151225 -holiday.es-MX11.name=Año Nuevo -holiday.es-MX11.date=20160101 -holiday.es-MX12.name=Día de la Constitución -holiday.es-MX12.date=20160201 -holiday.es-MX13.name=Natalicio de Benito Juárez -holiday.es-MX13.date=20160314 -holiday.es-MX14.name=Jueves Santo -holiday.es-MX14.date=20160324 -holiday.es-MX15.name=Viernes Santo -holiday.es-MX15.date=20160325 -holiday.es-MX16.name=Día del Trabajo -holiday.es-MX16.date=20160501 -holiday.es-MX17.name=Día de la Independencia -holiday.es-MX17.date=20160916 -holiday.es-MX18.name=Día de la Revolución -holiday.es-MX18.date=20161121 -holiday.es-MX19.name=Nuestra Señora de Guadalupe -holiday.es-MX19.date=20161212 -holiday.es-MX20.name=Navidad -holiday.es-MX20.date=20161225 diff --git a/doc/rc/holidays.es-US.rc b/doc/rc/holidays.es-US.rc index 98a6592ad..34aa2e28e 100644 --- a/doc/rc/holidays.es-US.rc +++ b/doc/rc/holidays.es-US.rc @@ -1,9 +1,9 @@ ############################################################################### # International Holiday Data provided by Holidata.net -# http://holidata.net/es-US/2015.json -# http://holidata.net/es-US/2016.json +# https://holidata.net/es-US/2020.json +# https://holidata.net/es-US/2021.json # -# Copyright 2006 - 2016, Paul Beckingham, Federico Hernandez. +# Copyright 2006 - 2020, 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 @@ -23,51 +23,55 @@ # 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 +# https://www.opensource.org/licenses/mit-license.php # ############################################################################### holiday.es-US1.name=Año Neuvo -holiday.es-US1.date=20150101 +holiday.es-US1.date=20200101 holiday.es-US2.name=Cumpleaños de Martin Luther King, Jr. -holiday.es-US2.date=20150119 +holiday.es-US2.date=20200120 holiday.es-US3.name=Día del Presidente -holiday.es-US3.date=20150216 +holiday.es-US3.date=20200217 holiday.es-US4.name=Día del Patriota -holiday.es-US4.date=20150420 +holiday.es-US4.date=20200420 holiday.es-US5.name=Día de los Caídos -holiday.es-US5.date=20150525 +holiday.es-US5.date=20200525 holiday.es-US6.name=Día de la Independiencia -holiday.es-US6.date=20150704 +holiday.es-US6.date=20200704 holiday.es-US7.name=Día del Trabajo -holiday.es-US7.date=20150907 +holiday.es-US7.date=20200907 holiday.es-US8.name=Día de Columbus -holiday.es-US8.date=20151012 +holiday.es-US8.date=20201012 holiday.es-US9.name=Día de los Veteranos -holiday.es-US9.date=20151111 +holiday.es-US9.date=20201111 holiday.es-US10.name=Día de Acción de Gracias -holiday.es-US10.date=20151126 -holiday.es-US11.name=Navidad -holiday.es-US11.date=20151225 -holiday.es-US12.name=Año Neuvo -holiday.es-US12.date=20160101 -holiday.es-US13.name=Cumpleaños de Martin Luther King, Jr. -holiday.es-US13.date=20160118 -holiday.es-US14.name=Día del Presidente -holiday.es-US14.date=20160215 -holiday.es-US15.name=Día del Patriota -holiday.es-US15.date=20160418 -holiday.es-US16.name=Día de los Caídos -holiday.es-US16.date=20160530 -holiday.es-US17.name=Día de la Independiencia -holiday.es-US17.date=20160704 -holiday.es-US18.name=Día del Trabajo -holiday.es-US18.date=20160905 -holiday.es-US19.name=Día de Columbus -holiday.es-US19.date=20161010 -holiday.es-US20.name=Día de los Veteranos -holiday.es-US20.date=20161111 -holiday.es-US21.name=Día de Acción de Gracias -holiday.es-US21.date=20161124 -holiday.es-US22.name=Navidad -holiday.es-US22.date=20161225 +holiday.es-US10.date=20201126 +holiday.es-US11.name=Día después de Acción de Gracias +holiday.es-US11.date=20201127 +holiday.es-US12.name=Nochebuena +holiday.es-US12.date=20201224 +holiday.es-US13.name=Navidad +holiday.es-US13.date=20201225 +holiday.es-US14.name=Año Neuvo +holiday.es-US14.date=20210101 +holiday.es-US15.name=Cumpleaños de Martin Luther King, Jr. +holiday.es-US15.date=20210118 +holiday.es-US16.name=Día del Presidente +holiday.es-US16.date=20210215 +holiday.es-US17.name=Día del Patriota +holiday.es-US17.date=20210419 +holiday.es-US18.name=Día de los Caídos +holiday.es-US18.date=20210531 +holiday.es-US19.name=Día de la Independiencia +holiday.es-US19.date=20210704 +holiday.es-US20.name=Día del Trabajo +holiday.es-US20.date=20210906 +holiday.es-US21.name=Día de Columbus +holiday.es-US21.date=20211011 +holiday.es-US22.name=Día de los Veteranos +holiday.es-US22.date=20211111 +holiday.es-US23.name=Día de Acción de Gracias +holiday.es-US23.date=20211125 +holiday.es-US24.name=Navidad +holiday.es-US24.date=20211225 diff --git a/doc/rc/holidays.et-EE.rc b/doc/rc/holidays.et-EE.rc deleted file mode 100644 index 0455ba44a..000000000 --- a/doc/rc/holidays.et-EE.rc +++ /dev/null @@ -1,77 +0,0 @@ -############################################################################### -# International Holiday Data provided by Holidata.net -# http://holidata.net/et-EE/2015.json -# http://holidata.net/et-EE/2016.json -# -# Copyright 2006 - 2016, 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 -# -############################################################################### - -holiday.et-EE1.name=uusaasta -holiday.et-EE1.date=20150101 -holiday.et-EE2.name=iseseisvuspäev -holiday.et-EE2.date=20150224 -holiday.et-EE3.name=suur reede -holiday.et-EE3.date=20150403 -holiday.et-EE4.name=ülestõusmispühade 1. püha -holiday.et-EE4.date=20150405 -holiday.et-EE5.name=kevadpüha -holiday.et-EE5.date=20150501 -holiday.et-EE6.name=nelipühade 1. püha -holiday.et-EE6.date=20150524 -holiday.et-EE7.name=võidupüha -holiday.et-EE7.date=20150623 -holiday.et-EE8.name=jaanipäev -holiday.et-EE8.date=20150624 -holiday.et-EE9.name=taasiseseisvumispäev -holiday.et-EE9.date=20150820 -holiday.et-EE10.name=jõululaupäev -holiday.et-EE10.date=20151224 -holiday.et-EE11.name=esimene jõulupüha -holiday.et-EE11.date=20151225 -holiday.et-EE12.name=teine jõulupüha -holiday.et-EE12.date=20151226 -holiday.et-EE13.name=uusaasta -holiday.et-EE13.date=20160101 -holiday.et-EE14.name=iseseisvuspäev -holiday.et-EE14.date=20160224 -holiday.et-EE15.name=suur reede -holiday.et-EE15.date=20160325 -holiday.et-EE16.name=ülestõusmispühade 1. püha -holiday.et-EE16.date=20160327 -holiday.et-EE17.name=kevadpüha -holiday.et-EE17.date=20160501 -holiday.et-EE18.name=nelipühade 1. püha -holiday.et-EE18.date=20160515 -holiday.et-EE19.name=võidupüha -holiday.et-EE19.date=20160623 -holiday.et-EE20.name=jaanipäev -holiday.et-EE20.date=20160624 -holiday.et-EE21.name=taasiseseisvumispäev -holiday.et-EE21.date=20160820 -holiday.et-EE22.name=jõululaupäev -holiday.et-EE22.date=20161224 -holiday.et-EE23.name=esimene jõulupüha -holiday.et-EE23.date=20161225 -holiday.et-EE24.name=teine jõulupüha -holiday.et-EE24.date=20161226 diff --git a/doc/rc/holidays.fi-FI.rc b/doc/rc/holidays.fi-FI.rc index b05671ee6..c2c1e9efb 100644 --- a/doc/rc/holidays.fi-FI.rc +++ b/doc/rc/holidays.fi-FI.rc @@ -1,9 +1,9 @@ ############################################################################### # International Holiday Data provided by Holidata.net -# http://holidata.net/fi-FI/2015.json -# http://holidata.net/fi-FI/2016.json +# https://holidata.net/fi-FI/2020.json +# https://holidata.net/fi-FI/2021.json # -# Copyright 2006 - 2016, Paul Beckingham, Federico Hernandez. +# Copyright 2006 - 2020, 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 @@ -23,67 +23,59 @@ # 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 +# https://www.opensource.org/licenses/mit-license.php # ############################################################################### holiday.fi-FI1.name=Uudenvuodenpäivä -holiday.fi-FI1.date=20150101 +holiday.fi-FI1.date=20200101 holiday.fi-FI2.name=Loppiainen -holiday.fi-FI2.date=20150106 +holiday.fi-FI2.date=20200106 holiday.fi-FI3.name=Pitkäperjantai -holiday.fi-FI3.date=20150403 +holiday.fi-FI3.date=20200410 holiday.fi-FI4.name=Pääsiäispäivä -holiday.fi-FI4.date=20150405 +holiday.fi-FI4.date=20200412 holiday.fi-FI5.name=2. pääsiäispäivä -holiday.fi-FI5.date=20150406 +holiday.fi-FI5.date=20200413 holiday.fi-FI6.name=Vappu -holiday.fi-FI6.date=20150501 +holiday.fi-FI6.date=20200501 holiday.fi-FI7.name=Helatorstai -holiday.fi-FI7.date=20150514 +holiday.fi-FI7.date=20200521 holiday.fi-FI8.name=Helluntaipäivä -holiday.fi-FI8.date=20150524 -holiday.fi-FI9.name=Juhannusaatto -holiday.fi-FI9.date=20150619 -holiday.fi-FI10.name=Juhannuspäivä -holiday.fi-FI10.date=20150620 -holiday.fi-FI11.name=Pyhäinpäivä -holiday.fi-FI11.date=20151031 -holiday.fi-FI12.name=Itsenäisyyspäivä -holiday.fi-FI12.date=20151206 -holiday.fi-FI13.name=Jouluaatto -holiday.fi-FI13.date=20151224 -holiday.fi-FI14.name=Joulupäivä -holiday.fi-FI14.date=20151225 -holiday.fi-FI15.name=2. joulupäivä -holiday.fi-FI15.date=20151226 -holiday.fi-FI16.name=Uudenvuodenpäivä -holiday.fi-FI16.date=20160101 -holiday.fi-FI17.name=Loppiainen -holiday.fi-FI17.date=20160106 -holiday.fi-FI18.name=Pitkäperjantai -holiday.fi-FI18.date=20160325 -holiday.fi-FI19.name=Pääsiäispäivä -holiday.fi-FI19.date=20160327 -holiday.fi-FI20.name=2. pääsiäispäivä -holiday.fi-FI20.date=20160328 -holiday.fi-FI21.name=Vappu -holiday.fi-FI21.date=20160501 -holiday.fi-FI22.name=Helatorstai -holiday.fi-FI22.date=20160505 -holiday.fi-FI23.name=Helluntaipäivä -holiday.fi-FI23.date=20160515 -holiday.fi-FI24.name=Juhannusaatto -holiday.fi-FI24.date=20160624 -holiday.fi-FI25.name=Juhannuspäivä -holiday.fi-FI25.date=20160625 -holiday.fi-FI26.name=Pyhäinpäivä -holiday.fi-FI26.date=20161105 -holiday.fi-FI27.name=Itsenäisyyspäivä -holiday.fi-FI27.date=20161206 -holiday.fi-FI28.name=Jouluaatto -holiday.fi-FI28.date=20161224 -holiday.fi-FI29.name=Joulupäivä -holiday.fi-FI29.date=20161225 -holiday.fi-FI30.name=2. joulupäivä -holiday.fi-FI30.date=20161226 +holiday.fi-FI8.date=20200531 +holiday.fi-FI9.name=Juhannuspäivä +holiday.fi-FI9.date=20200620 +holiday.fi-FI10.name=Pyhäinpäivä +holiday.fi-FI10.date=20201031 +holiday.fi-FI11.name=Itsenäisyyspäivä +holiday.fi-FI11.date=20201206 +holiday.fi-FI12.name=Joulupäivä +holiday.fi-FI12.date=20201225 +holiday.fi-FI13.name=Tapaninpäivä +holiday.fi-FI13.date=20201226 +holiday.fi-FI14.name=Uudenvuodenpäivä +holiday.fi-FI14.date=20210101 +holiday.fi-FI15.name=Loppiainen +holiday.fi-FI15.date=20210106 +holiday.fi-FI16.name=Pitkäperjantai +holiday.fi-FI16.date=20210402 +holiday.fi-FI17.name=Pääsiäispäivä +holiday.fi-FI17.date=20210404 +holiday.fi-FI18.name=2. pääsiäispäivä +holiday.fi-FI18.date=20210405 +holiday.fi-FI19.name=Vappu +holiday.fi-FI19.date=20210501 +holiday.fi-FI20.name=Helatorstai +holiday.fi-FI20.date=20210513 +holiday.fi-FI21.name=Helluntaipäivä +holiday.fi-FI21.date=20210523 +holiday.fi-FI22.name=Juhannuspäivä +holiday.fi-FI22.date=20210626 +holiday.fi-FI23.name=Pyhäinpäivä +holiday.fi-FI23.date=20211106 +holiday.fi-FI24.name=Itsenäisyyspäivä +holiday.fi-FI24.date=20211206 +holiday.fi-FI25.name=Joulupäivä +holiday.fi-FI25.date=20211225 +holiday.fi-FI26.name=Tapaninpäivä +holiday.fi-FI26.date=20211226 diff --git a/doc/rc/holidays.fr-BE.rc b/doc/rc/holidays.fr-BE.rc index 7f7ed30e4..89462636b 100644 --- a/doc/rc/holidays.fr-BE.rc +++ b/doc/rc/holidays.fr-BE.rc @@ -1,9 +1,9 @@ ############################################################################### # International Holiday Data provided by Holidata.net -# http://holidata.net/fr-BE/2015.json -# http://holidata.net/fr-BE/2016.json +# https://holidata.net/fr-BE/2020.json +# https://holidata.net/fr-BE/2021.json # -# Copyright 2006 - 2016, Paul Beckingham, Federico Hernandez. +# Copyright 2006 - 2020, 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 @@ -23,55 +23,55 @@ # 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 +# https://www.opensource.org/licenses/mit-license.php # ############################################################################### holiday.fr-BE1.name=Nouvel An -holiday.fr-BE1.date=20150101 +holiday.fr-BE1.date=20200101 holiday.fr-BE2.name=Pâques -holiday.fr-BE2.date=20150405 +holiday.fr-BE2.date=20200412 holiday.fr-BE3.name=Lundi de Pâques -holiday.fr-BE3.date=20150406 +holiday.fr-BE3.date=20200413 holiday.fr-BE4.name=Fête du Travail -holiday.fr-BE4.date=20150501 +holiday.fr-BE4.date=20200501 holiday.fr-BE5.name=Ascension -holiday.fr-BE5.date=20150514 +holiday.fr-BE5.date=20200521 holiday.fr-BE6.name=Pentecôte -holiday.fr-BE6.date=20150524 +holiday.fr-BE6.date=20200531 holiday.fr-BE7.name=Lundi de Pentecôte -holiday.fr-BE7.date=20150525 +holiday.fr-BE7.date=20200601 holiday.fr-BE8.name=Fête nationale -holiday.fr-BE8.date=20150721 +holiday.fr-BE8.date=20200721 holiday.fr-BE9.name=Assomption -holiday.fr-BE9.date=20150815 +holiday.fr-BE9.date=20200815 holiday.fr-BE10.name=Toussaint -holiday.fr-BE10.date=20151101 +holiday.fr-BE10.date=20201101 holiday.fr-BE11.name=Jour de l'armistice -holiday.fr-BE11.date=20151111 +holiday.fr-BE11.date=20201111 holiday.fr-BE12.name=Noël -holiday.fr-BE12.date=20151225 +holiday.fr-BE12.date=20201225 holiday.fr-BE13.name=Nouvel An -holiday.fr-BE13.date=20160101 +holiday.fr-BE13.date=20210101 holiday.fr-BE14.name=Pâques -holiday.fr-BE14.date=20160527 +holiday.fr-BE14.date=20210404 holiday.fr-BE15.name=Lundi de Pâques -holiday.fr-BE15.date=20160528 +holiday.fr-BE15.date=20210405 holiday.fr-BE16.name=Fête du Travail -holiday.fr-BE16.date=20160501 +holiday.fr-BE16.date=20210501 holiday.fr-BE17.name=Ascension -holiday.fr-BE17.date=20160505 +holiday.fr-BE17.date=20210513 holiday.fr-BE18.name=Pentecôte -holiday.fr-BE18.date=20160515 +holiday.fr-BE18.date=20210523 holiday.fr-BE19.name=Lundi de Pentecôte -holiday.fr-BE19.date=20160516 +holiday.fr-BE19.date=20210524 holiday.fr-BE20.name=Fête nationale -holiday.fr-BE20.date=20160721 +holiday.fr-BE20.date=20210721 holiday.fr-BE21.name=Assomption -holiday.fr-BE21.date=20160815 +holiday.fr-BE21.date=20210815 holiday.fr-BE22.name=Toussaint -holiday.fr-BE22.date=20161101 +holiday.fr-BE22.date=20211101 holiday.fr-BE23.name=Jour de l'armistice -holiday.fr-BE23.date=20161111 +holiday.fr-BE23.date=20211111 holiday.fr-BE24.name=Noël -holiday.fr-BE24.date=20161225 +holiday.fr-BE24.date=20211225 diff --git a/doc/rc/holidays.fr-FR.rc b/doc/rc/holidays.fr-FR.rc index 78426dd98..39053f60a 100644 --- a/doc/rc/holidays.fr-FR.rc +++ b/doc/rc/holidays.fr-FR.rc @@ -1,9 +1,9 @@ ############################################################################### # International Holiday Data provided by Holidata.net -# http://holidata.net/fr-FR/2015.json -# http://holidata.net/fr-FR/2016.json +# https://holidata.net/fr-FR/2020.json +# https://holidata.net/fr-FR/2021.json # -# Copyright 2006 - 2016, Paul Beckingham, Federico Hernandez. +# Copyright 2006 - 2020, 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 @@ -23,51 +23,55 @@ # 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 +# https://www.opensource.org/licenses/mit-license.php # ############################################################################### holiday.fr-FR1.name=Jour de l'an -holiday.fr-FR1.date=20150101 +holiday.fr-FR1.date=20200101 holiday.fr-FR2.name=Lundi de Pâques -holiday.fr-FR2.date=20150406 +holiday.fr-FR2.date=20200413 holiday.fr-FR3.name=Fête du premier mai -holiday.fr-FR3.date=20150501 +holiday.fr-FR3.date=20200501 holiday.fr-FR4.name=Armistice 1945 -holiday.fr-FR4.date=20150508 +holiday.fr-FR4.date=20200508 holiday.fr-FR5.name=Ascencion -holiday.fr-FR5.date=20150514 +holiday.fr-FR5.date=20200521 holiday.fr-FR6.name=Pentecôte -holiday.fr-FR6.date=20150524 -holiday.fr-FR7.name=Fête nationale -holiday.fr-FR7.date=20150714 -holiday.fr-FR8.name=Assomption -holiday.fr-FR8.date=20150815 -holiday.fr-FR9.name=Toussaint -holiday.fr-FR9.date=20151101 -holiday.fr-FR10.name=Armistice 1918 -holiday.fr-FR10.date=20151111 -holiday.fr-FR11.name=Noël -holiday.fr-FR11.date=20151225 -holiday.fr-FR12.name=Jour de l'an -holiday.fr-FR12.date=20160101 -holiday.fr-FR13.name=Lundi de Pâques -holiday.fr-FR13.date=20160328 -holiday.fr-FR14.name=Fête du premier mai -holiday.fr-FR14.date=20160501 -holiday.fr-FR15.name=Armistice 1945 -holiday.fr-FR15.date=20160508 -holiday.fr-FR16.name=Ascencion -holiday.fr-FR16.date=20160505 -holiday.fr-FR17.name=Pentecôte -holiday.fr-FR17.date=20160515 -holiday.fr-FR18.name=Fête nationale -holiday.fr-FR18.date=20160714 -holiday.fr-FR19.name=Assomption -holiday.fr-FR19.date=20160815 -holiday.fr-FR20.name=Toussaint -holiday.fr-FR20.date=20161101 -holiday.fr-FR21.name=Armistice 1918 -holiday.fr-FR21.date=20161111 -holiday.fr-FR22.name=Noël -holiday.fr-FR22.date=20161225 +holiday.fr-FR6.date=20200531 +holiday.fr-FR7.name=Lundi de Pentecôte +holiday.fr-FR7.date=20200601 +holiday.fr-FR8.name=Fête nationale +holiday.fr-FR8.date=20200714 +holiday.fr-FR9.name=Assomption +holiday.fr-FR9.date=20200815 +holiday.fr-FR10.name=Toussaint +holiday.fr-FR10.date=20201101 +holiday.fr-FR11.name=Armistice 1918 +holiday.fr-FR11.date=20201111 +holiday.fr-FR12.name=Noël +holiday.fr-FR12.date=20201225 +holiday.fr-FR13.name=Jour de l'an +holiday.fr-FR13.date=20210101 +holiday.fr-FR14.name=Lundi de Pâques +holiday.fr-FR14.date=20210405 +holiday.fr-FR15.name=Fête du premier mai +holiday.fr-FR15.date=20210501 +holiday.fr-FR16.name=Armistice 1945 +holiday.fr-FR16.date=20210508 +holiday.fr-FR17.name=Ascencion +holiday.fr-FR17.date=20210513 +holiday.fr-FR18.name=Pentecôte +holiday.fr-FR18.date=20210523 +holiday.fr-FR19.name=Lundi de Pentecôte +holiday.fr-FR19.date=20210524 +holiday.fr-FR20.name=Fête nationale +holiday.fr-FR20.date=20210714 +holiday.fr-FR21.name=Assomption +holiday.fr-FR21.date=20210815 +holiday.fr-FR22.name=Toussaint +holiday.fr-FR22.date=20211101 +holiday.fr-FR23.name=Armistice 1918 +holiday.fr-FR23.date=20211111 +holiday.fr-FR24.name=Noël +holiday.fr-FR24.date=20211225 diff --git a/doc/rc/holidays.ga-IE.rc b/doc/rc/holidays.ga-IE.rc deleted file mode 100644 index 5a13d9ada..000000000 --- a/doc/rc/holidays.ga-IE.rc +++ /dev/null @@ -1,65 +0,0 @@ -############################################################################### -# International Holiday Data provided by Holidata.net -# http://holidata.net/ga-IE/2015.json -# http://holidata.net/ga-IE/2016.json -# -# Copyright 2006 - 2016, 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 -# -############################################################################### - -holiday.ga-IE1.name=Lá Caille or Lá Bliana Nua -holiday.ga-IE1.date=20150101 -holiday.ga-IE2.name=Lá Fhéile Pádraig -holiday.ga-IE2.date=20150317 -holiday.ga-IE3.name=Luan Cásca -holiday.ga-IE3.date=20150406 -holiday.ga-IE4.name=Lá an Lucht Oibre -holiday.ga-IE4.date=20150504 -holiday.ga-IE5.name=Lá Saoire i mí Mheitheamh -holiday.ga-IE5.date=20150601 -holiday.ga-IE6.name=Lá Saoire i mí Lúnasa -holiday.ga-IE6.date=20150803 -holiday.ga-IE7.name=Lá Saoire i mí Dheireadh Fómhair -holiday.ga-IE7.date=20151026 -holiday.ga-IE8.name=Lá Nollag -holiday.ga-IE8.date=20151225 -holiday.ga-IE9.name=Lá Fhéile Stiofáin or Lá an Dreoilín -holiday.ga-IE9.date=20151226 -holiday.ga-IE10.name=Lá Caille or Lá Bliana Nua -holiday.ga-IE10.date=20160101 -holiday.ga-IE11.name=Lá Fhéile Pádraig -holiday.ga-IE11.date=20160317 -holiday.ga-IE12.name=Luan Cásca -holiday.ga-IE12.date=20160328 -holiday.ga-IE13.name=Lá an Lucht Oibre -holiday.ga-IE13.date=20160502 -holiday.ga-IE14.name=Lá Saoire i mí Mheitheamh -holiday.ga-IE14.date=20160606 -holiday.ga-IE15.name=Lá Saoire i mí Lúnasa -holiday.ga-IE15.date=20160801 -holiday.ga-IE16.name=Lá Saoire i mí Dheireadh Fómhair -holiday.ga-IE16.date=20161031 -holiday.ga-IE17.name=Lá Nollag -holiday.ga-IE17.date=20161225 -holiday.ga-IE18.name=Lá Fhéile Stiofáin or Lá an Dreoilín -holiday.ga-IE18.date=20161226 diff --git a/doc/rc/holidays.hr-HR.rc b/doc/rc/holidays.hr-HR.rc index 09bfaab43..cd2158325 100644 --- a/doc/rc/holidays.hr-HR.rc +++ b/doc/rc/holidays.hr-HR.rc @@ -1,9 +1,9 @@ ############################################################################### # International Holiday Data provided by Holidata.net -# http://holidata.net/hr-HR/2015.json -# http://holidata.net/hr-HR/2016.json +# https://holidata.net/hr-HR/2020.json +# https://holidata.net/hr-HR/2021.json # -# Copyright 2006 - 2016, Paul Beckingham, Federico Hernandez. +# Copyright 2006 - 2020, 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 @@ -23,63 +23,67 @@ # 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 +# https://www.opensource.org/licenses/mit-license.php # ############################################################################### holiday.hr-HR1.name=Nova Godina -holiday.hr-HR1.date=20150101 +holiday.hr-HR1.date=20200101 holiday.hr-HR2.name=Bogojavljenje -holiday.hr-HR2.date=20150106 +holiday.hr-HR2.date=20200106 holiday.hr-HR3.name=Uskrs -holiday.hr-HR3.date=20150405 +holiday.hr-HR3.date=20200412 holiday.hr-HR4.name=Uskrsni ponedjeljak -holiday.hr-HR4.date=20150406 -holiday.hr-HR5.name=Međunarodni praznik rada -holiday.hr-HR5.date=20150501 +holiday.hr-HR4.date=20200413 +holiday.hr-HR5.name=Praznik rada +holiday.hr-HR5.date=20200501 holiday.hr-HR6.name=Tijelovo -holiday.hr-HR6.date=20150604 +holiday.hr-HR6.date=20200611 holiday.hr-HR7.name=Dan antifašističke borbe -holiday.hr-HR7.date=20150622 +holiday.hr-HR7.date=20200622 holiday.hr-HR8.name=Dan državnosti -holiday.hr-HR8.date=20150625 -holiday.hr-HR9.name=Dan pobjede -holiday.hr-HR9.date=20150805 +holiday.hr-HR8.date=20200625 +holiday.hr-HR9.name=Dan pobjede i domovinske zahvalnosti i Dan hrvatskih branitelja +holiday.hr-HR9.date=20200805 holiday.hr-HR10.name=Velika Gospa -holiday.hr-HR10.date=20150815 +holiday.hr-HR10.date=20200815 holiday.hr-HR11.name=Dan neovisnosti -holiday.hr-HR11.date=20151008 -holiday.hr-HR12.name=Dan svih svetih -holiday.hr-HR12.date=20151101 -holiday.hr-HR13.name=Božić -holiday.hr-HR13.date=20151225 -holiday.hr-HR14.name=Prvi dan po Božiću -holiday.hr-HR14.date=20151226 -holiday.hr-HR15.name=Nova Godina -holiday.hr-HR15.date=20160101 -holiday.hr-HR16.name=Bogojavljenje -holiday.hr-HR16.date=20160106 -holiday.hr-HR17.name=Uskrs -holiday.hr-HR17.date=20160327 -holiday.hr-HR18.name=Uskrsni ponedjeljak -holiday.hr-HR18.date=20160328 -holiday.hr-HR19.name=Međunarodni praznik rada -holiday.hr-HR19.date=20160501 -holiday.hr-HR20.name=Tijelovo -holiday.hr-HR20.date=20160526 -holiday.hr-HR21.name=Dan antifašističke borbe -holiday.hr-HR21.date=20160622 -holiday.hr-HR22.name=Dan državnosti -holiday.hr-HR22.date=20160625 -holiday.hr-HR23.name=Dan pobjede -holiday.hr-HR23.date=20160805 -holiday.hr-HR24.name=Velika Gospa -holiday.hr-HR24.date=20160815 -holiday.hr-HR25.name=Dan neovisnosti -holiday.hr-HR25.date=20161008 -holiday.hr-HR26.name=Dan svih svetih -holiday.hr-HR26.date=20161101 -holiday.hr-HR27.name=Božić -holiday.hr-HR27.date=20161225 -holiday.hr-HR28.name=Prvi dan po Božiću -holiday.hr-HR28.date=20161226 +holiday.hr-HR11.date=20201008 +holiday.hr-HR12.name=Svi sveti +holiday.hr-HR12.date=20201101 +holiday.hr-HR13.name=Dan sjećanja na žrtve Domovinskog rata i Dan sjećanja na žrtvu Vukovara i Škabrnje +holiday.hr-HR13.date=20201118 +holiday.hr-HR14.name=Božić +holiday.hr-HR14.date=20201225 +holiday.hr-HR15.name=Sveti Stjepan +holiday.hr-HR15.date=20201226 +holiday.hr-HR16.name=Nova Godina +holiday.hr-HR16.date=20210101 +holiday.hr-HR17.name=Bogojavljenje +holiday.hr-HR17.date=20210106 +holiday.hr-HR18.name=Uskrs +holiday.hr-HR18.date=20210404 +holiday.hr-HR19.name=Uskrsni ponedjeljak +holiday.hr-HR19.date=20210405 +holiday.hr-HR20.name=Praznik rada +holiday.hr-HR20.date=20210501 +holiday.hr-HR21.name=Tijelovo +holiday.hr-HR21.date=20210603 +holiday.hr-HR22.name=Dan antifašističke borbe +holiday.hr-HR22.date=20210622 +holiday.hr-HR23.name=Dan državnosti +holiday.hr-HR23.date=20210625 +holiday.hr-HR24.name=Dan pobjede i domovinske zahvalnosti i Dan hrvatskih branitelja +holiday.hr-HR24.date=20210805 +holiday.hr-HR25.name=Velika Gospa +holiday.hr-HR25.date=20210815 +holiday.hr-HR26.name=Dan neovisnosti +holiday.hr-HR26.date=20211008 +holiday.hr-HR27.name=Svi sveti +holiday.hr-HR27.date=20211101 +holiday.hr-HR28.name=Dan sjećanja na žrtve Domovinskog rata i Dan sjećanja na žrtvu Vukovara i Škabrnje +holiday.hr-HR28.date=20211118 +holiday.hr-HR29.name=Božić +holiday.hr-HR29.date=20211225 +holiday.hr-HR30.name=Sveti Stjepan +holiday.hr-HR30.date=20211226 diff --git a/doc/rc/holidays.is-IS.rc b/doc/rc/holidays.is-IS.rc index ca08273bc..a1a94ddb9 100644 --- a/doc/rc/holidays.is-IS.rc +++ b/doc/rc/holidays.is-IS.rc @@ -1,9 +1,9 @@ ############################################################################### # International Holiday Data provided by Holidata.net -# http://holidata.net/is-IS/2015.json -# http://holidata.net/is-IS/2016.json +# https://holidata.net/is-IS/2020.json +# https://holidata.net/is-IS/2021.json # -# Copyright 2006 - 2016, Paul Beckingham, Federico Hernandez. +# Copyright 2006 - 2020, 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 @@ -23,67 +23,71 @@ # 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 +# https://www.opensource.org/licenses/mit-license.php # ############################################################################### holiday.is-IS1.name=Nýársdagur -holiday.is-IS1.date=20150101 +holiday.is-IS1.date=20200101 holiday.is-IS2.name=Skírdagur -holiday.is-IS2.date=20150402 -holiday.is-IS3.name=Föstudaginn langi -holiday.is-IS3.date=20150403 +holiday.is-IS2.date=20200409 +holiday.is-IS3.name=Föstudagurinn langi +holiday.is-IS3.date=20200410 holiday.is-IS4.name=Páskadagur -holiday.is-IS4.date=20150405 -holiday.is-IS5.name=Annar í páskum -holiday.is-IS5.date=20150406 +holiday.is-IS4.date=20200412 +holiday.is-IS5.name=Annar dagur páska +holiday.is-IS5.date=20200413 holiday.is-IS6.name=Sumardagurinn fyrsti -holiday.is-IS6.date=20150423 +holiday.is-IS6.date=20200423 holiday.is-IS7.name=Verkalýðsdagurinn -holiday.is-IS7.date=20150501 +holiday.is-IS7.date=20200501 holiday.is-IS8.name=Uppstigningardagur -holiday.is-IS8.date=20150514 -holiday.is-IS9.name=Annar í hvítasunnu -holiday.is-IS9.date=20150525 -holiday.is-IS10.name=Lýðveldisdagurinn -holiday.is-IS10.date=20150617 -holiday.is-IS11.name=Frídagur verslunarmanna -holiday.is-IS11.date=20150803 -holiday.is-IS12.name=Jól -holiday.is-IS12.date=20151224 -holiday.is-IS13.name=Jól -holiday.is-IS13.date=20151225 -holiday.is-IS14.name=Jól -holiday.is-IS14.date=20151226 -holiday.is-IS15.name=Gamlárskvöld -holiday.is-IS15.date=20151231 -holiday.is-IS16.name=Nýársdagur -holiday.is-IS16.date=20160101 -holiday.is-IS17.name=Skírdagur -holiday.is-IS17.date=20160324 -holiday.is-IS18.name=Föstudaginn langi -holiday.is-IS18.date=20160325 -holiday.is-IS19.name=Páskadagur -holiday.is-IS19.date=20160327 -holiday.is-IS20.name=Annar í páskum -holiday.is-IS20.date=20160328 -holiday.is-IS21.name=Sumardagurinn fyrsti -holiday.is-IS21.date=20160421 -holiday.is-IS22.name=Verkalýðsdagurinn -holiday.is-IS22.date=20160501 -holiday.is-IS23.name=Uppstigningardagur -holiday.is-IS23.date=20160505 -holiday.is-IS24.name=Annar í hvítasunnu -holiday.is-IS24.date=20160516 -holiday.is-IS25.name=Lýðveldisdagurinn -holiday.is-IS25.date=20160617 -holiday.is-IS26.name=Frídagur verslunarmanna -holiday.is-IS26.date=20160801 -holiday.is-IS27.name=Jól -holiday.is-IS27.date=20161224 -holiday.is-IS28.name=Jól -holiday.is-IS28.date=20161225 -holiday.is-IS29.name=Jól -holiday.is-IS29.date=20161226 -holiday.is-IS30.name=Gamlárskvöld -holiday.is-IS30.date=20161231 +holiday.is-IS8.date=20200521 +holiday.is-IS9.name=Hvítasunnudagur +holiday.is-IS9.date=20200531 +holiday.is-IS10.name=Annar dagur hvítasunnu +holiday.is-IS10.date=20200601 +holiday.is-IS11.name=Þjóðhátíðardagurinn +holiday.is-IS11.date=20200617 +holiday.is-IS12.name=Frídagur verslunarmanna +holiday.is-IS12.date=20200803 +holiday.is-IS13.name=Aðfangadagur jóla +holiday.is-IS13.date=20201224 +holiday.is-IS14.name=Jóladagur +holiday.is-IS14.date=20201225 +holiday.is-IS15.name=Annar dagur jóla +holiday.is-IS15.date=20201226 +holiday.is-IS16.name=Gamlársdagur +holiday.is-IS16.date=20201231 +holiday.is-IS17.name=Nýársdagur +holiday.is-IS17.date=20210101 +holiday.is-IS18.name=Skírdagur +holiday.is-IS18.date=20210401 +holiday.is-IS19.name=Föstudagurinn langi +holiday.is-IS19.date=20210402 +holiday.is-IS20.name=Páskadagur +holiday.is-IS20.date=20210404 +holiday.is-IS21.name=Annar dagur páska +holiday.is-IS21.date=20210405 +holiday.is-IS22.name=Sumardagurinn fyrsti +holiday.is-IS22.date=20210422 +holiday.is-IS23.name=Verkalýðsdagurinn +holiday.is-IS23.date=20210501 +holiday.is-IS24.name=Uppstigningardagur +holiday.is-IS24.date=20210513 +holiday.is-IS25.name=Hvítasunnudagur +holiday.is-IS25.date=20210523 +holiday.is-IS26.name=Annar dagur hvítasunnu +holiday.is-IS26.date=20210524 +holiday.is-IS27.name=Þjóðhátíðardagurinn +holiday.is-IS27.date=20210617 +holiday.is-IS28.name=Frídagur verslunarmanna +holiday.is-IS28.date=20210802 +holiday.is-IS29.name=Aðfangadagur jóla +holiday.is-IS29.date=20211224 +holiday.is-IS30.name=Jóladagur +holiday.is-IS30.date=20211225 +holiday.is-IS31.name=Annar dagur jóla +holiday.is-IS31.date=20211226 +holiday.is-IS32.name=Gamlársdagur +holiday.is-IS32.date=20211231 diff --git a/doc/rc/holidays.it-IT.rc b/doc/rc/holidays.it-IT.rc index 4d83610ae..3e9123004 100644 --- a/doc/rc/holidays.it-IT.rc +++ b/doc/rc/holidays.it-IT.rc @@ -1,9 +1,9 @@ ############################################################################### # International Holiday Data provided by Holidata.net -# http://holidata.net/it-IT/2015.json -# http://holidata.net/it-IT/2016.json +# https://holidata.net/it-IT/2020.json +# https://holidata.net/it-IT/2021.json # -# Copyright 2006 - 2016, Paul Beckingham, Federico Hernandez. +# Copyright 2006 - 2020, 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 @@ -23,55 +23,55 @@ # 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 +# https://www.opensource.org/licenses/mit-license.php # ############################################################################### holiday.it-IT1.name=Capodanno -holiday.it-IT1.date=20150101 +holiday.it-IT1.date=20200101 holiday.it-IT2.name=Epifania -holiday.it-IT2.date=20150106 -holiday.it-IT3.name=Carnevale -holiday.it-IT3.date=20150217 -holiday.it-IT4.name=Pasqua -holiday.it-IT4.date=20150405 +holiday.it-IT2.date=20200106 +holiday.it-IT3.name=Pasqua +holiday.it-IT3.date=20200412 +holiday.it-IT4.name=Pasquetta +holiday.it-IT4.date=20200413 holiday.it-IT5.name=Festa della liberazione -holiday.it-IT5.date=20150425 +holiday.it-IT5.date=20200425 holiday.it-IT6.name=Festa del lavoro -holiday.it-IT6.date=20150501 +holiday.it-IT6.date=20200501 holiday.it-IT7.name=Festa della repubblica -holiday.it-IT7.date=20150602 +holiday.it-IT7.date=20200602 holiday.it-IT8.name=Assunzione (ferragosto) -holiday.it-IT8.date=20150815 +holiday.it-IT8.date=20200815 holiday.it-IT9.name=Ognissanti -holiday.it-IT9.date=20151101 +holiday.it-IT9.date=20201101 holiday.it-IT10.name=Immacolata concezione -holiday.it-IT10.date=20151208 +holiday.it-IT10.date=20201208 holiday.it-IT11.name=Natale -holiday.it-IT11.date=20151225 +holiday.it-IT11.date=20201225 holiday.it-IT12.name=S.to Stefano -holiday.it-IT12.date=20151226 +holiday.it-IT12.date=20201226 holiday.it-IT13.name=Capodanno -holiday.it-IT13.date=20160101 +holiday.it-IT13.date=20210101 holiday.it-IT14.name=Epifania -holiday.it-IT14.date=20160106 -holiday.it-IT15.name=Carnevale -holiday.it-IT15.date=20160209 -holiday.it-IT16.name=Pasqua -holiday.it-IT16.date=20160327 +holiday.it-IT14.date=20210106 +holiday.it-IT15.name=Pasqua +holiday.it-IT15.date=20210404 +holiday.it-IT16.name=Pasquetta +holiday.it-IT16.date=20210405 holiday.it-IT17.name=Festa della liberazione -holiday.it-IT17.date=20160425 +holiday.it-IT17.date=20210425 holiday.it-IT18.name=Festa del lavoro -holiday.it-IT18.date=20160501 +holiday.it-IT18.date=20210501 holiday.it-IT19.name=Festa della repubblica -holiday.it-IT19.date=20160602 +holiday.it-IT19.date=20210602 holiday.it-IT20.name=Assunzione (ferragosto) -holiday.it-IT20.date=20160815 +holiday.it-IT20.date=20210815 holiday.it-IT21.name=Ognissanti -holiday.it-IT21.date=20161101 +holiday.it-IT21.date=20211101 holiday.it-IT22.name=Immacolata concezione -holiday.it-IT22.date=20161208 +holiday.it-IT22.date=20211208 holiday.it-IT23.name=Natale -holiday.it-IT23.date=20161225 +holiday.it-IT23.date=20211225 holiday.it-IT24.name=S.to Stefano -holiday.it-IT24.date=20161226 +holiday.it-IT24.date=20211226 diff --git a/doc/rc/holidays.jp-JP.rc b/doc/rc/holidays.jp-JP.rc deleted file mode 100644 index 66c05d4ff..000000000 --- a/doc/rc/holidays.jp-JP.rc +++ /dev/null @@ -1,91 +0,0 @@ -############################################################################### -# International Holiday Data provided by Holidata.net -# http://holidata.net/jp-JP/2015.json -# http://holidata.net/jp-JP/2016.json -# -# Copyright 2006 - 2016, 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 -# -############################################################################### - -holiday.jp-JP1.name=元日 -holiday.jp-JP1.date=20150101 -holiday.jp-JP2.name=成人の日 -holiday.jp-JP2.date=20150112 -holiday.jp-JP3.name=建国記念の日 -holiday.jp-JP3.date=20150211 -holiday.jp-JP4.name=春分の日 -holiday.jp-JP4.date=20150321 -holiday.jp-JP5.name=昭和の日 -holiday.jp-JP5.date=20150429 -holiday.jp-JP6.name=憲法記念日 -holiday.jp-JP6.date=20150503 -holiday.jp-JP7.name=みどりの日 -holiday.jp-JP7.date=20150504 -holiday.jp-JP8.name=こどもの日 -holiday.jp-JP8.date=20150505 -holiday.jp-JP9.name=振替休日 -holiday.jp-JP9.date=20150506 -holiday.jp-JP10.name=海の日 -holiday.jp-JP10.date=20150720 -holiday.jp-JP11.name=敬老の日 -holiday.jp-JP11.date=20150921 -holiday.jp-JP12.name=秋分の日 -holiday.jp-JP12.date=20150923 -holiday.jp-JP13.name=体育の日 -holiday.jp-JP13.date=20151012 -holiday.jp-JP14.name=文化の日 -holiday.jp-JP14.date=20151103 -holiday.jp-JP15.name=勤労感謝の日 -holiday.jp-JP15.date=20151123 -holiday.jp-JP16.name=天皇誕生日 -holiday.jp-JP16.date=20151223 -holiday.jp-JP17.name=元日 -holiday.jp-JP17.date=20160101 -holiday.jp-JP18.name=成人の日 -holiday.jp-JP18.date=20160111 -holiday.jp-JP19.name=建国記念の日 -holiday.jp-JP19.date=20160211 -holiday.jp-JP20.name=春分の日 -holiday.jp-JP20.date=20160321 -holiday.jp-JP21.name=昭和の日 -holiday.jp-JP21.date=20160429 -holiday.jp-JP22.name=憲法記念日 -holiday.jp-JP22.date=20160503 -holiday.jp-JP23.name=みどりの日 -holiday.jp-JP23.date=20160504 -holiday.jp-JP24.name=こどもの日 -holiday.jp-JP24.date=20160505 -holiday.jp-JP25.name=海の日 -holiday.jp-JP25.date=20160718 -holiday.jp-JP26.name=敬老の日 -holiday.jp-JP26.date=20160919 -holiday.jp-JP27.name=秋分の日 -holiday.jp-JP27.date=20160922 -holiday.jp-JP28.name=体育の日 -holiday.jp-JP28.date=20161010 -holiday.jp-JP29.name=文化の日 -holiday.jp-JP29.date=20161103 -holiday.jp-JP30.name=勤労感謝の日 -holiday.jp-JP30.date=20161123 -holiday.jp-JP31.name=天皇誕生日 -holiday.jp-JP31.date=20161223 diff --git a/doc/rc/holidays.lt-LT.rc b/doc/rc/holidays.lt-LT.rc deleted file mode 100644 index 13ed0790f..000000000 --- a/doc/rc/holidays.lt-LT.rc +++ /dev/null @@ -1,81 +0,0 @@ -############################################################################### -# International Holiday Data provided by Holidata.net -# http://holidata.net/lt-LT/2015.json -# http://holidata.net/lt-LT/2016.json -# -# Copyright 2006 - 2016, 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 -# -############################################################################### - -holiday.lt-LT1.name=Naujieji metai -holiday.lt-LT1.date=20150101 -holiday.lt-LT2.name=Lietuvos valstybės atkūrimo diena -holiday.lt-LT2.date=20150216 -holiday.lt-LT3.name=Lietuvos nepriklausomybės atkūrimo diena -holiday.lt-LT3.date=20150311 -holiday.lt-LT4.name=Velykos -holiday.lt-LT4.date=20150405 -holiday.lt-LT5.name=Velykos -holiday.lt-LT5.date=20150406 -holiday.lt-LT6.name=Tarptautinė darbo diena -holiday.lt-LT6.date=20150501 -holiday.lt-LT7.name=Joninės, Rasos -holiday.lt-LT7.date=20150624 -holiday.lt-LT8.name=Valstybės diena -holiday.lt-LT8.date=20150706 -holiday.lt-LT9.name=Žolinė -holiday.lt-LT9.date=20150815 -holiday.lt-LT10.name=Visų šventųjų diena -holiday.lt-LT10.date=20151101 -holiday.lt-LT11.name=Šv. Kalėdos -holiday.lt-LT11.date=20151224 -holiday.lt-LT12.name=Šv. Kalėdos -holiday.lt-LT12.date=20151225 -holiday.lt-LT13.name=Šv. Kalėdos -holiday.lt-LT13.date=20151226 -holiday.lt-LT14.name=Naujieji metai -holiday.lt-LT14.date=20160101 -holiday.lt-LT15.name=Lietuvos valstybės atkūrimo diena -holiday.lt-LT15.date=20160216 -holiday.lt-LT16.name=Lietuvos nepriklausomybės atkūrimo diena -holiday.lt-LT16.date=20160311 -holiday.lt-LT17.name=Velykos -holiday.lt-LT17.date=20160327 -holiday.lt-LT18.name=Velykos -holiday.lt-LT18.date=20160328 -holiday.lt-LT19.name=Tarptautinė darbo diena -holiday.lt-LT19.date=20160501 -holiday.lt-LT20.name=Joninės, Rasos -holiday.lt-LT20.date=20160624 -holiday.lt-LT21.name=Valstybės diena -holiday.lt-LT21.date=20160706 -holiday.lt-LT22.name=Žolinė -holiday.lt-LT22.date=20160815 -holiday.lt-LT23.name=Visų šventųjų diena -holiday.lt-LT23.date=20161101 -holiday.lt-LT24.name=Šv. Kalėdos -holiday.lt-LT24.date=20161224 -holiday.lt-LT25.name=Šv. Kalėdos -holiday.lt-LT25.date=20161225 -holiday.lt-LT26.name=Šv. Kalėdos -holiday.lt-LT26.date=20161226 diff --git a/doc/rc/holidays.lv-LV.rc b/doc/rc/holidays.lv-LV.rc deleted file mode 100644 index 9ba43134e..000000000 --- a/doc/rc/holidays.lv-LV.rc +++ /dev/null @@ -1,77 +0,0 @@ -############################################################################### -# International Holiday Data provided by Holidata.net -# http://holidata.net/lv-LV/2015.json -# http://holidata.net/lv-LV/2016.json -# -# Copyright 2006 - 2016, 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 -# -############################################################################### - -holiday.lv-LV1.name=Jaunais Gads -holiday.lv-LV1.date=20150101 -holiday.lv-LV2.name=Lielā Piektdiena -holiday.lv-LV2.date=20150403 -holiday.lv-LV3.name=Lieldienas -holiday.lv-LV3.date=20150405 -holiday.lv-LV4.name=2. Lieldienas -holiday.lv-LV4.date=20150406 -holiday.lv-LV5.name=Darba svētki -holiday.lv-LV5.date=20150501 -holiday.lv-LV6.name=Latvijas Republikas Neatkarības atjaunošanas dienu -holiday.lv-LV6.date=20150505 -holiday.lv-LV7.name=Jāņi -holiday.lv-LV7.date=20150624 -holiday.lv-LV8.name=Latvijas Republikas proklamēšanas diena -holiday.lv-LV8.date=20151118 -holiday.lv-LV9.name=Ziemassvētku vakars -holiday.lv-LV9.date=20151224 -holiday.lv-LV10.name=Ziemassvētki -holiday.lv-LV10.date=20151225 -holiday.lv-LV11.name=2. Ziemassvētki -holiday.lv-LV11.date=20151226 -holiday.lv-LV12.name=Vecgada vakars -holiday.lv-LV12.date=20151231 -holiday.lv-LV13.name=Jaunais Gads -holiday.lv-LV13.date=20160101 -holiday.lv-LV14.name=Lielā Piektdiena -holiday.lv-LV14.date=20160325 -holiday.lv-LV15.name=Lieldienas -holiday.lv-LV15.date=20160327 -holiday.lv-LV16.name=2. Lieldienas -holiday.lv-LV16.date=20160327 -holiday.lv-LV17.name=Darba svētki -holiday.lv-LV17.date=20160501 -holiday.lv-LV18.name=Latvijas Republikas Neatkarības atjaunošanas dienu -holiday.lv-LV18.date=20160505 -holiday.lv-LV19.name=Jāņi -holiday.lv-LV19.date=20160624 -holiday.lv-LV20.name=Latvijas Republikas proklamēšanas diena -holiday.lv-LV20.date=20161118 -holiday.lv-LV21.name=Ziemassvētku vakars -holiday.lv-LV21.date=20161224 -holiday.lv-LV22.name=Ziemassvētki -holiday.lv-LV22.date=20161225 -holiday.lv-LV23.name=2. Ziemassvētki -holiday.lv-LV23.date=20161226 -holiday.lv-LV24.name=Vecgada vakars -holiday.lv-LV24.date=20161231 diff --git a/doc/rc/holidays.nb-NO.rc b/doc/rc/holidays.nb-NO.rc index fb0e2ae7c..ad07b00eb 100644 --- a/doc/rc/holidays.nb-NO.rc +++ b/doc/rc/holidays.nb-NO.rc @@ -1,9 +1,9 @@ ############################################################################### # International Holiday Data provided by Holidata.net -# http://holidata.net/nb-NO/2015.json -# http://holidata.net/nb-NO/2016.json +# https://holidata.net/nb-NO/2020.json +# https://holidata.net/nb-NO/2021.json # -# Copyright 2006 - 2016, Paul Beckingham, Federico Hernandez. +# Copyright 2006 - 2020, 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 @@ -23,75 +23,75 @@ # 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 +# https://www.opensource.org/licenses/mit-license.php # ############################################################################### holiday.nb-NO1.name=Nyttårsdag -holiday.nb-NO1.date=20150101 +holiday.nb-NO1.date=20200101 holiday.nb-NO2.name=Fastelavn -holiday.nb-NO2.date=20150215 +holiday.nb-NO2.date=20200223 holiday.nb-NO3.name=Palmesøndag -holiday.nb-NO3.date=20150329 +holiday.nb-NO3.date=20200405 holiday.nb-NO4.name=Skjærtorsdag -holiday.nb-NO4.date=20150402 +holiday.nb-NO4.date=20200409 holiday.nb-NO5.name=Langfredag -holiday.nb-NO5.date=20150403 +holiday.nb-NO5.date=20200410 holiday.nb-NO6.name=Påskedag -holiday.nb-NO6.date=20150405 +holiday.nb-NO6.date=20200412 holiday.nb-NO7.name=Påskedag -holiday.nb-NO7.date=20150406 +holiday.nb-NO7.date=20200413 holiday.nb-NO8.name=Offentlig Høytidsdag -holiday.nb-NO8.date=20150501 +holiday.nb-NO8.date=20200501 holiday.nb-NO9.name=Frigjøringsdag 1945 -holiday.nb-NO9.date=20150508 +holiday.nb-NO9.date=20200508 holiday.nb-NO10.name=Grunnlovsdag -holiday.nb-NO10.date=20150517 +holiday.nb-NO10.date=20200517 holiday.nb-NO11.name=Kristi Himmelfartsdag -holiday.nb-NO11.date=20150514 +holiday.nb-NO11.date=20200521 holiday.nb-NO12.name=Pinsedag -holiday.nb-NO12.date=20150524 +holiday.nb-NO12.date=20200531 holiday.nb-NO13.name=Pinsedag -holiday.nb-NO13.date=20150525 +holiday.nb-NO13.date=20200601 holiday.nb-NO14.name=Julaften -holiday.nb-NO14.date=20151224 +holiday.nb-NO14.date=20201224 holiday.nb-NO15.name=Juledag -holiday.nb-NO15.date=20151225 +holiday.nb-NO15.date=20201225 holiday.nb-NO16.name=Juledag -holiday.nb-NO16.date=20151226 +holiday.nb-NO16.date=20201226 holiday.nb-NO17.name=Nyttårsaften -holiday.nb-NO17.date=20151231 +holiday.nb-NO17.date=20201231 holiday.nb-NO18.name=Nyttårsdag -holiday.nb-NO18.date=20160101 +holiday.nb-NO18.date=20210101 holiday.nb-NO19.name=Fastelavn -holiday.nb-NO19.date=20160207 +holiday.nb-NO19.date=20210214 holiday.nb-NO20.name=Palmesøndag -holiday.nb-NO20.date=20160320 +holiday.nb-NO20.date=20210328 holiday.nb-NO21.name=Skjærtorsdag -holiday.nb-NO21.date=20160324 +holiday.nb-NO21.date=20210401 holiday.nb-NO22.name=Langfredag -holiday.nb-NO22.date=20160325 +holiday.nb-NO22.date=20210402 holiday.nb-NO23.name=Påskedag -holiday.nb-NO23.date=20160327 +holiday.nb-NO23.date=20210404 holiday.nb-NO24.name=Påskedag -holiday.nb-NO24.date=20160328 +holiday.nb-NO24.date=20210405 holiday.nb-NO25.name=Offentlig Høytidsdag -holiday.nb-NO25.date=20160501 +holiday.nb-NO25.date=20210501 holiday.nb-NO26.name=Frigjøringsdag 1945 -holiday.nb-NO26.date=20160508 -holiday.nb-NO27.name=Grunnlovsdag -holiday.nb-NO27.date=20160517 -holiday.nb-NO28.name=Kristi Himmelfartsdag -holiday.nb-NO28.date=20160505 +holiday.nb-NO26.date=20210508 +holiday.nb-NO27.name=Kristi Himmelfartsdag +holiday.nb-NO27.date=20210513 +holiday.nb-NO28.name=Grunnlovsdag +holiday.nb-NO28.date=20210517 holiday.nb-NO29.name=Pinsedag -holiday.nb-NO29.date=20160515 +holiday.nb-NO29.date=20210523 holiday.nb-NO30.name=Pinsedag -holiday.nb-NO30.date=20160516 +holiday.nb-NO30.date=20210524 holiday.nb-NO31.name=Julaften -holiday.nb-NO31.date=20161224 +holiday.nb-NO31.date=20211224 holiday.nb-NO32.name=Juledag -holiday.nb-NO32.date=20161225 +holiday.nb-NO32.date=20211225 holiday.nb-NO33.name=Juledag -holiday.nb-NO33.date=20161226 +holiday.nb-NO33.date=20211226 holiday.nb-NO34.name=Nyttårsaften -holiday.nb-NO34.date=20161231 +holiday.nb-NO34.date=20211231 diff --git a/doc/rc/holidays.nb-SJ.rc b/doc/rc/holidays.nb-SJ.rc deleted file mode 100644 index d3845fad6..000000000 --- a/doc/rc/holidays.nb-SJ.rc +++ /dev/null @@ -1,97 +0,0 @@ -############################################################################### -# International Holiday Data provided by Holidata.net -# http://holidata.net/nb-SJ/2015.json -# http://holidata.net/nb-SJ/2016.json -# -# Copyright 2006 - 2016, 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 -# -############################################################################### - -holiday.nb-SJ1.name=Nyttårsdag -holiday.nb-SJ1.date=20150101 -holiday.nb-SJ2.name=Fastelavn -holiday.nb-SJ2.date=20150215 -holiday.nb-SJ3.name=Palmesøndag -holiday.nb-SJ3.date=20150329 -holiday.nb-SJ4.name=Skjærtorsdag -holiday.nb-SJ4.date=20150402 -holiday.nb-SJ5.name=Langfredag -holiday.nb-SJ5.date=20150403 -holiday.nb-SJ6.name=Påskedag -holiday.nb-SJ6.date=20150405 -holiday.nb-SJ7.name=Påskedag -holiday.nb-SJ7.date=20150406 -holiday.nb-SJ8.name=Offentlig Høytidsdag -holiday.nb-SJ8.date=20150501 -holiday.nb-SJ9.name=Frigjøringsdag 1945 -holiday.nb-SJ9.date=20150508 -holiday.nb-SJ10.name=Grunnlovsdag -holiday.nb-SJ10.date=20150517 -holiday.nb-SJ11.name=Kristi Himmelfartsdag -holiday.nb-SJ11.date=20150514 -holiday.nb-SJ12.name=Pinsedag -holiday.nb-SJ12.date=20150524 -holiday.nb-SJ13.name=Pinsedag -holiday.nb-SJ13.date=20150525 -holiday.nb-SJ14.name=Julaften -holiday.nb-SJ14.date=20151224 -holiday.nb-SJ15.name=Juledag -holiday.nb-SJ15.date=20151225 -holiday.nb-SJ16.name=Juledag -holiday.nb-SJ16.date=20151226 -holiday.nb-SJ17.name=Nyttårsaften -holiday.nb-SJ17.date=20151231 -holiday.nb-SJ18.name=Nyttårsdag -holiday.nb-SJ18.date=20160101 -holiday.nb-SJ19.name=Fastelavn -holiday.nb-SJ19.date=20160207 -holiday.nb-SJ20.name=Palmesøndag -holiday.nb-SJ20.date=20160320 -holiday.nb-SJ21.name=Skjærtorsdag -holiday.nb-SJ21.date=20160324 -holiday.nb-SJ22.name=Langfredag -holiday.nb-SJ22.date=20160325 -holiday.nb-SJ23.name=Påskedag -holiday.nb-SJ23.date=20160327 -holiday.nb-SJ24.name=Påskedag -holiday.nb-SJ24.date=20160328 -holiday.nb-SJ25.name=Offentlig Høytidsdag -holiday.nb-SJ25.date=20160501 -holiday.nb-SJ26.name=Frigjøringsdag 1945 -holiday.nb-SJ26.date=20160508 -holiday.nb-SJ27.name=Grunnlovsdag -holiday.nb-SJ27.date=20160517 -holiday.nb-SJ28.name=Kristi Himmelfartsdag -holiday.nb-SJ28.date=20160505 -holiday.nb-SJ29.name=Pinsedag -holiday.nb-SJ29.date=20160515 -holiday.nb-SJ30.name=Pinsedag -holiday.nb-SJ30.date=20160516 -holiday.nb-SJ31.name=Julaften -holiday.nb-SJ31.date=20161224 -holiday.nb-SJ32.name=Juledag -holiday.nb-SJ32.date=20161225 -holiday.nb-SJ33.name=Juledag -holiday.nb-SJ33.date=20161226 -holiday.nb-SJ34.name=Nyttårsaften -holiday.nb-SJ34.date=20161231 diff --git a/doc/rc/holidays.nl-BE.rc b/doc/rc/holidays.nl-BE.rc index 868c38507..a96e086f1 100644 --- a/doc/rc/holidays.nl-BE.rc +++ b/doc/rc/holidays.nl-BE.rc @@ -1,9 +1,9 @@ ############################################################################### # International Holiday Data provided by Holidata.net -# http://holidata.net/nl-BE/2015.json -# http://holidata.net/nl-BE/2016.json +# https://holidata.net/nl-BE/2020.json +# https://holidata.net/nl-BE/2021.json # -# Copyright 2006 - 2016, Paul Beckingham, Federico Hernandez. +# Copyright 2006 - 2020, 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 @@ -23,55 +23,55 @@ # 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 +# https://www.opensource.org/licenses/mit-license.php # ############################################################################### holiday.nl-BE1.name=Nieuwjaar -holiday.nl-BE1.date=20150101 +holiday.nl-BE1.date=20200101 holiday.nl-BE2.name=Pasen -holiday.nl-BE2.date=20150405 +holiday.nl-BE2.date=20200412 holiday.nl-BE3.name=Paasmaandag -holiday.nl-BE3.date=20150406 +holiday.nl-BE3.date=20200413 holiday.nl-BE4.name=Dag van de arbeid -holiday.nl-BE4.date=20150501 +holiday.nl-BE4.date=20200501 holiday.nl-BE5.name=Onze Lieve Heer hemelvaart -holiday.nl-BE5.date=20150514 +holiday.nl-BE5.date=20200521 holiday.nl-BE6.name=Pinksteren -holiday.nl-BE6.date=20150524 +holiday.nl-BE6.date=20200531 holiday.nl-BE7.name=Pinkstermaandag -holiday.nl-BE7.date=20150525 +holiday.nl-BE7.date=20200601 holiday.nl-BE8.name=Nationale feestdag -holiday.nl-BE8.date=20150721 +holiday.nl-BE8.date=20200721 holiday.nl-BE9.name=Onze Lieve Vrouw hemelvaart -holiday.nl-BE9.date=20150815 +holiday.nl-BE9.date=20200815 holiday.nl-BE10.name=Allerheiligen -holiday.nl-BE10.date=20151101 +holiday.nl-BE10.date=20201101 holiday.nl-BE11.name=Wapenstilstand -holiday.nl-BE11.date=20151111 +holiday.nl-BE11.date=20201111 holiday.nl-BE12.name=Kerstmis -holiday.nl-BE12.date=20151225 +holiday.nl-BE12.date=20201225 holiday.nl-BE13.name=Nieuwjaar -holiday.nl-BE13.date=20160101 +holiday.nl-BE13.date=20210101 holiday.nl-BE14.name=Pasen -holiday.nl-BE14.date=20160327 +holiday.nl-BE14.date=20210404 holiday.nl-BE15.name=Paasmaandag -holiday.nl-BE15.date=20160328 +holiday.nl-BE15.date=20210405 holiday.nl-BE16.name=Dag van de arbeid -holiday.nl-BE16.date=20160501 +holiday.nl-BE16.date=20210501 holiday.nl-BE17.name=Onze Lieve Heer hemelvaart -holiday.nl-BE17.date=20160505 +holiday.nl-BE17.date=20210513 holiday.nl-BE18.name=Pinksteren -holiday.nl-BE18.date=20160515 +holiday.nl-BE18.date=20210523 holiday.nl-BE19.name=Pinkstermaandag -holiday.nl-BE19.date=20160516 +holiday.nl-BE19.date=20210524 holiday.nl-BE20.name=Nationale feestdag -holiday.nl-BE20.date=20160721 +holiday.nl-BE20.date=20210721 holiday.nl-BE21.name=Onze Lieve Vrouw hemelvaart -holiday.nl-BE21.date=20160815 +holiday.nl-BE21.date=20210815 holiday.nl-BE22.name=Allerheiligen -holiday.nl-BE22.date=20161101 +holiday.nl-BE22.date=20211101 holiday.nl-BE23.name=Wapenstilstand -holiday.nl-BE23.date=20161111 +holiday.nl-BE23.date=20211111 holiday.nl-BE24.name=Kerstmis -holiday.nl-BE24.date=20161225 +holiday.nl-BE24.date=20211225 diff --git a/doc/rc/holidays.nl-NL.rc b/doc/rc/holidays.nl-NL.rc index 2af6bd14a..8c324df79 100644 --- a/doc/rc/holidays.nl-NL.rc +++ b/doc/rc/holidays.nl-NL.rc @@ -1,9 +1,9 @@ ############################################################################### # International Holiday Data provided by Holidata.net -# http://holidata.net/nl-NL/2015.json -# http://holidata.net/nl-NL/2016.json +# https://holidata.net/nl-NL/2020.json +# https://holidata.net/nl-NL/2021.json # -# Copyright 2006 - 2016, Paul Beckingham, Federico Hernandez. +# Copyright 2006 - 2020, 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 @@ -23,59 +23,63 @@ # 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 +# https://www.opensource.org/licenses/mit-license.php # ############################################################################### -holiday.nl-NL1.name=Nieuwjaar -holiday.nl-NL1.date=20150101 +holiday.nl-NL1.name=Nieuwjaarsdag +holiday.nl-NL1.date=20200101 holiday.nl-NL2.name=Goede Vrijdag -holiday.nl-NL2.date=20150403 -holiday.nl-NL3.name=Pasen -holiday.nl-NL3.date=20150405 -holiday.nl-NL4.name=Tweede Pasdag -holiday.nl-NL4.date=20150406 -holiday.nl-NL5.name=Koninginnedag -holiday.nl-NL5.date=20150427 +holiday.nl-NL2.date=20200410 +holiday.nl-NL3.name=Eerste Paasdag +holiday.nl-NL3.date=20200412 +holiday.nl-NL4.name=Tweede Paasdag +holiday.nl-NL4.date=20200413 +holiday.nl-NL5.name=Koningsdag +holiday.nl-NL5.date=20200427 holiday.nl-NL6.name=Dodenherdenking -holiday.nl-NL6.date=20150504 +holiday.nl-NL6.date=20200504 holiday.nl-NL7.name=Bevrijdingsdag -holiday.nl-NL7.date=20150505 +holiday.nl-NL7.date=20200505 holiday.nl-NL8.name=Hemelvaartsdag -holiday.nl-NL8.date=20150514 -holiday.nl-NL9.name=Pinksteren -holiday.nl-NL9.date=20150524 +holiday.nl-NL8.date=20200521 +holiday.nl-NL9.name=Eerste Pinksterdag +holiday.nl-NL9.date=20200531 holiday.nl-NL10.name=Tweede Pinksterdag -holiday.nl-NL10.date=20150525 +holiday.nl-NL10.date=20200601 holiday.nl-NL11.name=Sinterklaas -holiday.nl-NL11.date=20151205 -holiday.nl-NL12.name=Kerstmis -holiday.nl-NL12.date=20151225 -holiday.nl-NL13.name=Tweede Kerstdag -holiday.nl-NL13.date=20151226 -holiday.nl-NL14.name=Nieuwjaar -holiday.nl-NL14.date=20160101 -holiday.nl-NL15.name=Goede Vrijdag -holiday.nl-NL15.date=20160325 -holiday.nl-NL16.name=Pasen -holiday.nl-NL16.date=20160327 -holiday.nl-NL17.name=Tweede Pasdag -holiday.nl-NL17.date=20160328 -holiday.nl-NL18.name=Koninginnedag -holiday.nl-NL18.date=20160427 -holiday.nl-NL19.name=Dodenherdenking -holiday.nl-NL19.date=20160504 -holiday.nl-NL20.name=Bevrijdingsdag -holiday.nl-NL20.date=20160505 -holiday.nl-NL21.name=Hemelvaartsdag -holiday.nl-NL21.date=20160505 -holiday.nl-NL22.name=Pinksteren -holiday.nl-NL22.date=20160515 -holiday.nl-NL23.name=Tweede Pinksterdag -holiday.nl-NL23.date=20160516 -holiday.nl-NL24.name=Sinterklaas -holiday.nl-NL24.date=20161205 -holiday.nl-NL25.name=Kerstmis -holiday.nl-NL25.date=20161225 -holiday.nl-NL26.name=Tweede Kerstdag -holiday.nl-NL26.date=20161226 +holiday.nl-NL11.date=20201205 +holiday.nl-NL12.name=Koninkrijksdag +holiday.nl-NL12.date=20201215 +holiday.nl-NL13.name=Eerste Kerstdag +holiday.nl-NL13.date=20201225 +holiday.nl-NL14.name=Tweede Kerstdag +holiday.nl-NL14.date=20201226 +holiday.nl-NL15.name=Nieuwjaarsdag +holiday.nl-NL15.date=20210101 +holiday.nl-NL16.name=Goede Vrijdag +holiday.nl-NL16.date=20210402 +holiday.nl-NL17.name=Eerste Paasdag +holiday.nl-NL17.date=20210404 +holiday.nl-NL18.name=Tweede Paasdag +holiday.nl-NL18.date=20210405 +holiday.nl-NL19.name=Koningsdag +holiday.nl-NL19.date=20210427 +holiday.nl-NL20.name=Dodenherdenking +holiday.nl-NL20.date=20210504 +holiday.nl-NL21.name=Bevrijdingsdag +holiday.nl-NL21.date=20210505 +holiday.nl-NL22.name=Hemelvaartsdag +holiday.nl-NL22.date=20210513 +holiday.nl-NL23.name=Eerste Pinksterdag +holiday.nl-NL23.date=20210523 +holiday.nl-NL24.name=Tweede Pinksterdag +holiday.nl-NL24.date=20210524 +holiday.nl-NL25.name=Sinterklaas +holiday.nl-NL25.date=20211205 +holiday.nl-NL26.name=Koninkrijksdag +holiday.nl-NL26.date=20211215 +holiday.nl-NL27.name=Eerste Kerstdag +holiday.nl-NL27.date=20211225 +holiday.nl-NL28.name=Tweede Kerstdag +holiday.nl-NL28.date=20211226 diff --git a/doc/rc/holidays.pl-PL.rc b/doc/rc/holidays.pl-PL.rc index 5aba73caf..37099c3ec 100644 --- a/doc/rc/holidays.pl-PL.rc +++ b/doc/rc/holidays.pl-PL.rc @@ -1,9 +1,9 @@ ############################################################################### # International Holiday Data provided by Holidata.net -# http://holidata.net/pl-PL/2015.json -# http://holidata.net/pl-PL/2016.json +# https://holidata.net/pl-PL/2020.json +# https://holidata.net/pl-PL/2021.json # -# Copyright 2006 - 2016, Paul Beckingham, Federico Hernandez. +# Copyright 2006 - 2020, 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 @@ -23,63 +23,59 @@ # 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 +# https://www.opensource.org/licenses/mit-license.php # ############################################################################### holiday.pl-PL1.name=Nowy Rok -holiday.pl-PL1.date=20150101 +holiday.pl-PL1.date=20200101 holiday.pl-PL2.name=Trzech Króli -holiday.pl-PL2.date=20150106 +holiday.pl-PL2.date=20200106 holiday.pl-PL3.name=Wielkanoc -holiday.pl-PL3.date=20150405 +holiday.pl-PL3.date=20200412 holiday.pl-PL4.name=Poniedziałek Wielkanocny -holiday.pl-PL4.date=20150406 +holiday.pl-PL4.date=20200413 holiday.pl-PL5.name=Święto Pracy -holiday.pl-PL5.date=20150501 +holiday.pl-PL5.date=20200501 holiday.pl-PL6.name=Święto Konstytucji Trzeciego Maja -holiday.pl-PL6.date=20150503 +holiday.pl-PL6.date=20200503 holiday.pl-PL7.name=Zielone Świątki -holiday.pl-PL7.date=20150524 +holiday.pl-PL7.date=20200531 holiday.pl-PL8.name=Boże Ciało -holiday.pl-PL8.date=20150604 -holiday.pl-PL9.name=Święto Wojska Polskiego -holiday.pl-PL9.date=20150815 -holiday.pl-PL10.name=Wniebowzięcia NMP -holiday.pl-PL10.date=20150815 -holiday.pl-PL11.name=Wszystkich Świętych -holiday.pl-PL11.date=20151101 -holiday.pl-PL12.name=Dzień Niepodległości -holiday.pl-PL12.date=20151111 -holiday.pl-PL13.name=Boże Narodzenie (pierwszy dzień) -holiday.pl-PL13.date=20151225 -holiday.pl-PL14.name=Boże Narodzenie (drugi dzień) -holiday.pl-PL14.date=20151226 -holiday.pl-PL15.name=Nowy Rok -holiday.pl-PL15.date=20160101 -holiday.pl-PL16.name=Trzech Króli -holiday.pl-PL16.date=20160106 -holiday.pl-PL17.name=Wielkanoc -holiday.pl-PL17.date=20160327 -holiday.pl-PL18.name=Poniedziałek Wielkanocny -holiday.pl-PL18.date=20160328 -holiday.pl-PL19.name=Święto Pracy -holiday.pl-PL19.date=20160501 -holiday.pl-PL20.name=Święto Konstytucji Trzeciego Maja -holiday.pl-PL20.date=20160503 -holiday.pl-PL21.name=Zielone Świątki -holiday.pl-PL21.date=20160515 -holiday.pl-PL22.name=Boże Ciało -holiday.pl-PL22.date=20160526 -holiday.pl-PL23.name=Święto Wojska Polskiego -holiday.pl-PL23.date=20160815 -holiday.pl-PL24.name=Wniebowzięcia NMP -holiday.pl-PL24.date=20160815 -holiday.pl-PL25.name=Wszystkich Świętych -holiday.pl-PL25.date=20161101 -holiday.pl-PL26.name=Dzień Niepodległości -holiday.pl-PL26.date=20161111 -holiday.pl-PL27.name=Boże Narodzenie (pierwszy dzień) -holiday.pl-PL27.date=20161225 -holiday.pl-PL28.name=Boże Narodzenie (drugi dzień) -holiday.pl-PL28.date=20161226 +holiday.pl-PL8.date=20200611 +holiday.pl-PL9.name=Wniebowzięcie Najświętszej Maryi Panny +holiday.pl-PL9.date=20200815 +holiday.pl-PL10.name=Wszystkich Świętych +holiday.pl-PL10.date=20201101 +holiday.pl-PL11.name=Narodowe Święto Niepodległości +holiday.pl-PL11.date=20201111 +holiday.pl-PL12.name=Boże Narodzenie (pierwszy dzień) +holiday.pl-PL12.date=20201225 +holiday.pl-PL13.name=Boże Narodzenie (drugi dzień) +holiday.pl-PL13.date=20201226 +holiday.pl-PL14.name=Nowy Rok +holiday.pl-PL14.date=20210101 +holiday.pl-PL15.name=Trzech Króli +holiday.pl-PL15.date=20210106 +holiday.pl-PL16.name=Wielkanoc +holiday.pl-PL16.date=20210404 +holiday.pl-PL17.name=Poniedziałek Wielkanocny +holiday.pl-PL17.date=20210405 +holiday.pl-PL18.name=Święto Pracy +holiday.pl-PL18.date=20210501 +holiday.pl-PL19.name=Święto Konstytucji Trzeciego Maja +holiday.pl-PL19.date=20210503 +holiday.pl-PL20.name=Zielone Świątki +holiday.pl-PL20.date=20210523 +holiday.pl-PL21.name=Boże Ciało +holiday.pl-PL21.date=20210603 +holiday.pl-PL22.name=Wniebowzięcie Najświętszej Maryi Panny +holiday.pl-PL22.date=20210815 +holiday.pl-PL23.name=Wszystkich Świętych +holiday.pl-PL23.date=20211101 +holiday.pl-PL24.name=Narodowe Święto Niepodległości +holiday.pl-PL24.date=20211111 +holiday.pl-PL25.name=Boże Narodzenie (pierwszy dzień) +holiday.pl-PL25.date=20211225 +holiday.pl-PL26.name=Boże Narodzenie (drugi dzień) +holiday.pl-PL26.date=20211226 diff --git a/doc/rc/holidays.pt-BR.rc b/doc/rc/holidays.pt-BR.rc deleted file mode 100644 index 515b7d426..000000000 --- a/doc/rc/holidays.pt-BR.rc +++ /dev/null @@ -1,81 +0,0 @@ -############################################################################### -# International Holiday Data provided by Holidata.net -# http://holidata.net/pt-BR/2015.json -# http://holidata.net/pt-BR/2016.json -# -# Copyright 2006 - 2016, 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 -# -############################################################################### - -holiday.pt-BR1.name=Confraternização Universal -holiday.pt-BR1.date=20150101 -holiday.pt-BR2.name=Carnaval -holiday.pt-BR2.date=20150216 -holiday.pt-BR3.name=Carnaval -holiday.pt-BR3.date=20150217 -holiday.pt-BR4.name=Sexta-feira Santa -holiday.pt-BR4.date=20150403 -holiday.pt-BR5.name=Páscoa -holiday.pt-BR5.date=20150405 -holiday.pt-BR6.name=Tiradentes -holiday.pt-BR6.date=20150421 -holiday.pt-BR7.name=Dia do Trabalho -holiday.pt-BR7.date=20150501 -holiday.pt-BR8.name=Corpus Christi -holiday.pt-BR8.date=20150604 -holiday.pt-BR9.name=Independência do Brasil -holiday.pt-BR9.date=20150907 -holiday.pt-BR10.name=Nossa Senhora Aparecida -holiday.pt-BR10.date=20151012 -holiday.pt-BR11.name=Finados -holiday.pt-BR11.date=20151102 -holiday.pt-BR12.name=Proclamação da República -holiday.pt-BR12.date=20151115 -holiday.pt-BR13.name=Natal -holiday.pt-BR13.date=20151225 -holiday.pt-BR14.name=Confraternização Universal -holiday.pt-BR14.date=20160101 -holiday.pt-BR15.name=Carnaval -holiday.pt-BR15.date=20160208 -holiday.pt-BR16.name=Carnaval -holiday.pt-BR16.date=20160209 -holiday.pt-BR17.name=Sexta-feira Santa -holiday.pt-BR17.date=20160325 -holiday.pt-BR18.name=Páscoa -holiday.pt-BR18.date=20160327 -holiday.pt-BR19.name=Tiradentes -holiday.pt-BR19.date=20160421 -holiday.pt-BR20.name=Dia do Trabalho -holiday.pt-BR20.date=20160501 -holiday.pt-BR21.name=Corpus Christi -holiday.pt-BR21.date=20160526 -holiday.pt-BR22.name=Independência do Brasil -holiday.pt-BR22.date=20160907 -holiday.pt-BR23.name=Nossa Senhora Aparecida -holiday.pt-BR23.date=20161012 -holiday.pt-BR24.name=Finados -holiday.pt-BR24.date=20161102 -holiday.pt-BR25.name=Proclamação da República -holiday.pt-BR25.date=20161115 -holiday.pt-BR26.name=Natal -holiday.pt-BR26.date=20161225 diff --git a/doc/rc/holidays.pt-PT.rc b/doc/rc/holidays.pt-PT.rc index 531d0b8e9..da8ce981c 100644 --- a/doc/rc/holidays.pt-PT.rc +++ b/doc/rc/holidays.pt-PT.rc @@ -1,9 +1,9 @@ ############################################################################### # International Holiday Data provided by Holidata.net -# http://holidata.net/pt-PT/2015.json -# http://holidata.net/pt-PT/2016.json +# https://holidata.net/pt-PT/2020.json +# https://holidata.net/pt-PT/2021.json # -# Copyright 2006 - 2016, Paul Beckingham, Federico Hernandez. +# Copyright 2006 - 2020, 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 @@ -23,63 +23,63 @@ # 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 +# https://www.opensource.org/licenses/mit-license.php # ############################################################################### holiday.pt-PT1.name=Ano Novo -holiday.pt-PT1.date=20150101 +holiday.pt-PT1.date=20200101 holiday.pt-PT2.name=Carnaval -holiday.pt-PT2.date=20150217 +holiday.pt-PT2.date=20200225 holiday.pt-PT3.name=Sexta-feira Santa -holiday.pt-PT3.date=20150403 +holiday.pt-PT3.date=20200410 holiday.pt-PT4.name=Páscoa -holiday.pt-PT4.date=20150405 +holiday.pt-PT4.date=20200412 holiday.pt-PT5.name=Dia da Liberdade -holiday.pt-PT5.date=20150425 +holiday.pt-PT5.date=20200425 holiday.pt-PT6.name=Dia do Trabalhador -holiday.pt-PT6.date=20150501 -holiday.pt-PT7.name=Corpo de Deus -holiday.pt-PT7.date=20150604 -holiday.pt-PT8.name=Dia de Portugal -holiday.pt-PT8.date=20150610 +holiday.pt-PT6.date=20200501 +holiday.pt-PT7.name=Dia de Portugal +holiday.pt-PT7.date=20200610 +holiday.pt-PT8.name=Corpo de Deus +holiday.pt-PT8.date=20200611 holiday.pt-PT9.name=Assunção de Nossa Senhora -holiday.pt-PT9.date=20150815 +holiday.pt-PT9.date=20200815 holiday.pt-PT10.name=Implantação da República -holiday.pt-PT10.date=20151005 -holiday.pt-PT11.name=Todos os Santos -holiday.pt-PT11.date=20151101 +holiday.pt-PT10.date=20201005 +holiday.pt-PT11.name=Dia de Todos os Santos +holiday.pt-PT11.date=20201101 holiday.pt-PT12.name=Restauração da Independência -holiday.pt-PT12.date=20151201 +holiday.pt-PT12.date=20201201 holiday.pt-PT13.name=Imaculada Conceição -holiday.pt-PT13.date=20151208 +holiday.pt-PT13.date=20201208 holiday.pt-PT14.name=Natal -holiday.pt-PT14.date=20151225 +holiday.pt-PT14.date=20201225 holiday.pt-PT15.name=Ano Novo -holiday.pt-PT15.date=20160101 +holiday.pt-PT15.date=20210101 holiday.pt-PT16.name=Carnaval -holiday.pt-PT16.date=20160209 +holiday.pt-PT16.date=20210216 holiday.pt-PT17.name=Sexta-feira Santa -holiday.pt-PT17.date=20160325 +holiday.pt-PT17.date=20210402 holiday.pt-PT18.name=Páscoa -holiday.pt-PT18.date=20160327 +holiday.pt-PT18.date=20210404 holiday.pt-PT19.name=Dia da Liberdade -holiday.pt-PT19.date=20160425 +holiday.pt-PT19.date=20210425 holiday.pt-PT20.name=Dia do Trabalhador -holiday.pt-PT20.date=20160501 +holiday.pt-PT20.date=20210501 holiday.pt-PT21.name=Corpo de Deus -holiday.pt-PT21.date=20160526 +holiday.pt-PT21.date=20210603 holiday.pt-PT22.name=Dia de Portugal -holiday.pt-PT22.date=20160610 +holiday.pt-PT22.date=20210610 holiday.pt-PT23.name=Assunção de Nossa Senhora -holiday.pt-PT23.date=20160815 +holiday.pt-PT23.date=20210815 holiday.pt-PT24.name=Implantação da República -holiday.pt-PT24.date=20161005 -holiday.pt-PT25.name=Todos os Santos -holiday.pt-PT25.date=20161101 +holiday.pt-PT24.date=20211005 +holiday.pt-PT25.name=Dia de Todos os Santos +holiday.pt-PT25.date=20211101 holiday.pt-PT26.name=Restauração da Independência -holiday.pt-PT26.date=20161201 +holiday.pt-PT26.date=20211201 holiday.pt-PT27.name=Imaculada Conceição -holiday.pt-PT27.date=20161208 +holiday.pt-PT27.date=20211208 holiday.pt-PT28.name=Natal -holiday.pt-PT28.date=20161225 +holiday.pt-PT28.date=20211225 diff --git a/doc/rc/holidays.ru-RU.rc b/doc/rc/holidays.ru-RU.rc index 2b8455d51..df47a00b7 100644 --- a/doc/rc/holidays.ru-RU.rc +++ b/doc/rc/holidays.ru-RU.rc @@ -1,9 +1,9 @@ ############################################################################### # International Holiday Data provided by Holidata.net -# http://holidata.net/ru-RU/2015.json -# http://holidata.net/ru-RU/2016.json +# https://holidata.net/ru-RU/2020.json +# https://holidata.net/ru-RU/2021.json # -# Copyright 2006 - 2016, Paul Beckingham, Federico Hernandez. +# Copyright 2006 - 2020, 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 @@ -23,43 +23,43 @@ # 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 +# https://www.opensource.org/licenses/mit-license.php # ############################################################################### holiday.ru-RU1.name=Новый Год -holiday.ru-RU1.date=20150101 +holiday.ru-RU1.date=20200101 holiday.ru-RU2.name=Рождество Христово -holiday.ru-RU2.date=20150107 +holiday.ru-RU2.date=20200107 holiday.ru-RU3.name=День защитника Отечества -holiday.ru-RU3.date=20150223 +holiday.ru-RU3.date=20200223 holiday.ru-RU4.name=Международный женский день -holiday.ru-RU4.date=20150308 +holiday.ru-RU4.date=20200308 holiday.ru-RU5.name=Пасха -holiday.ru-RU5.date=20150412 +holiday.ru-RU5.date=20200419 holiday.ru-RU6.name=Праздник весны и труда -holiday.ru-RU6.date=20150501 +holiday.ru-RU6.date=20200501 holiday.ru-RU7.name=День Победы -holiday.ru-RU7.date=20150509 +holiday.ru-RU7.date=20200509 holiday.ru-RU8.name=День России -holiday.ru-RU8.date=20150612 +holiday.ru-RU8.date=20200612 holiday.ru-RU9.name=День народного единства -holiday.ru-RU9.date=20151104 +holiday.ru-RU9.date=20201104 holiday.ru-RU10.name=Новый Год -holiday.ru-RU10.date=20160101 +holiday.ru-RU10.date=20210101 holiday.ru-RU11.name=Рождество Христово -holiday.ru-RU11.date=20160107 +holiday.ru-RU11.date=20210107 holiday.ru-RU12.name=День защитника Отечества -holiday.ru-RU12.date=20160223 +holiday.ru-RU12.date=20210223 holiday.ru-RU13.name=Международный женский день -holiday.ru-RU13.date=20160308 -holiday.ru-RU14.name=Пасха -holiday.ru-RU14.date=20160501 -holiday.ru-RU15.name=Праздник весны и труда -holiday.ru-RU15.date=20160501 +holiday.ru-RU13.date=20210308 +holiday.ru-RU14.name=Праздник весны и труда +holiday.ru-RU14.date=20210501 +holiday.ru-RU15.name=Пасха +holiday.ru-RU15.date=20210502 holiday.ru-RU16.name=День Победы -holiday.ru-RU16.date=20160509 +holiday.ru-RU16.date=20210509 holiday.ru-RU17.name=День России -holiday.ru-RU17.date=20160612 +holiday.ru-RU17.date=20210612 holiday.ru-RU18.name=День народного единства -holiday.ru-RU18.date=20161104 +holiday.ru-RU18.date=20211104 diff --git a/doc/rc/holidays.sv-SE.rc b/doc/rc/holidays.sv-SE.rc index cbbb9bc9c..0c5ea8a2a 100644 --- a/doc/rc/holidays.sv-SE.rc +++ b/doc/rc/holidays.sv-SE.rc @@ -1,9 +1,9 @@ ############################################################################### # International Holiday Data provided by Holidata.net -# http://holidata.net/sv-SE/2015.json -# http://holidata.net/sv-SE/2016.json +# https://holidata.net/sv-SE/2020.json +# https://holidata.net/sv-SE/2021.json # -# Copyright 2006 - 2016, Paul Beckingham, Federico Hernandez. +# Copyright 2006 - 2020, 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 @@ -23,75 +23,71 @@ # 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 +# https://www.opensource.org/licenses/mit-license.php # ############################################################################### holiday.sv-SE1.name=Nyårsdagen -holiday.sv-SE1.date=20150101 +holiday.sv-SE1.date=20200101 holiday.sv-SE2.name=Trettondedag jul -holiday.sv-SE2.date=20150106 +holiday.sv-SE2.date=20200106 holiday.sv-SE3.name=Långfredagen -holiday.sv-SE3.date=20150403 +holiday.sv-SE3.date=20200410 holiday.sv-SE4.name=Påskdagen -holiday.sv-SE4.date=20150405 +holiday.sv-SE4.date=20200412 holiday.sv-SE5.name=Annandag påsk -holiday.sv-SE5.date=20150406 -holiday.sv-SE6.name=Valborgmässoafton -holiday.sv-SE6.date=20150430 -holiday.sv-SE7.name=Första maj -holiday.sv-SE7.date=20150501 -holiday.sv-SE8.name=Kristi Himmelsfärdsdag -holiday.sv-SE8.date=20150514 -holiday.sv-SE9.name=Pingstdagen -holiday.sv-SE9.date=20150524 -holiday.sv-SE10.name=Nationaldagen -holiday.sv-SE10.date=20150606 -holiday.sv-SE11.name=Midsommarafton -holiday.sv-SE11.date=20150619 -holiday.sv-SE12.name=Midsommardagen -holiday.sv-SE12.date=20150620 -holiday.sv-SE13.name=Alla Helgons Dag -holiday.sv-SE13.date=20151031 -holiday.sv-SE14.name=Julafton -holiday.sv-SE14.date=20151224 -holiday.sv-SE15.name=Juldagen -holiday.sv-SE15.date=20151225 -holiday.sv-SE16.name=Annandag jul -holiday.sv-SE16.date=20151226 -holiday.sv-SE17.name=Nyårsafton -holiday.sv-SE17.date=20151231 -holiday.sv-SE18.name=Nyårsdagen -holiday.sv-SE18.date=20160101 -holiday.sv-SE19.name=Trettondedag jul -holiday.sv-SE19.date=20160106 -holiday.sv-SE20.name=Långfredagen -holiday.sv-SE20.date=20160325 -holiday.sv-SE21.name=Påskdagen -holiday.sv-SE21.date=20160327 -holiday.sv-SE22.name=Annandag påsk -holiday.sv-SE22.date=20160328 -holiday.sv-SE23.name=Valborgmässoafton -holiday.sv-SE23.date=20160430 -holiday.sv-SE24.name=Första maj -holiday.sv-SE24.date=20160501 -holiday.sv-SE25.name=Kristi Himmelsfärdsdag -holiday.sv-SE25.date=20160505 -holiday.sv-SE26.name=Pingstdagen -holiday.sv-SE26.date=20160515 -holiday.sv-SE27.name=Nationaldagen -holiday.sv-SE27.date=20160606 -holiday.sv-SE28.name=Midsommarafton -holiday.sv-SE28.date=20160624 -holiday.sv-SE29.name=Midsommardagen -holiday.sv-SE29.date=20160625 -holiday.sv-SE30.name=Alla Helgons Dag -holiday.sv-SE30.date=20161105 -holiday.sv-SE31.name=Julafton -holiday.sv-SE31.date=20161224 -holiday.sv-SE32.name=Juldagen -holiday.sv-SE32.date=20161225 -holiday.sv-SE33.name=Annandag jul -holiday.sv-SE33.date=20161226 -holiday.sv-SE34.name=Nyårsafton -holiday.sv-SE34.date=20161231 +holiday.sv-SE5.date=20200413 +holiday.sv-SE6.name=Första maj +holiday.sv-SE6.date=20200501 +holiday.sv-SE7.name=Kristi himmelsfärdsdag +holiday.sv-SE7.date=20200521 +holiday.sv-SE8.name=Pingstdagen +holiday.sv-SE8.date=20200531 +holiday.sv-SE9.name=Nationaldagen +holiday.sv-SE9.date=20200606 +holiday.sv-SE10.name=Midsommarafton +holiday.sv-SE10.date=20200619 +holiday.sv-SE11.name=Midsommardagen +holiday.sv-SE11.date=20200620 +holiday.sv-SE12.name=Alla helgons dag +holiday.sv-SE12.date=20201031 +holiday.sv-SE13.name=Julafton +holiday.sv-SE13.date=20201224 +holiday.sv-SE14.name=Juldagen +holiday.sv-SE14.date=20201225 +holiday.sv-SE15.name=Annandag jul +holiday.sv-SE15.date=20201226 +holiday.sv-SE16.name=Nyårsafton +holiday.sv-SE16.date=20201231 +holiday.sv-SE17.name=Nyårsdagen +holiday.sv-SE17.date=20210101 +holiday.sv-SE18.name=Trettondedag jul +holiday.sv-SE18.date=20210106 +holiday.sv-SE19.name=Långfredagen +holiday.sv-SE19.date=20210402 +holiday.sv-SE20.name=Påskdagen +holiday.sv-SE20.date=20210404 +holiday.sv-SE21.name=Annandag påsk +holiday.sv-SE21.date=20210405 +holiday.sv-SE22.name=Första maj +holiday.sv-SE22.date=20210501 +holiday.sv-SE23.name=Kristi himmelsfärdsdag +holiday.sv-SE23.date=20210513 +holiday.sv-SE24.name=Pingstdagen +holiday.sv-SE24.date=20210523 +holiday.sv-SE25.name=Nationaldagen +holiday.sv-SE25.date=20210606 +holiday.sv-SE26.name=Midsommarafton +holiday.sv-SE26.date=20210625 +holiday.sv-SE27.name=Midsommardagen +holiday.sv-SE27.date=20210626 +holiday.sv-SE28.name=Alla helgons dag +holiday.sv-SE28.date=20211106 +holiday.sv-SE29.name=Julafton +holiday.sv-SE29.date=20211224 +holiday.sv-SE30.name=Juldagen +holiday.sv-SE30.date=20211225 +holiday.sv-SE31.name=Annandag jul +holiday.sv-SE31.date=20211226 +holiday.sv-SE32.name=Nyårsafton +holiday.sv-SE32.date=20211231 diff --git a/doc/rc/holidays.tr-TR.rc b/doc/rc/holidays.tr-TR.rc index 453a5698e..1bcb56281 100644 --- a/doc/rc/holidays.tr-TR.rc +++ b/doc/rc/holidays.tr-TR.rc @@ -1,9 +1,9 @@ ############################################################################### # International Holiday Data provided by Holidata.net -# http://holidata.net/tr-TR/2015.json -# http://holidata.net/tr-TR/2016.json +# https://holidata.net/tr-TR/2020.json +# https://holidata.net/tr-TR/2021.json # -# Copyright 2006 - 2016, Paul Beckingham, Federico Hernandez. +# Copyright 2006 - 2020, 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 @@ -23,59 +23,63 @@ # 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 +# https://www.opensource.org/licenses/mit-license.php # ############################################################################### holiday.tr-TR1.name=Yılbaşı -holiday.tr-TR1.date=20150101 +holiday.tr-TR1.date=20200101 holiday.tr-TR2.name=Ulusal Egemenlik ve Çocuk Bayramı -holiday.tr-TR2.date=20150423 +holiday.tr-TR2.date=20200423 holiday.tr-TR3.name=Emek ve Dayanışma Günü -holiday.tr-TR3.date=20150501 -holiday.tr-TR4.name=Atatürk'ü Anma Gençlik ve Spor Bayramı -holiday.tr-TR4.date=20150519 -holiday.tr-TR5.name=Zafer Bayramı -holiday.tr-TR5.date=20150830 -holiday.tr-TR6.name=Cumhuriyet Bayramı -holiday.tr-TR6.date=20151029 -holiday.tr-TR7.name=Ramazan Bayramı 1 -holiday.tr-TR7.date=20150717 -holiday.tr-TR8.name=Ramazan Bayramı 2 -holiday.tr-TR8.date=20150718 -holiday.tr-TR9.name=Ramazan Bayramı 3 -holiday.tr-TR9.date=20150719 -holiday.tr-TR10.name=Kurban Bayramı 1 -holiday.tr-TR10.date=20150923 -holiday.tr-TR11.name=Kurban Bayramı 2 -holiday.tr-TR11.date=20150924 -holiday.tr-TR12.name=Kurban Bayramı 3 -holiday.tr-TR12.date=20150925 -holiday.tr-TR13.name=Kurban Bayramı 4 -holiday.tr-TR13.date=20150926 -holiday.tr-TR14.name=Yılbaşı -holiday.tr-TR14.date=20160101 -holiday.tr-TR15.name=Ulusal Egemenlik ve Çocuk Bayramı -holiday.tr-TR15.date=20160423 -holiday.tr-TR16.name=Emek ve Dayanışma Günü -holiday.tr-TR16.date=20160501 -holiday.tr-TR17.name=Atatürk'ü Anma Gençlik ve Spor Bayramı -holiday.tr-TR17.date=20160519 -holiday.tr-TR18.name=Zafer Bayramı -holiday.tr-TR18.date=20160830 -holiday.tr-TR19.name=Cumhuriyet Bayramı -holiday.tr-TR19.date=20161029 -holiday.tr-TR20.name=Ramazan Bayramı 1 -holiday.tr-TR20.date=20160705 -holiday.tr-TR21.name=Ramazan Bayramı 2 -holiday.tr-TR21.date=20160706 -holiday.tr-TR22.name=Ramazan Bayramı 3 -holiday.tr-TR22.date=20160707 -holiday.tr-TR23.name=Kurban Bayramı 1 -holiday.tr-TR23.date=20160912 -holiday.tr-TR24.name=Kurban Bayramı 2 -holiday.tr-TR24.date=20160913 -holiday.tr-TR25.name=Kurban Bayramı 3 -holiday.tr-TR25.date=20160914 -holiday.tr-TR26.name=Kurban Bayramı 4 -holiday.tr-TR26.date=20160915 +holiday.tr-TR3.date=20200501 +holiday.tr-TR4.name=Atatürk'ü Anma, Gençlik ve Spor Bayramı +holiday.tr-TR4.date=20200519 +holiday.tr-TR5.name=Ramazan Bayramı (1. Gün) +holiday.tr-TR5.date=20200524 +holiday.tr-TR6.name=Ramazan Bayramı (2. Gün) +holiday.tr-TR6.date=20200525 +holiday.tr-TR7.name=Ramazan Bayramı (3. Gün) +holiday.tr-TR7.date=20200526 +holiday.tr-TR8.name=Demokrasi ve Milli Birlik Günü +holiday.tr-TR8.date=20200715 +holiday.tr-TR9.name=Kurban Bayramı (1. Gün) +holiday.tr-TR9.date=20200731 +holiday.tr-TR10.name=Kurban Bayramı (2. Gün) +holiday.tr-TR10.date=20200801 +holiday.tr-TR11.name=Kurban Bayramı (3. Gün) +holiday.tr-TR11.date=20200802 +holiday.tr-TR12.name=Kurban Bayramı (4. Gün) +holiday.tr-TR12.date=20200803 +holiday.tr-TR13.name=Zafer Bayramı +holiday.tr-TR13.date=20200830 +holiday.tr-TR14.name=Cumhuriyet Bayramı +holiday.tr-TR14.date=20201029 +holiday.tr-TR15.name=Yılbaşı +holiday.tr-TR15.date=20210101 +holiday.tr-TR16.name=Ulusal Egemenlik ve Çocuk Bayramı +holiday.tr-TR16.date=20210423 +holiday.tr-TR17.name=Emek ve Dayanışma Günü +holiday.tr-TR17.date=20210501 +holiday.tr-TR18.name=Ramazan Bayramı (1. Gün) +holiday.tr-TR18.date=20210513 +holiday.tr-TR19.name=Ramazan Bayramı (2. Gün) +holiday.tr-TR19.date=20210514 +holiday.tr-TR20.name=Ramazan Bayramı (3. Gün) +holiday.tr-TR20.date=20210515 +holiday.tr-TR21.name=Atatürk'ü Anma, Gençlik ve Spor Bayramı +holiday.tr-TR21.date=20210519 +holiday.tr-TR22.name=Demokrasi ve Milli Birlik Günü +holiday.tr-TR22.date=20210715 +holiday.tr-TR23.name=Kurban Bayramı (1. Gün) +holiday.tr-TR23.date=20210720 +holiday.tr-TR24.name=Kurban Bayramı (2. Gün) +holiday.tr-TR24.date=20210721 +holiday.tr-TR25.name=Kurban Bayramı (3. Gün) +holiday.tr-TR25.date=20210722 +holiday.tr-TR26.name=Kurban Bayramı (4. Gün) +holiday.tr-TR26.date=20210723 +holiday.tr-TR27.name=Zafer Bayramı +holiday.tr-TR27.date=20210830 +holiday.tr-TR28.name=Cumhuriyet Bayramı +holiday.tr-TR28.date=20211029 diff --git a/doc/rc/light-16.theme b/doc/rc/light-16.theme index 7e1ebaf52..c582c4802 100644 --- a/doc/rc/light-16.theme +++ b/doc/rc/light-16.theme @@ -1,6 +1,6 @@ ############################################################################### # -# Copyright 2006 - 2016, Paul Beckingham, Federico Hernandez. +# Copyright 2006 - 2020, 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 @@ -20,7 +20,7 @@ # 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 +# https://www.opensource.org/licenses/mit-license.php # ############################################################################### diff --git a/doc/rc/light-256.theme b/doc/rc/light-256.theme index 44d1384c5..7d2106e0f 100644 --- a/doc/rc/light-256.theme +++ b/doc/rc/light-256.theme @@ -1,6 +1,6 @@ ############################################################################### # -# Copyright 2006 - 2016, Paul Beckingham, Federico Hernandez. +# Copyright 2006 - 2020, 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 @@ -20,7 +20,7 @@ # 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 +# https://www.opensource.org/licenses/mit-license.php # ############################################################################### diff --git a/doc/rc/no-color.theme b/doc/rc/no-color.theme index c72b4f94e..635e6e799 100644 --- a/doc/rc/no-color.theme +++ b/doc/rc/no-color.theme @@ -1,6 +1,6 @@ ############################################################################### # -# Copyright 2006 - 2016, Paul Beckingham, Federico Hernandez. +# Copyright 2006 - 2020, 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 @@ -20,7 +20,7 @@ # 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 +# https://www.opensource.org/licenses/mit-license.php # ############################################################################### diff --git a/doc/rc/solarized-dark-256.theme b/doc/rc/solarized-dark-256.theme index 264c66584..31f1d36f6 100644 --- a/doc/rc/solarized-dark-256.theme +++ b/doc/rc/solarized-dark-256.theme @@ -1,6 +1,6 @@ ################################################################################ # -# Copyright 2006 - 2016, Paul Beckingham, Federico Hernandez. +# Copyright 2006 - 2020, 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 @@ -20,7 +20,7 @@ # 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 +# https://www.opensource.org/licenses/mit-license.php # ############################################################################### diff --git a/doc/rc/solarized-light-256.theme b/doc/rc/solarized-light-256.theme index 2702103a1..44575f49a 100644 --- a/doc/rc/solarized-light-256.theme +++ b/doc/rc/solarized-light-256.theme @@ -1,6 +1,6 @@ ################################################################################ # -# Copyright 2006 - 2016, Paul Beckingham, Federico Hernandez. +# Copyright 2006 - 2020, 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 @@ -20,7 +20,7 @@ # 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 +# https://www.opensource.org/licenses/mit-license.php # ############################################################################### diff --git a/doc/ref/task-ref.pages b/doc/ref/task-ref.pages index 249c66b92..6607a8614 100644 Binary files a/doc/ref/task-ref.pages and b/doc/ref/task-ref.pages differ diff --git a/doc/ref/task-ref.pdf b/doc/ref/task-ref.pdf index 95152a966..ee3cab6d5 100644 Binary files a/doc/ref/task-ref.pdf and b/doc/ref/task-ref.pdf differ diff --git a/docker-compose.yml b/docker-compose.yml new file mode 100644 index 000000000..3ddc1f830 --- /dev/null +++ b/docker-compose.yml @@ -0,0 +1,82 @@ +version: '3' +services: + test-centos7: + build: + context: . + dockerfile: test/docker/centos7 + network_mode: "host" + security_opt: + - label=type:container_runtime_t + tty: true + test-fedora28: + build: + context: . + dockerfile: test/docker/fedora28 + network_mode: "host" + security_opt: + - label=type:container_runtime_t + tty: true + test-fedora29: + build: + context: . + dockerfile: test/docker/fedora29 + network_mode: "host" + security_opt: + - label=type:container_runtime_t + tty: true + test-ubuntu1604: + build: + context: . + dockerfile: test/docker/ubuntu1604 + network_mode: "host" + security_opt: + - label=type:container_runtime_t + tty: true + test-ubuntu1804: + build: + context: . + dockerfile: test/docker/ubuntu1804 + network_mode: "host" + security_opt: + - label=type:container_runtime_t + tty: true + test-debianstable: + build: + context: . + dockerfile: test/docker/debianstable + network_mode: "host" + security_opt: + - label=type:container_runtime_t + tty: true + test-debiantesting: + build: + context: . + dockerfile: test/docker/debiantesting + network_mode: "host" + security_opt: + - label=type:container_runtime_t + tty: true + test-gentoo: + build: + context: . + dockerfile: test/docker/gentoo + network_mode: "host" + security_opt: + - label=type:container_runtime_t + tty: true + test-opensuse1500: + build: + context: . + dockerfile: test/docker/opensuse1500 + network_mode: "host" + security_opt: + - label=type:container_runtime_t + tty: true + test-arch180101: + build: + context: . + dockerfile: test/docker/arch180101 + network_mode: "host" + security_opt: + - label=type:container_runtime_t + tty: true diff --git a/performance/CMakeLists.txt b/performance/CMakeLists.txt index 792e7f10b..a990911fe 100644 --- a/performance/CMakeLists.txt +++ b/performance/CMakeLists.txt @@ -1,4 +1,4 @@ -cmake_minimum_required (VERSION 2.8) +cmake_minimum_required (VERSION 3.0) add_custom_target (performance ./run_perf DEPENDS task_executable diff --git a/scripts/CMakeLists.txt b/scripts/CMakeLists.txt index edc8e2eb5..e6ac28d12 100644 --- a/scripts/CMakeLists.txt +++ b/scripts/CMakeLists.txt @@ -1,4 +1,4 @@ -cmake_minimum_required (VERSION 2.8) +cmake_minimum_required (VERSION 3.0) install (DIRECTORY bash fish vim zsh hooks DESTINATION ${TASK_DOCDIR}/scripts) install (DIRECTORY add-ons diff --git a/scripts/add-ons/README b/scripts/add-ons/README index 0a9799cde..45a9cc00b 100644 --- a/scripts/add-ons/README +++ b/scripts/add-ons/README @@ -1,3 +1,3 @@ The import/export add-on scripts have been relocated online. Please see: -https://taskwarrior.org/tools/#exts +https://taskwarrior.org/tools diff --git a/scripts/add-ons/update-holidays.pl b/scripts/add-ons/update-holidays.pl index 5205b5b1e..035157e23 100755 --- a/scripts/add-ons/update-holidays.pl +++ b/scripts/add-ons/update-holidays.pl @@ -1,7 +1,7 @@ #! /usr/bin/perl ################################################################################ ## -## Copyright 2006 - 2016, Paul Beckingham, Federico Hernandez. +## Copyright 2006 - 2020, 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 @@ -21,7 +21,7 @@ ## 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 +## https://www.opensource.org/licenses/mit-license.php ## ################################################################################ @@ -130,8 +130,8 @@ my $current = (localtime (time))[5] + 1900; my $next = $current + 1; # Construct the holidata.net URL. -my $url_current = "http://holidata.net/${locale}/${current}.json"; -my $url_next = "http://holidata.net/${locale}/${next}.json"; +my $url_current = "https://holidata.net/${locale}/${current}.json"; +my $url_next = "https://holidata.net/${locale}/${next}.json"; # Fetch data for the current year. my $data_current = get ($url_current); @@ -189,7 +189,7 @@ if (open my $fh, '>:utf8', $file) "# ${url_current}\n", "# ${url_next}\n", "#\n", - "# Copyright 2006 - 2016, Paul Beckingham, Federico Hernandez.\n", + "# Copyright 2006 - 2020, Paul Beckingham, Federico Hernandez.\n", "#\n", "# Permission is hereby granted, free of charge, to any person obtaining a copy\n", "# of this software and associated documentation files (the \"Software\"), to deal\n", @@ -209,7 +209,7 @@ if (open my $fh, '>:utf8', $file) "# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\n", "# SOFTWARE.\n", "#\n", - "# http://www.opensource.org/licenses/mit-license.php\n", + "# https://www.opensource.org/licenses/mit-license.php\n", "#\n", "###############################################################################\n", "\n", diff --git a/scripts/bash/task.sh b/scripts/bash/task.sh index e0c7fb039..ac07c096d 100644 --- a/scripts/bash/task.sh +++ b/scripts/bash/task.sh @@ -1,6 +1,6 @@ ################################################################################ # -# Copyright 2006 - 2016, Paul Beckingham, Federico Hernandez. +# Copyright 2006 - 2020, 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 @@ -20,7 +20,7 @@ # 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 +# https://www.opensource.org/licenses/mit-license.php # ################################################################################ # @@ -72,7 +72,7 @@ _task_offer_contexts() { COMPREPLY=( $(compgen -W "$($taskcommand _context) define delete list none show" -- $cur) ) } -_task_context_alias=$($taskcommand show | grep alias.*context | cut -d' ' -f1 | cut -d. -f2) +_task_context_alias=$($taskcommand show | grep 'alias.*context' | cut -d' ' -f1 | cut -d. -f2) _task() { diff --git a/scripts/bash/task_functions.sh b/scripts/bash/task_functions.sh deleted file mode 100644 index f60050e79..000000000 --- a/scripts/bash/task_functions.sh +++ /dev/null @@ -1,26 +0,0 @@ -CONFIRM_PROMPT='are you sure' -task_config () -{ - var="${1}" - shift - value="${@}" - echo y | task config $var "$value" | grep -iv "$CONFIRM_PROMPT" -} -task_vars () -{ - task _show | grep "^.*${1}.*=" | cut -d'=' -f1 -} -task_get () -{ - task _show | grep "^${1}=" | cut -d'=' -f2 -} -task_color () -{ - color="${1}" - shift - text="${@}" - task rc.verbose=nothing rc._forcecolor=yes color ${color} | grep 'task color' | \ - tail -n 1 | sed -e 's/^ //' -e "s/task color ${color}/${text}/" -} - - diff --git a/scripts/fish/task.fish b/scripts/fish/task.fish index 4daa4c65b..da0e0b544 100644 --- a/scripts/fish/task.fish +++ b/scripts/fish/task.fish @@ -33,7 +33,7 @@ # set -g task_complete_attribute_modifiers yes # # -# Copyright 2014 - 2016, Roman Inflianskas +# Copyright 2014 - 2020, Roman Inflianskas # # Permission is hereby granted, free of charge, to any person obtaining a copy # of this software and associated documentation files (the "Software"), to deal @@ -53,7 +53,7 @@ # 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 +# https://www.opensource.org/licenses/mit-license.php # NOTE: remember that sed on OS X is different in some aspects. E.g. it does # not understand \t for tabs. @@ -186,7 +186,7 @@ end function __fish.task.list.command # ignore special commands - __fish.task.list._command $argv | grep -Ev '^_' + __fish.task.list._command $argv | command grep -Ev '^_' end function __fish.task.list.command_mods diff --git a/scripts/utils/l10n b/scripts/utils/l10n deleted file mode 100755 index 2a4fd24b2..000000000 --- a/scripts/utils/l10n +++ /dev/null @@ -1,195 +0,0 @@ -#!/usr/bin/env python2.7 -################################################################################ -## -## Copyright 2006 - 2016, 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 -## -################################################################################ - -from __future__ import print_function -from __future__ import unicode_literals - -import os -import sys -import argparse -import re -import fnmatch - -REFERENCE = 'eng-USA.h' - -def find_localizations(source, single=''): - '''Finds all [a-z][a-z]-[A-Z][A-Z].h files in the source tree.''' - found = [] - for path, dirs, files in os.walk(source, topdown=True, onerror=None, followlinks=False): - matches = map(lambda x: os.path.join(path, x), - fnmatch.filter(files, '[a-z][a-z][a-z]-[A-Z][A-Z][A-Z].h')) - - if single: - # Accept both cases - if user specified es-ES.h or only es-ES - if not single.endswith('.h'): - single = '%s.h' % single - - for match in matches: - if match.endswith(single) or match.endswith(REFERENCE): - found.append(match) - else: - found.extend(matches) - - # Make sure REFERENCE is the first column. - # NOTE Empty string is always sorted first than any string - found.sort(key=lambda x: "" if x.endswith(REFERENCE) else x) - - return found - -def read_file(translations, file): - '''Reads all the localized strings from a file.''' - translations[file] = {} - with open(file, 'r') as fh: - for match in re.findall(r'^\s*#define\s+(STRING_[^\s]+)(\s|\\)+"([^"]*)"', fh.read(), re.MULTILINE): - translations[file][match[0]] = match[2] - -def is_present(translations, file, string): - '''Determines if the string is defined in a translation.''' - return string in translations[file] - -def used_in_source(source, string): - '''Determines if the string is used in the source.''' - command = "git grep %s %s | grep -v [a-z][a-z][a-z]-[A-Z][A-Z][A-Z].h >/dev/null 2>&1" % (string, source) - return True if os.system(command) == 0 else False - -def is_translated(translations, file, string): - '''Determines whether the string is the same in the base version as in the - translation, indicating work needed.''' - if file == base: - return True - elif string not in translations[base]: - return True - elif string not in translations[file]: - return False - else: - return bool(translations[file][string] != translations[base][string]) - -def main(args): - '''Processes all the localized files.''' - errors = 0 - translations = {} - - for file in args.files: - # Verify all files exist. - if not os.path.exists(file): - raise Exception("Localized file '%s' not readable." % file) - read_file(translations, file) - - strings = set() - for file in translations: - for string in translations[file]: - strings.add(string) - - if len(strings) == 0: - if not args.quiet: - print("There are no localized strings found.") - errors = 1 - - # Get length of longest string ID. - longest_string = len(max(strings, key=len)) - - # Display info. - if not args.quiet: - print('Scanning in', args.source) - print() - - # Print header line. - files = map(lambda x: os.path.basename(x), args.files) - - if not args.quiet: - print('%-*s' % (longest_string, 'String ID'), end='') - print(*map(lambda x: '%10s' % x, files), sep='') - print('-' * longest_string, ' '.join(['---------'] * len(files))) - - for string in sorted(strings): - # assess status of 'string': - # - clean - - line = '' - line_errors = 0 - for file in args.files: - message = ' ' - if is_present(translations, file, string): - if is_translated(translations, file, string): - message = ' Ok ' - else: - message = ' TODO ' - else: - message = ' Missing ' - line_errors = 1 - - line += message - - if args.all or line_errors != 0: - if args.search: - if used_in_source(args.source, string): - if not args.quiet: - print('%-*s' % (longest_string, string), line, sep='') - else: - if not args.quiet: - print('%-*s' % (longest_string, string), line, sep='') - line_errors = 1 - else: - if not args.quiet: - print('%-*s' % (longest_string, string), line, sep='') - - if line_errors: - errors = 1 - - if not args.quiet: - print('-' * longest_string, ' '.join(['---------'] * len(files))) - print('%-*s' % (longest_string, 'Total'), end='') - for file in args.files: - print('%10d' % len(translations[file]), end='') - print() - - sys.exit(errors) - -if __name__ == "__main__": - usage="""Utility for checking localized string status across translations.""" - - parser = argparse.ArgumentParser(description=usage) - parser.add_argument('--source', action='store', required=True, help='The source code tree.') - parser.add_argument('--single', action='store', help='Show only given localization next to reference.') - parser.add_argument('--all', action='store_true', help='Show all string IDs.') - parser.add_argument('--search', action='store_true', help='Search source for use.') - parser.add_argument('--quiet', action='store_true', help='Produces no output.') - args = parser.parse_args() - - if args.source: - args.files = find_localizations(args.source) - - if args.single: - args.files = find_localizations(args.source, args.single) - - base = filter(lambda x: x.endswith(REFERENCE), args.files)[0] - - try: - main(args) - except Exception as msg: - print('Error:', msg) - diff --git a/scripts/vim/README b/scripts/vim/README index b250adc0a..91df60ee8 100644 --- a/scripts/vim/README +++ b/scripts/vim/README @@ -53,7 +53,7 @@ You should then be ready to go. --- All four above mentioned files are -Copyright 2009 - 2016 John Florian +Copyright 2009 - 2020 John Florian and are available under the MIT license. For the full text of this license, see COPYING. diff --git a/scripts/vim/ftdetect/task.vim b/scripts/vim/ftdetect/task.vim index 241b63a79..82dc22539 100644 --- a/scripts/vim/ftdetect/task.vim +++ b/scripts/vim/ftdetect/task.vim @@ -4,7 +4,7 @@ " Maintainer: John Florian " Updated: Thu Dec 10 18:28:26 EST 2009 " -" Copyright 2009 - 2016 John Florian +" Copyright 2009 - 2020 John Florian " " This file is available under the MIT license. " For the full text of this license, see COPYING. @@ -16,6 +16,7 @@ au BufRead,BufNewFile backlog.data set filetype=javascript " Taskwarrior configuration file au BufRead,BufNewFile .taskrc set filetype=taskrc +au BufRead,BufNewFile taskrc set filetype=taskrc " Taskwarrior handling of 'task 42 edit' au BufRead,BufNewFile *.task set filetype=taskedit diff --git a/scripts/vim/syntax/taskdata.vim b/scripts/vim/syntax/taskdata.vim index 6782f732f..739a86efa 100644 --- a/scripts/vim/syntax/taskdata.vim +++ b/scripts/vim/syntax/taskdata.vim @@ -3,7 +3,7 @@ " Maintainer: John Florian " Updated: Wed Jul 8 19:46:20 EDT 2009 " -" Copyright 2009 - 2016 John Florian +" Copyright 2009 - 2020 John Florian " " This file is available under the MIT license. " For the full text of this license, see COPYING. diff --git a/scripts/vim/syntax/taskedit.vim b/scripts/vim/syntax/taskedit.vim index 2edbb7899..240e4dc96 100644 --- a/scripts/vim/syntax/taskedit.vim +++ b/scripts/vim/syntax/taskedit.vim @@ -3,7 +3,7 @@ " Maintainer: John Florian " Updated: Wed Jul 8 19:46:32 EDT 2009 " -" Copyright 2009 - 2016 John Florian +" Copyright 2009 - 2020 John Florian " " This file is available under the MIT license. " For the full text of this license, see COPYING. diff --git a/scripts/vim/syntax/taskrc.vim b/scripts/vim/syntax/taskrc.vim index 1ff32cb4e..1166a5ee0 100644 --- a/scripts/vim/syntax/taskrc.vim +++ b/scripts/vim/syntax/taskrc.vim @@ -1,6 +1,6 @@ " Vim syntax file " -" Copyright (c) 2014 - 2016 Taskwarrior Team +" Copyright (c) 2014 - 2020 Taskwarrior Team " Copyright (c) 2009 - 2014 John Florian " " Permission is hereby granted, free of charge, to any person obtaining a copy @@ -21,7 +21,7 @@ " 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 +" https://www.opensource.org/licenses/mit-license.php " if version < 600 @@ -102,6 +102,7 @@ syn match taskrcGoodKey '^\s*\Vdefault.command='he=e-1 syn match taskrcGoodKey '^\s*\Vdefault.due='he=e-1 syn match taskrcGoodKey '^\s*\Vdefault.priority='he=e-1 syn match taskrcGoodKey '^\s*\Vdefault.project='he=e-1 +syn match taskrcGoodKey '^\s*\Vdefault.scheduled='he=e-1 syn match taskrcGoodKey '^\s*\Vdefaultheight='he=e-1 syn match taskrcGoodKey '^\s*\Vdefaultwidth='he=e-1 syn match taskrcGoodKey '^\s*\Vdependency.confirmation='he=e-1 diff --git a/scripts/zsh/_task b/scripts/zsh/_task index 46628be94..2b244779c 100644 --- a/scripts/zsh/_task +++ b/scripts/zsh/_task @@ -1,6 +1,6 @@ #compdef task # -# Copyright 2010 - 2016 Johannes Schlatow +# Copyright 2010 - 2020 Johannes Schlatow # Copyright 2009 P.C. Shyamshankar # # Permission is hereby granted, free of charge, to any person obtaining a copy @@ -21,208 +21,205 @@ # 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 -# -typeset -g _task_cmds _task_projects _task_tags _task_config _task_modifiers -_task_projects=($(task _projects)) -_task_tags=($(task _tags)) -_task_zshids=( ${(f)"$(task _zshids)"} ) -_task_config=($(task _config)) -_task_columns=($(task _columns)) -_task_modifiers=( - 'before' \ - 'after' \ - 'none' \ - 'any' \ - 'is' \ - 'isnt' \ - 'has' \ - 'hasnt' \ - 'startswith' \ - 'endswith' \ - 'word' \ - 'noword' -) -_task_conjunctions=( - 'and' \ - 'or' \ - 'xor' \ - '\)' \ - '\(' \ - '<' \ - '<=' \ - '=' \ - '!=' \ - '>=' \ - '>' -) -_task_cmds=($(task _commands; task _aliases)) -_task_zshcmds=( ${(f)"$(task _zshcommands)"} sentinel:sentinel:sentinel ) - -_task_aliases=($(task _aliases)) - -_task() { - _arguments -s -S \ - "*::task default:_task_default" - return 0 -} - -local -a reply args word -word=$'[^\0]#\0' - -# priorities -local -a task_priorities -_regex_words values 'task priorities' \ - 'H:High' \ - 'M:Middle' \ - 'L:Low' -task_priorities=("$reply[@]") - -# projects -local -a task_projects -task_projects=( - /"$word"/ - ":values:task projects:compadd -a _task_projects" -) - -local -a _task_dates -_regex_words values 'task dates' \ - 'tod*ay:Today' \ - 'yes*terday:Yesterday' \ - 'tom*orrow:Tomorrow' \ - 'sow:Start of week' \ - 'soww:Start of work week' \ - 'socw:Start of calendar week' \ - 'som:Start of month' \ - 'soq:Start of quarter' \ - 'soy:Start of year' \ - 'eow:End of week' \ - 'eoww:End of work week' \ - 'eocw:End of calendar week' \ - 'eom:End of month' \ - 'eoq:End of quarter' \ - 'eoy:End of year' \ - 'mon:Monday' \ - 'tue:Tuesday'\ - 'wed:Wednesday' \ - 'thu:Thursday' \ - 'fri:Friday' \ - 'sat:Saturday' \ - 'sun:Sunday' \ - 'good*friday:Good Friday' \ - 'easter:Easter' \ - 'eastermonday:Easter Monday' \ - 'ascension:Ascension' \ - 'pentecost:Pentecost' \ - 'midsommar:Midsommar' \ - 'midsommarafton:Midsommarafton' \ - 'later:Later' \ - 'someday:Some Day' -_task_dates=("$reply[@]") - -local -a _task_reldates -_regex_words values 'task reldates' \ - 'hrs:n hours' \ - 'day:n days' \ - '1st:first' \ - '2nd:second' \ - '3rd:third' \ - 'th:4th, 5th, etc.' \ - 'wks:weeks' -_task_reldates=("$reply[@]") - -task_dates=( - \( "$_task_dates[@]" \| - \( /$'[0-9][0-9]#'/- \( "$_task_reldates[@]" \) \) - \) -) - -local -a task_zshids -if (( $#_task_zshids )); then - _regex_words values 'task IDs' $_task_zshids - task_zshids=("$reply[@]") -fi - -_regex_words values 'task frequencies' \ - 'daily:Every day' \ - 'day:Every day' \ - 'weekdays:Every day skipping weekend days' \ - 'weekly:Every week' \ - 'biweekly:Every two weeks' \ - 'fortnight:Every two weeks' \ - 'monthly:Every month' \ - 'quarterly:Every three months' \ - 'semiannual:Every six months' \ - 'annual:Every year' \ - 'yearly:Every year' \ - 'biannual:Every two years' \ - 'biyearly:Every two years' -_task_freqs=("$reply[@]") - -local -a _task_frequencies -_regex_words values 'task frequencies' \ - 'd:days' \ - 'w:weeks' \ - 'q:quarters' \ - 'y:years' -_task_frequencies=("$reply[@]") - -task_freqs=( - \( "$_task_freqs[@]" \| - \( /$'[0-9][0-9]#'/- \( "$_task_frequencies[@]" \) \) - \) -) - -# attributes -local -a task_attributes -_regex_words -t ':' default 'task attributes' \ - 'des*cription:Task description text' \ - 'status:Status of task - pending, completed, deleted, waiting' \ - 'pro*ject:Project name:$task_projects' \ - 'pri*ority:priority:$task_priorities' \ - 'du*e:Due date:$task_dates' \ - 're*cur:Recurrence frequency:$task_freqs' \ - 'un*til:Expiration date:$task_dates' \ - 'li*mit:Desired number of rows in report' \ - 'wa*it:Date until task becomes pending:$task_dates' \ - 'ent*ry:Date task was created:$task_dates' \ - 'end:Date task was completed/deleted:$task_dates' \ - 'st*art:Date task was started:$task_dates' \ - 'sc*heduled:Date task is scheduled to start:$task_dates' \ - 'dep*ends:Other tasks that this task depends upon:$task_zshids' -task_attributes=("$reply[@]") - -args=( - \( "$task_attributes[@]" \| - \( /'(project|description|status|entry|end|start|scheduled|depends|due|wait|recur|priority|until|limit).'/- \( /$'[^:]#:'/ ":default:modifiers:compadd -S ':' -a _task_modifiers" \) \) \| - \( /'(rc).'/- \( /$'[^:]#:'/ ":arguments:config:compadd -S ':' -a _task_config" \) \) \| - \( /'(+|-)'/- \( /"$word"/ ":values:remove tag:compadd -a _task_tags" \) \) \| - \( /"$word"/ \) - \) \# -) -_regex_arguments _task_attributes "${args[@]}" - -## task commands +# https://www.opensource.org/licenses/mit-license.php # filter completion (( $+functions[_task_filter] )) || _task_filter() { + + local -a reply + local word=$'[^\0]#\0' + + # projects + local _task_projects=($(task _projects)) + local task_projects=( + /"$word"/ + ":values:task projects:compadd -a _task_projects" + ) + + _regex_words values 'task dates' \ + 'tod*ay:Today' \ + 'yes*terday:Yesterday' \ + 'tom*orrow:Tomorrow' \ + 'sow:Start of week' \ + 'soww:Start of work week' \ + 'socw:Start of calendar week' \ + 'som:Start of month' \ + 'soq:Start of quarter' \ + 'soy:Start of year' \ + 'eow:End of week' \ + 'eoww:End of work week' \ + 'eocw:End of calendar week' \ + 'eom:End of month' \ + 'eoq:End of quarter' \ + 'eoy:End of year' \ + 'mon:Monday' \ + 'tue:Tuesday'\ + 'wed:Wednesday' \ + 'thu:Thursday' \ + 'fri:Friday' \ + 'sat:Saturday' \ + 'sun:Sunday' \ + 'good*friday:Good Friday' \ + 'easter:Easter' \ + 'eastermonday:Easter Monday' \ + 'ascension:Ascension' \ + 'pentecost:Pentecost' \ + 'midsommar:Midsommar' \ + 'midsommarafton:Midsommarafton' \ + 'later:Later' \ + 'someday:Some Day' + local _task_dates=("$reply[@]") + + _regex_words values 'task reldates' \ + 'hrs:n hours' \ + 'day:n days' \ + '1st:first' \ + '2nd:second' \ + '3rd:third' \ + 'th:4th, 5th, etc.' \ + 'wks:weeks' + local _task_reldates=("$reply[@]") + + local task_dates=( + \( "$_task_dates[@]" \| + \( /$'[0-9][0-9]#'/- \( "$_task_reldates[@]" \) \) + \) + ) + + # This data is a little bit differnt, it may contain any kind of character so + # we parse it manually and quote using '${(q)_desc}' the descriptions + local -a _task_zshids + local _id desc + task _zshids | while IFS=':' read _id desc; do + _task_zshids+=("$_id:${(qq)desc}") + done + _regex_words values 'task IDs' $_task_zshids + local task_zshids=("$reply[@]") + + _regex_words values 'task frequencies' \ + 'daily:Every day' \ + 'day:Every day' \ + 'weekdays:Every day skipping weekend days' \ + 'weekly:Every week' \ + 'biweekly:Every two weeks' \ + 'fortnight:Every two weeks' \ + 'monthly:Every month' \ + 'quarterly:Every three months' \ + 'semiannual:Every six months' \ + 'annual:Every year' \ + 'yearly:Every year' \ + 'biannual:Every two years' \ + 'biyearly:Every two years' + local _task_freqs=("$reply[@]") + + _regex_words values 'task frequencies' \ + 'd:days' \ + 'w:weeks' \ + 'q:quarters' \ + 'y:years' + local _task_frequencies=("$reply[@]") + + local task_freqs=( + \( "$_task_freqs[@]" \| + \( /$'[0-9][0-9]#'/- \( "$_task_frequencies[@]" \) \) + \) + ) + + # task statuses + local _task_statuses=( + pending + completed + deleted + waiting + ) + _regex_words statuses 'task statuses' \ + "${_task_statuses}" + local task_statuses=("${reply[@]}") + + # attributes + local _task_all_attributes=( + 'des*cription:Task description text' + 'status:Status of task:$task_statuses' + 'pro*ject:Project name:$task_projects' + 'du*e:Due date:$task_dates' + 're*cur:Recurrence frequency:$task_freqs' + 'un*til:Expiration date:$task_dates' + 'li*mit:Desired number of rows in report' + 'wa*it:Date until task becomes pending:$task_dates' + 'ent*ry:Date task was created:$task_dates' + 'end:Date task was completed/deleted:$task_dates' + 'st*art:Date task was started:$task_dates' + 'sc*heduled:Date task is scheduled to start:$task_dates' + 'depends:Other tasks that this task depends upon:$task_zshids' + ) + ## add UDAs as attributes + local uda_name uda_label uda_values + local -a udas_spec + task _udas | while read uda_name; do + uda_label="$(task _get rc.uda."$uda_name".label)" + # TODO: we could have got the values of every uda and try to complete that + # but that can become extremly slow with a lot of udas + #uda_values=(${(@s:,:)"$(task _get rc.uda."$uda_name".values)"}) + udas_spec+=("${uda_name}:${(q)uda_label}") + done + _task_all_attributes=("${_task_all_attributes[@]}" "${udas_spec[@]}") + _regex_words -t ':' default 'task attributes' "${_task_all_attributes[@]}" + local task_attributes=("$reply[@]") + + local _task_tags=($(task _tags)) + local _task_config=($(task _config)) + local _task_modifiers=( + 'before' + 'after' + 'none' + 'any' + 'is' + 'isnt' + 'has' + 'hasnt' + 'startswith' + 'endswith' + 'word' + 'noword' + ) + local _task_conjunctions=( + 'and' + 'or' + 'xor' + '\)' + '\(' + '<' + '<=' + '=' + '!=' + '>=' + '>' + ) + _regex_arguments _task_attributes \ + \( "${task_attributes[@]}" \| \ + \( /'(project|description|status|entry|end|start|scheduled|depends|due|wait|recur|priority|until|limit).'/- \( /$'[^:]#:'/ ":default:modifiers:compadd -S ':' -a _task_modifiers" \) \) \| \ + \( /'(rc).'/- \( /$'[^:]#:'/ ":arguments:config:compadd -S ':' -a _task_config" \) \) \| \ + \( /'(+|-)'/- \( /"$word"/ ":values:remove tag:compadd -a _task_tags" \) \) \| \ + \( /"$word"/ \) \ + \) \# + _task_attributes "$@" # TODO complete conjunctions only if the previous word is a filter expression, i.e. attribute, ID, any non-command _describe -t default 'task conjunctions' _task_conjunctions } -# execute completion -(( $+functions[_task_execute] )) || -_task_execute() { - _files -} - # id-only completion -(( $+functions[_task_id] )) || -_task_id() { - _describe -t values 'task IDs' _task_zshids +(( $+functions[_task_ids] )) || +_task_ids() { + local _ids=( ${(f)"$(task _zshids)"} ) + _describe 'task ids' _ids +} +(( $+functions[_task_aliases] )) || +_task_aliases() { + local _aliases=( ${(f)"$(task _aliases)"} ) + _describe 'task aliases' _aliases } # subcommand-only function @@ -233,6 +230,7 @@ _task_subcommands() { local cmd category desc local lastcategory='' # The list is sorted by category, in the right order. + local _task_zshcmds=( ${(f)"$(task _zshcommands)"} sentinel:sentinel:sentinel ) for _zshcmd in "$_task_zshcmds[@]"; do # Parse out the three fields cmd=${_zshcmd%%:*} @@ -253,33 +251,42 @@ _task_subcommands() { done } +## contexts +(( $+functions[_task_context] )) || +_task_context() { + local _contexts=(${(f)"$(task _context)"}) + _describe 'task contexts' _contexts +} + ## first level completion => task sub-command completion (( $+functions[_task_default] )) || _task_default() { - local cmd ret=1 + local cmd ret=1 integer i=1 + local _task_cmds=($(task _commands; task _aliases)) while (( i < $#words )) do cmd="${_task_cmds[(r)$words[$i]]}" if (( $#cmd )); then - _call_function ret _task_${cmd} || - _call_function ret _task_filter || - _message "No command remaining." + if (( $+functions[_task_${cmd}] )); then + _task_${cmd} + return ret + fi + _call_function ret _task_filter || + _message "No command remaining." return ret fi (( i++ )) done - # update IDs - _task_zshids=( ${(f)"$(task _zshids)"} ) - _task_subcommands - _describe -t tasks 'task IDs' _task_zshids - _describe -t aliases 'task aliases' _task_aliases + # _task_ids + _task_aliases _call_function ret _task_filter return ret } -_task "$@" +_arguments -s -S \ + "*::task default:_task_default" diff --git a/src/.gitignore b/src/.gitignore index 6b6ab2aee..99a78c14e 100644 --- a/src/.gitignore +++ b/src/.gitignore @@ -3,3 +3,4 @@ Makefile.in debug calc lex +liblibshared.a diff --git a/src/CLI2.cpp b/src/CLI2.cpp index a6c1305b7..b641cafb4 100644 --- a/src/CLI2.cpp +++ b/src/CLI2.cpp @@ -1,6 +1,6 @@ //////////////////////////////////////////////////////////////////////////////// // -// Copyright 2006 - 2016, Paul Beckingham, Federico Hernandez. +// Copyright 2006 - 2020, 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 @@ -20,7 +20,7 @@ // 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 +// https://www.opensource.org/licenses/mit-license.php // //////////////////////////////////////////////////////////////////////////////// @@ -32,11 +32,8 @@ #include #include #include -#include -#include -#include - -extern Context context; +#include +#include // Overridden by rc.abbreviation.minimum. int CLI2::minimumMatchLength = 3; @@ -213,7 +210,7 @@ const std::string A2::dump () const else tags += "\033[32m" + tag + "\033[0m "; } - return output + " " + atts + tags; + return output + ' ' + atts + tags; } //////////////////////////////////////////////////////////////////////////////// @@ -236,7 +233,7 @@ void CLI2::getOverride (int argc, const char** argv, std::string& home, File& rc if (last_slash != std::string::npos) home = rc.parent (); - context.header (format (STRING_PARSER_ALTERNATE_RC, rc._data)); + Context::getContext ().header (format ("Using alternate .taskrc file {1}", rc._data)); // Keep looping, because if there are multiple rc:file arguments, the last // one should dominate. @@ -249,7 +246,7 @@ void CLI2::getOverride (int argc, const char** argv, std::string& home, File& rc // Static method. void CLI2::getDataLocation (int argc, const char** argv, Path& data) { - std::string location = context.config.get ("data.location"); + std::string location = Context::getContext ().config.get ("data.location"); if (location != "") data = location; @@ -263,7 +260,7 @@ void CLI2::getDataLocation (int argc, const char** argv, Path& data) raw.substr (0, 16) == "rc.data.location") { data = Directory (raw.substr (17)); - context.header (format (STRING_PARSER_ALTERNATE_DATA, (std::string) data)); + Context::getContext ().header (format ("Using alternate data.location {1}", (std::string) data)); // Keep looping, because if there are multiple rc:file arguments, the last // one should dominate. @@ -277,22 +274,31 @@ void CLI2::applyOverrides (int argc, const char** argv) { for (int i = 0; i < argc; ++i) { + + // Don't process any arguments after a '--' std::string raw = argv[i]; if (raw == "--") break; + // Overrides always start with 'rc.' if (raw.length () > 3 && raw.substr (0, 3) == "rc.") { + + // Our separator can either be '=' or ':', so try and find both. auto sep = raw.find ('=', 3); if (sep == std::string::npos) sep = raw.find (':', 3); + + // Process our override if well-formed if (sep != std::string::npos) { std::string name = raw.substr (3, sep - 3); std::string value = raw.substr (sep + 1); - context.config.set (name, value); - context.footnote (format (STRING_PARSER_OVERRIDE_RC, name, value)); + Context::getContext ().config.set (name, value); + + if (Context::getContext ().verbose("override")) + Context::getContext ().footnote (format ("Configuration override rc.{1}:{2}", name, value)); } } } @@ -376,9 +382,7 @@ void CLI2::handleArg0 () A2 cal ("calendar", Lexer::Type::word); _args.push_back (cal); } - else if (basename == "task" || - basename == "tw" || - basename == "t") + else { _args.push_back (a); } @@ -399,6 +403,7 @@ void CLI2::lexArguments () { bool quoted = Lexer::wasQuoted (_original_args[i].attribute ("raw")); + // Process single-token arguments. std::string lexeme; Lexer::Type type; Lexer lex (_original_args[i].attribute ("raw")); @@ -422,11 +427,13 @@ void CLI2::lexArguments () _args.push_back (a); } + + // Process muktiple-token arguments. else { std::string quote = "'"; std::string escaped = _original_args[i].attribute ("raw"); - str_replace (escaped, quote, "\\'"); + escaped = str_replace (escaped, quote, "\\'"); std::string::size_type cursor = 0; std::string word; @@ -460,8 +467,8 @@ void CLI2::lexArguments () } } - if (context.config.getInteger ("debug.parser") >= 2) - context.debug (dump ("CLI2::analyze lexArguments")); + if (Context::getContext ().config.getInteger ("debug.parser") >= 2) + Context::getContext ().debug (dump ("CLI2::analyze lexArguments")); } //////////////////////////////////////////////////////////////////////////////// @@ -491,7 +498,7 @@ void CLI2::demotion () else if (a._lextype == Lexer::Type::pair && canonicalize (canonical, "pseudo", a.attribute ("name"))) { - context.config.set (canonical, a.attribute ("value")); + Context::getContext ().config.set (canonical, a.attribute ("value")); changes = true; // Equivalent to erasing 'a'. @@ -502,16 +509,16 @@ void CLI2::demotion () } if (changes && - context.config.getInteger ("debug.parser") >= 2) - context.debug (dump ("CLI2::analyze demotion")); + Context::getContext ().config.getInteger ("debug.parser") >= 2) + Context::getContext ().debug (dump ("CLI2::analyze demotion")); } //////////////////////////////////////////////////////////////////////////////// // Intended to be called after ::add() to perform the final analysis. void CLI2::analyze () { - if (context.config.getInteger ("debug.parser") >= 2) - context.debug (dump ("CLI2::analyze")); + if (Context::getContext ().config.getInteger ("debug.parser") >= 2) + Context::getContext ().debug (dump ("CLI2::analyze")); // Process _original_args. _args.clear (); @@ -524,7 +531,7 @@ void CLI2::analyze () { defaultCommand (); if (! findCommand ()) - throw std::string (STRING_TRIVIAL_INPUT); + throw std::string ("You must specify a command or a task to modify."); } demotion (); @@ -568,10 +575,10 @@ void CLI2::addContextFilter () return; // Detect if any context is set, and bail out if not - std::string contextName = context.config.get ("context"); + std::string contextName = Context::getContext ().config.get ("context"); if (contextName == "") { - context.debug ("No context."); + Context::getContext ().debug ("No context."); return; } @@ -582,23 +589,23 @@ void CLI2::addContextFilter () a._lextype == Lexer::Type::number || a._lextype == Lexer::Type::set) { - context.debug (format ("UUID/ID argument found '{1}', not applying context.", a.attribute ("raw"))); + Context::getContext ().debug (format ("UUID/ID argument found '{1}', not applying context.", a.attribute ("raw"))); return; } } // Apply context - context.debug ("Applying context: " + contextName); - std::string contextFilter = context.config.get ("context." + contextName); + Context::getContext ().debug ("Applying context: " + contextName); + std::string contextFilter = Context::getContext ().config.get ("context." + contextName); if (contextFilter == "") - context.debug ("Context '" + contextName + "' not defined."); + Context::getContext ().debug ("Context '" + contextName + "' not defined."); else { _context_filter_added = true; addFilter (contextFilter); - if (context.verbose ("context")) - context.footnote (format ("Context '{1}' set. Use 'task context none' to remove.", contextName)); + if (Context::getContext ().verbose ("context")) + Context::getContext ().footnote (format ("Context '{1}' set. Use 'task context none' to remove.", contextName)); } } @@ -624,7 +631,7 @@ void CLI2::prepareFilter () desugarFilterPatterns (); insertJunctions (); // Deliberately after all desugar calls. - if (context.verbose ("filter")) + if (Context::getContext ().verbose ("filter")) { std::string combined; for (const auto& a : _args) @@ -632,14 +639,14 @@ void CLI2::prepareFilter () if (a.hasTag ("FILTER")) { if (combined != "") - combined += " "; + combined += ' '; combined += a.attribute ("raw"); } } if (combined.size ()) - context.footnote (std::string (STRING_COLUMN_LABEL_FILTER) + ": " + combined); + Context::getContext ().footnote (std::string ("Filter: ") + combined); } } @@ -652,13 +659,13 @@ const std::vector CLI2::getWords () if (a.hasTag ("MISCELLANEOUS")) words.push_back (a.attribute ("raw")); - if (context.config.getInteger ("debug.parser") >= 2) + if (Context::getContext ().config.getInteger ("debug.parser") >= 2) { Color colorOrigArgs ("gray10 on gray4"); std::string message = " "; for (const auto& word : words) - message += colorOrigArgs.colorize (word) + " "; - context.debug ("CLI2::getWords" + message); + message += colorOrigArgs.colorize (word) + ' '; + Context::getContext ().debug ("CLI2::getWords" + message); } return words; @@ -737,13 +744,13 @@ const std::string CLI2::dump (const std::string& title) const out << colorFilter.colorize (i->attribute ("raw")); } - out << "\n"; + out << '\n'; if (_args.size ()) { out << " _args\n"; for (const auto& a : _args) - out << " " << a.dump () << "\n"; + out << " " << a.dump () << '\n'; } if (_id_ranges.size ()) @@ -752,21 +759,21 @@ const std::string CLI2::dump (const std::string& title) const for (const auto& range : _id_ranges) { if (range.first != range.second) - out << colorArgs.colorize (range.first + "-" + range.second) << " "; + out << colorArgs.colorize (range.first + "-" + range.second) << ' '; else - out << colorArgs.colorize (range.first) << " "; + out << colorArgs.colorize (range.first) << ' '; } - out << "\n"; + out << '\n'; } if (_uuid_list.size ()) { out << " _uuid_list\n "; for (const auto& uuid : _uuid_list) - out << colorArgs.colorize (uuid) << " "; + out << colorArgs.colorize (uuid) << ' '; - out << "\n"; + out << '\n'; } return out.str (); @@ -845,11 +852,11 @@ void CLI2::aliasExpansion () while (action && counter++ < safetyValveDefault); if (counter >= safetyValveDefault) - context.debug (format (STRING_PARSER_ALIAS_NEST, safetyValveDefault)); + Context::getContext ().debug (format ("Nested alias limit of {1} reached.", safetyValveDefault)); if (changes && - context.config.getInteger ("debug.parser") >= 2) - context.debug (dump ("CLI2::analyze aliasExpansion")); + Context::getContext ().config.getInteger ("debug.parser") >= 2) + Context::getContext ().debug (dump ("CLI2::analyze aliasExpansion")); } //////////////////////////////////////////////////////////////////////////////// @@ -883,8 +890,8 @@ void CLI2::canonicalizeNames () } if (changes && - context.config.getInteger ("debug.parser") >= 2) - context.debug (dump ("CLI2::analyze canonicalizeNames")); + Context::getContext ().config.getInteger ("debug.parser") >= 2) + Context::getContext ().debug (dump ("CLI2::analyze canonicalizeNames")); } //////////////////////////////////////////////////////////////////////////////// @@ -893,7 +900,7 @@ void CLI2::categorizeArgs () { // Context is only applied for commands that request it. std::string command = getCommand (); - Command* cmd = context.commands[command]; + Command* cmd = Context::getContext ().commands[command]; if (cmd && cmd->uses_context ()) addContextFilter (); @@ -935,7 +942,7 @@ void CLI2::categorizeArgs () ! cmd->accepts_miscellaneous ()) { // No commands were expected --> error. - throw format (STRING_PARSER_UNEXPECTED_ARG, command, a.attribute ("raw")); + throw format ("The '{1}' command does not allow '{2}'.", command, a.attribute ("raw")); } else if (cmd && ! cmd->accepts_filter () && @@ -959,7 +966,7 @@ void CLI2::categorizeArgs () cmd->accepts_miscellaneous ()) { // Error: internally inconsistent. - throw std::string (STRING_UNKNOWN_ERROR); + throw std::string ("Unknown error. Please report."); } else if (cmd && cmd->accepts_filter () && @@ -999,13 +1006,13 @@ void CLI2::categorizeArgs () cmd->accepts_miscellaneous ()) { // Error: internally inconsistent. - throw std::string (STRING_UNKNOWN_ERROR); + throw std::string ("Unknown error. Please report."); } } if (changes && - context.config.getInteger ("debug.parser") >= 2) - context.debug (dump ("CLI2::analyze categorizeArgs")); + Context::getContext ().config.getInteger ("debug.parser") >= 2) + Context::getContext ().debug (dump ("CLI2::analyze categorizeArgs")); } //////////////////////////////////////////////////////////////////////////////// @@ -1073,8 +1080,8 @@ void CLI2::parenthesizeOriginalFilter () _args = reconstructed; - if (context.config.getInteger ("debug.parser") >= 2) - context.debug (dump ("CLI2::analyze parenthesizeOriginalFilter")); + if (Context::getContext ().config.getInteger ("debug.parser") >= 2) + Context::getContext ().debug (dump ("CLI2::analyze parenthesizeOriginalFilter")); } } @@ -1105,7 +1112,7 @@ bool CLI2::findCommand () a.tag ("CMD"); // Apply command DNA as tags. - Command* command = context.commands[canonical]; + Command* command = Context::getContext ().commands[canonical]; if (command->read_only ()) a.tag ("READONLY"); if (command->displays_id ()) a.tag ("SHOWSID"); if (command->needs_gc ()) a.tag ("RUNSGC"); @@ -1114,8 +1121,8 @@ bool CLI2::findCommand () if (command->accepts_modifications ()) a.tag ("ALLOWSMODIFICATIONS"); if (command->accepts_miscellaneous ()) a.tag ("ALLOWSMISC"); - if (context.config.getInteger ("debug.parser") >= 2) - context.debug (dump ("CLI2::analyze findCommand")); + if (Context::getContext ().config.getInteger ("debug.parser") >= 2) + Context::getContext ().debug (dump ("CLI2::analyze findCommand")); // Stop and indicate command found. return true; @@ -1176,8 +1183,8 @@ void CLI2::desugarFilterTags () { _args = reconstructed; - if (context.config.getInteger ("debug.parser") >= 2) - context.debug (dump ("CLI2::prepareFilter desugarFilterTags")); + if (Context::getContext ().config.getInteger ("debug.parser") >= 2) + Context::getContext ().debug (dump ("CLI2::prepareFilter desugarFilterTags")); } } @@ -1202,8 +1209,8 @@ void CLI2::findStrayModifications () } if (changes) - if (context.config.getInteger ("debug.parser") >= 2) - context.debug (dump ("CLI2::prepareFilter findStrayModifications")); + if (Context::getContext ().config.getInteger ("debug.parser") >= 2) + Context::getContext ().debug (dump ("CLI2::prepareFilter findStrayModifications")); } //////////////////////////////////////////////////////////////////////////////// @@ -1240,12 +1247,12 @@ void CLI2::desugarFilterAttributes () // ) // Use this sequence in place of a single value. std::vector values = lexExpression (value); - if (context.config.getInteger ("debug.parser") >= 2) + if (Context::getContext ().config.getInteger ("debug.parser") >= 2) { - context.debug ("CLI2::lexExpression " + name + ":" + value); + Context::getContext ().debug ("CLI2::lexExpression " + name + ':' + value); for (auto& v : values) - context.debug (" " + v.dump ()); - context.debug (" "); + Context::getContext ().debug (" " + v.dump ()); + Context::getContext ().debug (" "); } bool found = false; @@ -1258,7 +1265,7 @@ void CLI2::desugarFilterAttributes () // date --> yes // duration --> yes bool evalSupported = true; - Column* col = context.columns[canonical]; + Column* col = Context::getContext ().columns[canonical]; if (col && col->type () == "string") evalSupported = false; @@ -1270,7 +1277,7 @@ void CLI2::desugarFilterAttributes () A2 op ("", Lexer::Type::op); op.tag ("FILTER"); - A2 rhs ("", Lexer::Type::string); + A2 rhs ("", values[0]._lextype); rhs.tag ("FILTER"); // Special case for ':'. @@ -1357,22 +1364,27 @@ void CLI2::desugarFilterAttributes () #endif } else - throw format (STRING_PARSER_UNKNOWN_ATTMOD, mod); + throw format ("Error: unrecognized attribute modifier '{1}'.", mod); reconstructed.push_back (lhs); reconstructed.push_back (op); // Do not modify this construct without full understanding. - if (values.size () == 1 || ! evalSupported) + // Getting this wrong breaks a whole lot of filtering tests. + if (values.size () > 1 || evalSupported) { - if (Lexer::isDOM (rhs.attribute ("raw"))) - rhs._lextype = Lexer::Type::dom; - + for (auto& v : values) + reconstructed.push_back (v); + } + else if (Lexer::isDOM (rhs.attribute ("raw"))) + { + rhs._lextype = Lexer::Type::dom; reconstructed.push_back (rhs); } else - for (auto& v : values) - reconstructed.push_back (v); + { + reconstructed.push_back (rhs); + } found = true; } @@ -1399,8 +1411,8 @@ void CLI2::desugarFilterAttributes () { _args = reconstructed; - if (context.config.getInteger ("debug.parser") >= 2) - context.debug (dump ("CLI2::prepareFilter desugarFilterAttributes")); + if (Context::getContext ().config.getInteger ("debug.parser") >= 2) + Context::getContext ().debug (dump ("CLI2::prepareFilter desugarFilterAttributes")); } } @@ -1438,8 +1450,8 @@ void CLI2::desugarFilterPatterns () { _args = reconstructed; - if (context.config.getInteger ("debug.parser") >= 2) - context.debug (dump ("CLI2::prepareFilter desugarFilterPatterns")); + if (Context::getContext ().config.getInteger ("debug.parser") >= 2) + Context::getContext ().debug (dump ("CLI2::prepareFilter desugarFilterPatterns")); } } @@ -1456,7 +1468,7 @@ void CLI2::findIDs () { bool changes = false; - if (context.config.getBoolean ("sugar")) + if (Context::getContext ().config.getBoolean ("sugar")) { bool previousFilterArgWasAnOperator = false; int filterCount = 0; @@ -1480,8 +1492,7 @@ void CLI2::findIDs () else if (a._lextype == Lexer::Type::set) { // Split the ID list into elements. - std::vector elements; - split (elements, a.attribute ("raw"), ','); + auto elements = split (a.attribute ("raw"), ','); for (auto& element : elements) { @@ -1536,8 +1547,7 @@ void CLI2::findIDs () a.tag ("FILTER"); // Split the ID list into elements. - std::vector elements; - split (elements, raw, ','); + auto elements = split (raw, ','); for (const auto& element : elements) { @@ -1578,8 +1588,8 @@ void CLI2::findIDs () } if (changes) - if (context.config.getInteger ("debug.parser") >= 2) - context.debug (dump ("CLI2::prepareFilter findIDs")); + if (Context::getContext ().config.getInteger ("debug.parser") >= 2) + Context::getContext ().debug (dump ("CLI2::prepareFilter findIDs")); } //////////////////////////////////////////////////////////////////////////////// @@ -1587,7 +1597,7 @@ void CLI2::findUUIDs () { bool changes = false; - if (context.config.getBoolean ("sugar")) + if (Context::getContext ().config.getBoolean ("sugar")) { for (const auto& a : _args) { @@ -1639,8 +1649,8 @@ void CLI2::findUUIDs () } if (changes) - if (context.config.getInteger ("debug.parser") >= 2) - context.debug (dump ("CLI2::prepareFilter findUUIDs")); + if (Context::getContext ().config.getInteger ("debug.parser") >= 2) + Context::getContext ().debug (dump ("CLI2::prepareFilter findUUIDs")); } //////////////////////////////////////////////////////////////////////////////// @@ -1724,8 +1734,8 @@ void CLI2::insertIDExpr () else { bool ascending = true; - int low = strtol (r->first.c_str (), NULL, 10); - int high = strtol (r->second.c_str (), NULL, 10); + int low = strtol (r->first.c_str (), nullptr, 10); + int high = strtol (r->second.c_str (), nullptr, 10); if (low <= high) ascending = true; else @@ -1786,8 +1796,8 @@ void CLI2::insertIDExpr () { _args = reconstructed; - if (context.config.getInteger ("debug.parser") >= 2) - context.debug (dump ("CLI2::prepareFilter insertIDExpr")); + if (Context::getContext ().config.getInteger ("debug.parser") >= 2) + Context::getContext ().debug (dump ("CLI2::prepareFilter insertIDExpr")); } } @@ -1823,8 +1833,8 @@ void CLI2::lexFilterArgs () { _args = reconstructed; - if (context.config.getInteger ("debug.parser") >= 2) - context.debug (dump ("CLI2::prepareFilter lexFilterArgs")); + if (Context::getContext ().config.getInteger ("debug.parser") >= 2) + Context::getContext ().debug (dump ("CLI2::prepareFilter lexFilterArgs")); } } @@ -1930,8 +1940,8 @@ void CLI2::desugarFilterPlainArgs () { _args = reconstructed; - if (context.config.getInteger ("debug.parser") >= 2) - context.debug (dump ("CLI2::prepareFilter desugarFilterPlainArgs")); + if (Context::getContext ().config.getInteger ("debug.parser") >= 2) + Context::getContext ().debug (dump ("CLI2::prepareFilter desugarFilterPlainArgs")); } } @@ -1984,8 +1994,8 @@ void CLI2::insertJunctions () { _args = reconstructed; - if (context.config.getInteger ("debug.parser") >= 2) - context.debug (dump ("CLI2::prepareFilter insertJunctions")); + if (Context::getContext ().config.getInteger ("debug.parser") >= 2) + Context::getContext ().debug (dump ("CLI2::prepareFilter insertJunctions")); } } @@ -2025,7 +2035,7 @@ void CLI2::defaultCommand () if (! found_sequence) { // Apply overrides, if any. - std::string defaultCommand = context.config.get ("default.command"); + std::string defaultCommand = Context::getContext ().config.get ("default.command"); if (defaultCommand != "") { // Modify _args, _original_args to be: @@ -2068,8 +2078,8 @@ void CLI2::defaultCommand () } if (changes && - context.config.getInteger ("debug.parser") >= 2) - context.debug (dump ("CLI2::analyze defaultCommand")); + Context::getContext ().config.getInteger ("debug.parser") >= 2) + Context::getContext ().debug (dump ("CLI2::analyze defaultCommand")); } //////////////////////////////////////////////////////////////////////////////// @@ -2113,3 +2123,5 @@ std::vector CLI2::lexExpression (const std::string& expression) } //////////////////////////////////////////////////////////////////////////////// + +// vim: ts=2:sw=2 diff --git a/src/CLI2.h b/src/CLI2.h index db0029b45..23ecf8f31 100644 --- a/src/CLI2.h +++ b/src/CLI2.h @@ -1,6 +1,6 @@ //////////////////////////////////////////////////////////////////////////////// // -// Copyright 2006 - 2016, Paul Beckingham, Federico Hernandez. +// Copyright 2006 - 2020, 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 @@ -20,7 +20,7 @@ // 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 +// https://www.opensource.org/licenses/mit-license.php // //////////////////////////////////////////////////////////////////////////////// #ifndef INCLUDED_CLI2 diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 35c182b56..7346a7e05 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -1,55 +1,58 @@ -cmake_minimum_required (VERSION 2.8) +cmake_minimum_required (VERSION 3.0) include_directories (${CMAKE_SOURCE_DIR} ${CMAKE_SOURCE_DIR}/src ${CMAKE_SOURCE_DIR}/src/commands ${CMAKE_SOURCE_DIR}/src/columns + ${CMAKE_SOURCE_DIR}/src/libshared/src ${TASK_INCLUDE_DIRS}) -set (task_SRCS CLI2.cpp CLI2.h - Color.cpp Color.h - Config.cpp Config.h - Context.cpp Context.h - DOM.cpp DOM.h - Dates.cpp Dates.h - Eval.cpp Eval.h - Filter.cpp Filter.h - FS.cpp FS.h - Hooks.cpp Hooks.h - ISO8601.cpp ISO8601.h - JSON.cpp JSON.h - Lexer.cpp Lexer.h - Msg.cpp Msg.h - Nibbler.cpp Nibbler.h - RX.cpp RX.h - TDB2.cpp TDB2.h - Task.cpp Task.h - Timer.cpp Timer.h - TLSClient.cpp TLSClient.h - Variant.cpp Variant.h - ViewTask.cpp ViewTask.h - ViewText.cpp ViewText.h - dependency.cpp - feedback.cpp - i18n.h - interactive.cpp - legacy.cpp - recur.cpp - rules.cpp - sort.cpp - text.cpp text.h - utf8.cpp utf8.h - util.cpp util.h - wcwidth6.cpp) +add_library (task CLI2.cpp CLI2.h + Context.cpp Context.h + DOM.cpp DOM.h + Eval.cpp Eval.h + Filter.cpp Filter.h + Hooks.cpp Hooks.h + Lexer.cpp Lexer.h + TDB2.cpp TDB2.h + Task.cpp Task.h + TLSClient.cpp TLSClient.h + Variant.cpp Variant.h + ViewTask.cpp ViewTask.h + dependency.cpp + feedback.cpp + legacy.cpp + nag.cpp + recur.cpp + rules.cpp + sort.cpp + util.cpp util.h) + +add_library (libshared libshared/src/Color.cpp libshared/src/Color.h + libshared/src/Configuration.cpp libshared/src/Configuration.h + libshared/src/Datetime.cpp libshared/src/Datetime.h + libshared/src/Duration.cpp libshared/src/Duration.h + libshared/src/FS.cpp libshared/src/FS.h + libshared/src/JSON.cpp libshared/src/JSON.h + libshared/src/Msg.cpp libshared/src/Msg.h + libshared/src/Pig.cpp libshared/src/Pig.h + libshared/src/RX.cpp libshared/src/RX.h + libshared/src/Table.cpp libshared/src/Table.h + libshared/src/Timer.cpp libshared/src/Timer.h + libshared/src/format.cpp libshared/src/format.h + libshared/src/ip.cpp + libshared/src/shared.cpp libshared/src/shared.h + libshared/src/unicode.cpp libshared/src/unicode.h + libshared/src/utf8.cpp libshared/src/utf8.h + libshared/src/wcwidth6.cpp) -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}) +# Yes, 'task' (and hence libshared) is included twice, otherwise linking fails on assorted OSes. +target_link_libraries (task_executable task commands columns libshared task libshared ${TASK_LIBRARIES}) +target_link_libraries (calc_executable task commands columns libshared task libshared ${TASK_LIBRARIES}) +target_link_libraries (lex_executable task commands columns libshared task libshared ${TASK_LIBRARIES}) set_property (TARGET task_executable PROPERTY OUTPUT_NAME "task") diff --git a/src/Color.cpp b/src/Color.cpp deleted file mode 100644 index 05be8acd0..000000000 --- a/src/Color.cpp +++ /dev/null @@ -1,603 +0,0 @@ -//////////////////////////////////////////////////////////////////////////////// -// -// Copyright 2006 - 2016, 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 -#include -#include -#include -#include -#include -#include -#include -#include -#include - -// uint to string lookup table for Color::_colorize() -// _colorize() gets called _a lot_, having this lookup table is a cheap -// performance optimization. -const char *colorstring[] = { - "0", "1", "2", "3", "4", "5", "6", "7", "8", "9", - "10", "11", "12", "13", "14", "15", "16", "17", "18", "19", - "20", "21", "22", "23", "24", "25", "26", "27", "28", "29", - "30", "31", "32", "33", "34", "35", "36", "37", "38", "39", - "40", "41", "42", "43", "44", "45", "46", "47", "48", "49", - "50", "51", "52", "53", "54", "55", "56", "57", "58", "59", - "60", "61", "62", "63", "64", "65", "66", "67", "68", "69", - "70", "71", "72", "73", "74", "75", "76", "77", "78", "79", - "80", "81", "82", "83", "84", "85", "86", "87", "88", "89", - "90", "91", "92", "93", "94", "95", "96", "97", "98", "99", - "100", "101", "102", "103", "104", "105", "106", "107", "108", "109", - "110", "111", "112", "113", "114", "115", "116", "117", "118", "119", - "120", "121", "122", "123", "124", "125", "126", "127", "128", "129", - "130", "131", "132", "133", "134", "135", "136", "137", "138", "139", - "140", "141", "142", "143", "144", "145", "146", "147", "148", "149", - "150", "151", "152", "153", "154", "155", "156", "157", "158", "159", - "160", "161", "162", "163", "164", "165", "166", "167", "168", "169", - "170", "171", "172", "173", "174", "175", "176", "177", "178", "179", - "180", "181", "182", "183", "184", "185", "186", "187", "188", "189", - "190", "191", "192", "193", "194", "195", "196", "197", "198", "199", - "200", "201", "202", "203", "204", "205", "206", "207", "208", "209", - "210", "211", "212", "213", "214", "215", "216", "217", "218", "219", - "220", "221", "222", "223", "224", "225", "226", "227", "228", "229", - "230", "231", "232", "233", "234", "235", "236", "237", "238", "239", - "240", "241", "242", "243", "244", "245", "246", "247", "248", "249", - "250", "251", "252", "253", "254", "255" -}; - -//////////////////////////////////////////////////////////////////////////////// -static struct -{ - Color::color_id id; - std::string english_name; - int index; // offset red=3 (therefore fg=33, bg=43) -} allColors[] = -{ - // Color.h enum English Index - { Color::nocolor, "none", 0}, - { Color::black, "black", 1}, // fg 29+0 bg 39+0 - { Color::red, "red", 2}, - { Color::green, "green", 3}, - { Color::yellow, "yellow", 4}, - { Color::blue, "blue", 5}, - { Color::magenta, "magenta", 6}, - { Color::cyan, "cyan", 7}, - { Color::white, "white", 8}, - -}; - -#define NUM_COLORS (sizeof (allColors) / sizeof (allColors[0])) - -//////////////////////////////////////////////////////////////////////////////// -Color::Color () -: _value (0) -{ -} - -//////////////////////////////////////////////////////////////////////////////// -Color::Color (const Color& other) -{ - _value = other._value; -} - -//////////////////////////////////////////////////////////////////////////////// -Color::Color (unsigned int c) -: _value (0) -{ - if (!(c & _COLOR_HASFG)) _value &= ~_COLOR_FG; - if (!(c & _COLOR_HASBG)) _value &= ~_COLOR_BG; - - _value = c & (_COLOR_256 | _COLOR_HASBG | _COLOR_HASFG |_COLOR_UNDERLINE | - _COLOR_INVERSE | _COLOR_BOLD | _COLOR_BRIGHT | _COLOR_BG | - _COLOR_FG); -} - -//////////////////////////////////////////////////////////////////////////////// -// Supports the following constructs: -// [bright] [color] [on color] [bright] [underline] -// -// Where [color] is one of: -// black -// red -// ... -// grayN 0 <= N <= 23 fg 38;5;232 + N bg 48;5;232 + N -// greyN 0 <= N <= 23 fg 38;5;232 + N bg 48;5;232 + N -// colorN 0 <= N <= 255 fg 38;5;N bg 48;5;N -// rgbRGB 0 <= R,G,B <= 5 fg 38;5;16 + R*36 + G*6 + B bg 48;5;16 + R*36 + G*6 + B -Color::Color (const std::string& spec) -: _value (0) -{ - // Split spec into words. - std::vector words; - split (words, spec, ' '); - - // Construct the color as two separate colors, then blend them later. This - // make it possible to declare a color such as "color1 on black", and have - // the upgrade work properly. - unsigned int fg_value = 0; - unsigned int bg_value = 0; - - bool bg = false; - int index; - for (auto& word : words) - { - word = Lexer::lowerCase (Lexer::trim (word)); - - if (word == "bold") fg_value |= _COLOR_BOLD; - else if (word == "bright") bg_value |= _COLOR_BRIGHT; - else if (word == "underline") fg_value |= _COLOR_UNDERLINE; - else if (word == "inverse") fg_value |= _COLOR_INVERSE; - else if (word == "on") bg = true; - - // X where X is one of black, red, blue ... - else if ((index = find (word)) != -1) - { - if (index) - { - if (bg) - { - bg_value |= _COLOR_HASBG; - bg_value |= index << 8; - } - else - { - fg_value |= _COLOR_HASFG; - fg_value |= index; - } - } - } - - // greyN/grayN, where 0 <= N <= 23. - else if (! word.compare (0, 4, "grey", 4) || - ! word.compare (0, 4, "gray", 4)) - { - index = strtol (word.substr (4).c_str (), nullptr, 10); - if (index < 0 || index > 23) - throw format (STRING_COLOR_UNRECOGNIZED, word); - - if (bg) - { - bg_value |= _COLOR_HASBG; - bg_value |= (index + 232) << 8; - bg_value |= _COLOR_256; - } - else - { - fg_value |= _COLOR_HASFG; - fg_value |= index + 232; - fg_value |= _COLOR_256; - } - } - - // rgbRGB, where 0 <= R,G,B <= 5. - else if (! word.compare (0, 3, "rgb", 3)) - { - index = strtol (word.substr (3).c_str (), nullptr, 10); - if (word.length () != 6 || - index < 0 || index > 555) - throw format (STRING_COLOR_UNRECOGNIZED, word); - - int r = strtol (word.substr (3, 1).c_str (), nullptr, 10); - int g = strtol (word.substr (4, 1).c_str (), nullptr, 10); - int b = strtol (word.substr (5, 1).c_str (), nullptr, 10); - if (r < 0 || r > 5 || - g < 0 || g > 5 || - b < 0 || b > 5) - throw format (STRING_COLOR_UNRECOGNIZED, word); - - index = 16 + r*36 + g*6 + b; - - if (bg) - { - bg_value |= _COLOR_HASBG; - bg_value |= index << 8; - bg_value |= _COLOR_256; - } - else - { - fg_value |= _COLOR_HASFG; - fg_value |= index; - fg_value |= _COLOR_256; - } - } - - // colorN, where 0 <= N <= 255. - else if (! word.compare (0, 5, "color", 5)) - { - index = strtol (word.substr (5).c_str (), nullptr, 10); - if (index < 0 || index > 255) - throw format (STRING_COLOR_UNRECOGNIZED, word); - - upgrade (); - - if (bg) - { - bg_value |= _COLOR_HASBG; - bg_value |= index << 8; - bg_value |= _COLOR_256; - } - else - { - fg_value |= _COLOR_HASFG; - fg_value |= index; - fg_value |= _COLOR_256; - } - } - else if (word != "") - throw format (STRING_COLOR_UNRECOGNIZED, word); - } - - // Now combine the fg and bg into a single color. - _value = fg_value; - blend (Color (bg_value)); -} - -//////////////////////////////////////////////////////////////////////////////// -Color::Color (color_id fg) -: _value (0) -{ - if (fg != Color::nocolor) - { - _value |= _COLOR_HASFG; - _value |= fg; - } -} - -//////////////////////////////////////////////////////////////////////////////// -Color::Color (color_id fg, color_id bg, bool underline, bool bold, bool bright) -: _value (0) -{ - _value |= ((underline ? 1 : 0) << 18) - | ((bold ? 1 : 0) << 17) - | ((bright ? 1 : 0) << 16); - - if (bg != Color::nocolor) - { - _value |= _COLOR_HASBG; - _value |= (bg << 8); - } - - if (fg != Color::nocolor) - { - _value |= _COLOR_HASFG; - _value |= fg; - } -} - -//////////////////////////////////////////////////////////////////////////////// -Color::operator std::string () const -{ - std::string description; - if (_value & _COLOR_BOLD) description += "bold"; - - if (_value & _COLOR_UNDERLINE) - description += std::string (description.length () ? " " : "") + "underline"; - - if (_value & _COLOR_INVERSE) - description += std::string (description.length () ? " " : "") + "inverse"; - - if (_value & _COLOR_HASFG) - description += std::string (description.length () ? " " : "") + fg (); - - if (_value & _COLOR_HASBG) - { - description += std::string (description.length () ? " " : "") + "on"; - - if (_value & _COLOR_BRIGHT) - description += std::string (description.length () ? " " : "") + "bright"; - - description += " " + bg (); - } - - return description; -} - -//////////////////////////////////////////////////////////////////////////////// -Color::operator int () const -{ - return (int) _value; -} - -//////////////////////////////////////////////////////////////////////////////// -// If 'other' has styles that are compatible, merge them into this. Colors in -// other take precedence. -void Color::blend (const Color& other) -{ - if (!other.nontrivial ()) - return; - - Color c (other); - _value |= (c._value & _COLOR_UNDERLINE); // Always inherit underline. - _value |= (c._value & _COLOR_INVERSE); // Always inherit inverse. - - // 16 <-- 16. - if (!(_value & _COLOR_256) && - !(c._value & _COLOR_256)) - { - _value |= (c._value & _COLOR_BOLD); // Inherit bold. - _value |= (c._value & _COLOR_BRIGHT); // Inherit bright. - - if (c._value & _COLOR_HASFG) - { - _value |= _COLOR_HASFG; // There is now a color. - _value &= ~_COLOR_FG; // Remove previous color. - _value |= (c._value & _COLOR_FG); // Apply other color. - } - - if (c._value & _COLOR_HASBG) - { - _value |= _COLOR_HASBG; // There is now a color. - _value &= ~_COLOR_BG; // Remove previous color. - _value |= (c._value & _COLOR_BG); // Apply other color. - } - - return; - } - else - { - // Upgrade either color, if necessary. - if (!(_value & _COLOR_256)) upgrade (); - if (!(c._value & _COLOR_256)) c.upgrade (); - - // 256 <-- 256. - if (c._value & _COLOR_HASFG) - { - _value |= _COLOR_HASFG; // There is now a color. - _value &= ~_COLOR_FG; // Remove previous color. - _value |= (c._value & _COLOR_FG); // Apply other color. - } - - if (c._value & _COLOR_HASBG) - { - _value |= _COLOR_HASBG; // There is now a color. - _value &= ~_COLOR_BG; // Remove previous color. - _value |= (c._value & _COLOR_BG); // Apply other color. - } - } -} - -//////////////////////////////////////////////////////////////////////////////// -void Color::upgrade () -{ - if (!(_value & _COLOR_256)) - { - if (_value & _COLOR_HASFG) - { - bool bold = _value & _COLOR_BOLD; - unsigned int fg = _value & _COLOR_FG; - _value &= ~_COLOR_FG; - _value &= ~_COLOR_BOLD; - _value |= (bold ? fg + 7 : fg - 1); - } - - if (_value & _COLOR_HASBG) - { - bool bright = _value & _COLOR_BRIGHT; - unsigned int bg = (_value & _COLOR_BG) >> 8; - _value &= ~_COLOR_BG; - _value &= ~_COLOR_BRIGHT; - _value |= (bright ? bg + 7 : bg - 1) << 8; - } - - _value |= _COLOR_256; - } -} - -//////////////////////////////////////////////////////////////////////////////// -std::string Color::colorize (const std::string& input) const -{ - std::string result; - _colorize (result, input); - return result; -} - -//////////////////////////////////////////////////////////////////////////////// -// Sample color codes: -// red \033[31m -// bold red \033[91m -// underline red \033[4;31m -// bold underline red \033[1;4;31m -// -// on red \033[41m -// on bright red \033[101m -// -// 256 fg \033[38;5;Nm -// 256 bg \033[48;5;Nm -void Color::_colorize (std::string &result, const std::string& input) const -{ - if (!nontrivial ()) - { - result += input; - return; - } - - int count = 0; - - // 256 color - if (_value & _COLOR_256) - { - if (_value & _COLOR_UNDERLINE) - result += "\033[4m"; - - if (_value & _COLOR_INVERSE) - result += "\033[7m"; - - if (_value & _COLOR_HASFG) - { - result += "\033[38;5;"; - result += colorstring[(_value & _COLOR_FG)]; - result += "m"; - } - - if (_value & _COLOR_HASBG) - { - result += "\033[48;5;"; - result += colorstring[((_value & _COLOR_BG) >> 8)]; - result += "m"; - } - - result += input; - result += "\033[0m"; - } - - // 16 color - else - { - result += "\033["; - - if (_value & _COLOR_BOLD) - { - if (count++) result += ";"; - result += "1"; - } - - if (_value & _COLOR_UNDERLINE) - { - if (count++) result += ";"; - result += "4"; - } - - if (_value & _COLOR_INVERSE) - { - if (count++) result += ";"; - result += "7"; - } - - if (_value & _COLOR_HASFG) - { - if (count++) result += ";"; - result += colorstring[(29 + (_value & _COLOR_FG))]; - } - - if (_value & _COLOR_HASBG) - { - if (count++) result += ";"; - result += colorstring[((_value & _COLOR_BRIGHT ? 99 : 39) + ((_value & _COLOR_BG) >> 8))]; - } - - result += "m"; - result += input; - result += "\033[0m"; - } -} - -//////////////////////////////////////////////////////////////////////////////// -// Remove color codes from a string. -std::string Color::strip (const std::string& input) -{ - int length = input.length (); - bool inside = false; - std::string output; - for (int i = 0; i < length; ++i) - { - if (inside) - { - if (input[i] == 'm') - inside = false; - } - else - { - if (input[i] == 033) - inside = true; - else - output += input[i]; - } - } - - return output; -} - -//////////////////////////////////////////////////////////////////////////////// -std::string Color::colorize (const std::string& input, const std::string& spec) -{ - Color c (spec); - return c.colorize (input); -} - -//////////////////////////////////////////////////////////////////////////////// -bool Color::nontrivial () const -{ - return _value != 0 ? true : false; -} - -//////////////////////////////////////////////////////////////////////////////// -int Color::find (const std::string& input) -{ - for (unsigned int i = 0; i < NUM_COLORS; ++i) - if (allColors[i].english_name == input) - return (int) i; - - return -1; -} - -//////////////////////////////////////////////////////////////////////////////// -std::string Color::fg () const -{ - int index = _value & _COLOR_FG; - - if (_value & _COLOR_256) - { - if (_value & _COLOR_HASFG) - { - std::stringstream s; - s << "color" << (_value & _COLOR_FG); - return s.str (); - } - } - else - { - for (unsigned int i = 0; i < NUM_COLORS; ++i) - if (allColors[i].index == index) - return allColors[i].english_name; - } - - return ""; -} - -//////////////////////////////////////////////////////////////////////////////// -std::string Color::bg () const -{ - int index = (_value & _COLOR_BG) >> 8; - - if (_value & _COLOR_256) - { - if (_value & _COLOR_HASBG) - { - std::stringstream s; - s << "color" << ((_value & _COLOR_BG) >> 8); - return s.str (); - } - } - else - { - for (unsigned int i = 0; i < NUM_COLORS; ++i) - if (allColors[i].index == index) - return allColors[i].english_name; - } - - return ""; -} - -//////////////////////////////////////////////////////////////////////////////// diff --git a/src/Color.h b/src/Color.h deleted file mode 100644 index f998c40f6..000000000 --- a/src/Color.h +++ /dev/null @@ -1,75 +0,0 @@ -//////////////////////////////////////////////////////////////////////////////// -// -// Copyright 2006 - 2016, 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_COLOR -#define INCLUDED_COLOR - -#include - -#define _COLOR_INVERSE 0x00400000 // Inverse attribute. -#define _COLOR_256 0x00200000 // 256-color mode. -#define _COLOR_HASBG 0x00100000 // Has background color (all values taken). -#define _COLOR_HASFG 0x00080000 // Has foreground color (all values taken). -#define _COLOR_UNDERLINE 0x00040000 // General underline attribute. -#define _COLOR_BOLD 0x00020000 // 16-color bold attribute. -#define _COLOR_BRIGHT 0x00010000 // 16-color bright background attribute. -#define _COLOR_BG 0x0000FF00 // 8-bit background color index. -#define _COLOR_FG 0x000000FF // 8-bit foreground color index. - -class Color -{ -public: - enum color_id {nocolor = 0, black, red, green, yellow, blue, magenta, cyan, white}; - - Color (); - Color (const Color&); - Color (unsigned int); // 256 | INVERSE | UNDERLINE | BOLD | BRIGHT | (BG << 8) | FG - Color (const std::string&); // "red on bright black" - Color (color_id); // fg. - Color (color_id, color_id, bool, bool, bool); // fg, bg, underline, bold, bright - operator std::string () const; - operator int () const; - - void upgrade (); - void blend (const Color&); - - std::string colorize (const std::string&) const; - static std::string colorize (const std::string&, const std::string&); - void _colorize (std::string&, const std::string&) const; - static std::string strip (const std::string&); - - bool nontrivial () const; - -private: - int find (const std::string&); - std::string fg () const; - std::string bg () const; - -private: - unsigned int _value; -}; - -#endif diff --git a/src/Config.cpp b/src/Config.cpp deleted file mode 100644 index 92e9ff146..000000000 --- a/src/Config.cpp +++ /dev/null @@ -1,637 +0,0 @@ -//////////////////////////////////////////////////////////////////////////////// -// -// Copyright 2006 - 2016, 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 -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -//////////////////////////////////////////////////////////////////////////////// -// This string is used in two ways: -// 1) It is used to create a new .taskrc file, by copying it directly to disk. -// 2) It is parsed and used as default values for all Config.get calls. -std::string Config::_defaults = - "# Taskwarrior program configuration file.\n" - "# For more documentation, see http://taskwarrior.org or try 'man task', 'man task-color',\n" - "# 'man task-sync' or 'man taskrc'\n" - "\n" - "# Here is an example of entries that use the default, override and blank values\n" - "# variable=foo -- By specifying a value, this overrides the default\n" - "# variable= -- By specifying no value, this means no default\n" - "# #variable=foo -- By commenting out the line, or deleting it, this uses the default\n" - "\n" - "# Use the command 'task show' to see all defaults and overrides\n" - "\n" - "# Files\n" - "data.location=~/.task\n" - "locking=on # Use file-level locking\n" - "gc=on # Garbage-collect data files - DO NOT CHANGE unless you are sure\n" - "exit.on.missing.db=no # Whether to exit if ~/.task is not found\n" - "hooks=on # Master control switch for hooks\n" - "\n" - "# Terminal\n" - "detection=on # Detects terminal width\n" - "defaultwidth=80 # Without detection, assumed width\n" - "defaultheight=24 # Without detection, assumed height\n" - "avoidlastcolumn=no # Fixes Cygwin width problem\n" - "hyphenate=on # Hyphenates lines wrapped on non-word-breaks\n" - "#editor=vi # Preferred text editor\n" - "reserved.lines=1 # Assume a 1-line prompt\n" - "\n" - "# Miscellaneous\n" - "# # Comma-separated list. May contain any subset of:\n" - "verbose=blank,header,footnote,label,new-id,new-uuid,affected,edit,special,project,sync,unwait,recur\n" - "confirmation=yes # Confirmation on delete, big changes\n" - "recurrence=yes # Enable recurrence\n" - "recurrence.confirmation=prompt # Confirmation for propagating changes among recurring tasks (yes/no/prompt)\n" - "allow.empty.filter=yes # An empty filter gets a warning and requires confirmation\n" - "indent.annotation=2 # Indent spaces for annotations\n" - "indent.report=0 # Indent spaces for whole report\n" - "row.padding=0 # Left and right padding for each row of report\n" - "column.padding=1 # Spaces between each column in a report\n" - "bulk=3 # 3 or more tasks considered a bulk change and is confirmed\n" - "nag=You have more urgent tasks. # Nag message to keep you honest\n" // TODO - "search.case.sensitive=yes # Setting to no allows case insensitive searches\n" - "active.indicator=* # What to show as an active task indicator\n" - "tag.indicator=+ # What to show as a tag indicator\n" - "dependency.indicator=D # What to show as a dependency indicator\n" - "recurrence.indicator=R # What to show as a task recurrence indicator\n" - "recurrence.limit=1 # Number of future recurring pending tasks\n" - "undo.style=side # Undo style - can be 'side', or 'diff'\n" - "regex=yes # Assume all search/filter strings are regexes\n" - "xterm.title=no # Sets xterm title for some commands\n" - "expressions=infix # Prefer infix over postfix expressions\n" - "json.array=on # Enclose JSON output in [ ]\n" - "json.depends.array=off # Encode dependencies as a JSON array\n" - "abbreviation.minimum=2 # Shortest allowed abbreviation\n" - "\n" - "# Dates\n" - "dateformat=Y-M-D # Preferred input and display date format\n" - "dateformat.holiday=YMD # Preferred input date format for holidays\n" - "dateformat.edit=Y-M-D H:N:S # Preferred display date format when editing\n" - "dateformat.info=Y-M-D H:N:S # Preferred display date format for information\n" - "dateformat.report= # Preferred display date format for reports\n" - "dateformat.annotation= # Preferred display date format for annotations\n" - "date.iso=yes # Enable ISO date support\n" - "weekstart=" - STRING_DATE_SUNDAY - " # Sunday or Monday only\n" - "displayweeknumber=yes # Show week numbers on calendar\n" - "due=7 # Task is considered due in 7 days\n" - "\n" - "# Calendar controls\n" - "calendar.legend=yes # Display the legend on calendar\n" - "calendar.details=sparse # Calendar shows information for tasks w/due dates: full, sparse or none\n" - "calendar.details.report=list # Report to use when showing task information in cal\n" - "calendar.offset=no # Apply an offset value to control the first month of the calendar\n" - "calendar.offset.value=-1 # The number of months the first month of the calendar is moved\n" - "calendar.holidays=none # Show public holidays on calendar:full, sparse or none\n" - "#monthsperline=3 # Number of calendar months on a line\n" - "\n" - "# Journal controls\n" - "journal.time=no # Record start/stop commands as annotation\n" - "journal.time.start.annotation=Started task # Annotation description for the start journal entry\n" - "journal.time.stop.annotation=Stopped task # Annotation description for the stop journal entry\n" - "journal.info=on # Display task journal with info command\n" - "\n" - "# Dependency controls\n" - "dependency.reminder=on # Nags on dependency chain violations\n" - "dependency.confirmation=on # Should dependency chain repair be confirmed?\n" - "\n" - "# Urgency Coefficients\n" - "urgency.user.tag.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.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" - "urgency.annotations.coefficient=1.0 # Urgency coefficient for annotations\n" - "urgency.tags.coefficient=1.0 # Urgency coefficient for tags\n" - "urgency.project.coefficient=1.0 # Urgency coefficient for projects\n" - "urgency.blocked.coefficient=-5.0 # Urgency coefficient for blocked tasks\n" - "urgency.waiting.coefficient=-3.0 # Urgency coefficient for waiting status\n" - "urgency.inherit=off # Recursively inherit highest urgency value from blocked tasks\n" - "urgency.age.max=365 # Maximum age in days\n" - "\n" - "#urgency.user.project.foo.coefficient=5.0 # Urgency coefficients for 'foo' project\n" - "#urgency.user.tag.foo.coefficient=5.0 # Urgency coefficients for 'foo' tag\n" - "#urgency.uda.foo.coefficient=5.0 # Urgency coefficients for UDA 'foo'\n" - "\n" - "# Color controls.\n" - "color=on # Enable color\n" - "\n" - "rule.precedence.color=deleted,completed,active,keyword.,tag.,project.,overdue,scheduled,due.today,due,blocked,blocking,recurring,tagged,uda.\n" - "\n" - "# General decoration\n" - "rule.color.merge=yes\n" - "color.label=\n" - "color.label.sort=\n" - "color.alternate=on gray2\n" - "color.header=color3\n" - "color.footnote=color3\n" - "color.warning=bold red\n" - "color.error=white on red\n" - "color.debug=color4\n" - "\n" - "# Task state\n" - "color.completed=\n" - "color.deleted=\n" - "color.active=rgb555 on rgb410\n" - "color.recurring=rgb013\n" - "color.scheduled=on rgb001\n" - "color.until=\n" - "color.blocked=white on color8\n" - "color.blocking=black on color15\n" - "\n" - "# Project\n" - "color.project.none=\n" - "\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" - "color.tag.none=\n" - "color.tagged=rgb031\n" - "\n" - "# Due\n" - "color.due.today=rgb400\n" - "color.due=color1\n" - "color.overdue=color9\n" - "\n" - "# Report: burndown\n" - "color.burndown.done=on rgb010\n" - "color.burndown.pending=on color9\n" - "color.burndown.started=on color11\n" - "\n" - "# Report: history\n" - "color.history.add=color0 on rgb500\n" - "color.history.delete=color0 on rgb550\n" - "color.history.done=color0 on rgb050\n" - "\n" - "# Report: summary\n" - "color.summary.background=white on color0\n" - "color.summary.bar=black on rgb141\n" - "\n" - "# Command: calendar\n" - "color.calendar.due.today=color15 on color1\n" - "color.calendar.due=color0 on color1\n" - "color.calendar.holiday=color0 on color11\n" - "color.calendar.overdue=color0 on color9\n" - "color.calendar.today=color15 on rgb013\n" - "color.calendar.weekend=on color235\n" - "color.calendar.weeknumber=rgb013\n" - "\n" - "# Command: sync\n" - "color.sync.added=rgb010\n" - "color.sync.changed=color11\n" - "color.sync.rejected=color9\n" - "\n" - "# Command: undo\n" - "color.undo.after=color2\n" - "color.undo.before=color1\n" - "\n" - "# 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.,project.,overdue,scheduled,due.today,due,blocked,blocking,recurring,tagged,uda.\n" - "\n" - "#default.project=foo # Default project 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" - "sugar=yes # Syntactic sugar\n" - "obfuscate=no # Obfuscate data for error reporting\n" - "fontunderline=yes # Uses underlines rather than -------\n" - "\n" - "# WARNING: Please read the documentation (man task-sync) before setting up\n" - "# Taskwarrior for Taskserver synchronization.\n" - "#taskd.ca \n" - "#taskd.certificate \n" - "#taskd.credentials //\n" - "#taskd.server :\n" - "taskd.trust=strict\n" - "#taskd.trust=ignore hostname\n" - "#taskd.trust=allow all\n" - "taskd.ciphers=NORMAL\n" - "\n" - "# Aliases - alternate names for commands\n" - "alias.rm=delete # Alias for the delete command\n" - "alias.history=history.monthly # Prefer monthly over annual history reports\n" - "alias.ghistory=ghistory.monthly # Prefer monthly graphical over annual history reports\n" - "alias.burndown=burndown.weekly # Prefer the weekly burndown chart\n" - "alias.shell=exec tasksh # Alias old shell command to new shell\n" - "\n" - "# Reports\n" - "\n" - "report.long.description=All details of tasks\n" - "report.long.labels=ID,A,Created,Mod,Deps,P,Project,Tags,Recur,Wait,Sched,Due,Until,Description\n" - "report.long.columns=id,start.active,entry,modified.age,depends,priority,project,tags,recur,wait.remaining,scheduled,due,until,description\n" - "report.long.filter=status:pending\n" - "report.long.sort=modified-\n" - "\n" - "report.list.description=Most details of tasks\n" - "report.list.labels=ID,Active,Age,D,P,Project,Tags,R,Sch,Due,Until,Description,Urg\n" - "report.list.columns=id,start.age,entry.age,depends.indicator,priority,project,tags,recur.indicator,scheduled.countdown,due,until.remaining,description.count,urgency\n" - "report.list.filter=status:pending\n" - "report.list.sort=start-,due+,project+,urgency-\n" - "\n" - "report.ls.description=Few details of tasks\n" - "report.ls.labels=ID,A,D,Project,Tags,R,Wait,S,Due,Until,Description\n" - "report.ls.columns=id,start.active,depends.indicator,project,tags,recur.indicator,wait.remaining,scheduled.countdown,due.countdown,until.countdown,description.count\n" - "report.ls.filter=status:pending\n" - "report.ls.sort=start-,description+\n" - "\n" - "report.minimal.description=Minimal details of tasks\n" - "report.minimal.labels=ID,Project,Tags,Description\n" - "report.minimal.columns=id,project,tags.count,description.count\n" - "report.minimal.filter=status:pending or status:waiting\n" - "report.minimal.sort=project+/,description+\n" - "\n" - "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\n" - "report.newest.sort=entry-\n" - "\n" - "report.oldest.description=Oldest tasks\n" - "report.oldest.labels=ID,Active,Created,Age,Mod,D,P,Project,Tags,R,Wait,Sch,Due,Until,Description\n" - "report.oldest.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.oldest.filter=status:pending or status:waiting\n" - "report.oldest.sort=entry+\n" - "\n" - "report.overdue.description=Overdue tasks\n" - "report.overdue.labels=ID,Active,Age,Deps,P,Project,Tag,R,S,Due,Until,Description,Urg\n" - "report.overdue.columns=id,start.age,entry.age,depends,priority,project,tags,recur.indicator,scheduled.countdown,due,until,description,urgency\n" - "report.overdue.filter=(status:pending or status:waiting) and +OVERDUE\n" - "report.overdue.sort=urgency-,due+\n" - "\n" - "report.active.description=Active tasks\n" - "report.active.labels=ID,Started,Active,Age,D,P,Project,Tags,Recur,W,Sch,Due,Until,Description\n" - "report.active.columns=id,start,start.age,entry.age,depends.indicator,priority,project,tags,recur,wait,scheduled.remaining,due,until,description\n" - "report.active.filter=status:pending and +ACTIVE\n" - "report.active.sort=project+,start+\n" - "\n" - "report.completed.description=Completed tasks\n" - "report.completed.labels=ID,UUID,Created,Completed,Age,Deps,P,Project,Tags,R,Due,Description\n" - "report.completed.columns=id,uuid.short,entry,end,entry.age,depends,priority,project,tags,recur.indicator,due,description\n" - "report.completed.filter=status:completed\n" - "report.completed.sort=end+\n" - "\n" - "report.recurring.description=Recurring Tasks\n" - "report.recurring.labels=ID,Active,Age,D,P,Project,Tags,Recur,Sch,Due,Until,Description,Urg\n" - "report.recurring.columns=id,start.age,entry.age,depends.indicator,priority,project,tags,recur,scheduled.countdown,due,until.remaining,description,urgency\n" - "report.recurring.filter=(status:pending or status:waiting) and (+PARENT or +CHILD)\n" - "report.recurring.sort=due+,urgency-,entry+\n" - "\n" - "report.waiting.description=Waiting (hidden) tasks\n" - "report.waiting.labels=ID,A,Age,D,P,Project,Tags,R,Wait,Remaining,Sched,Due,Until,Description\n" - "report.waiting.columns=id,start.active,entry.age,depends.indicator,priority,project,tags,recur.indicator,wait,wait.remaining,scheduled,due,until,description\n" - "report.waiting.filter=+WAITING\n" - "report.waiting.sort=due+,wait+,entry+\n" - "\n" - "report.all.description=All tasks\n" - "report.all.labels=ID,St,UUID,A,Age,Done,D,P,Project,Tags,R,Wait,Sch,Due,Until,Description\n" - "report.all.columns=id,status.short,uuid.short,start.active,entry.age,end.age,depends.indicator,priority,project.parent,tags.count,recur.indicator,wait.remaining,scheduled.remaining,due,until.remaining,description\n" - "report.all.sort=entry-\n" - "\n" - "report.next.description=Most urgent tasks\n" - "report.next.labels=ID,Active,Age,Deps,P,Project,Tag,Recur,S,Due,Until,Description,Urg\n" - "report.next.columns=id,start.age,entry.age,depends,priority,project,tags,recur,scheduled.countdown,due.relative,until.remaining,description,urgency\n" - "report.next.filter=status:pending limit:page\n" - "report.next.sort=urgency-\n" - "\n" - "report.ready.description=Most urgent actionable tasks\n" - "report.ready.labels=ID,Active,Age,D,P,Project,Tags,R,S,Due,Until,Description,Urg\n" - "report.ready.columns=id,start.age,entry.age,depends.indicator,priority,project,tags,recur.indicator,scheduled.countdown,due.countdown,until.remaining,description,urgency\n" - "report.ready.filter=+READY\n" - "report.ready.sort=start-,urgency-\n" - "\n" - "report.blocked.description=Blocked tasks\n" - "report.blocked.columns=id,depends,project,priority,due,start.active,entry.age,description\n" - "report.blocked.labels=ID,Deps,Proj,Pri,Due,Active,Age,Description\n" - "report.blocked.sort=due+,priority-,start-,project+\n" - "report.blocked.filter=status:pending +BLOCKED\n" - "\n" - "report.unblocked.description=Unblocked tasks\n" - "report.unblocked.columns=id,depends,project,priority,due,start.active,entry.age,description\n" - "report.unblocked.labels=ID,Deps,Proj,Pri,Due,Active,Age,Description\n" - "report.unblocked.sort=due+,priority-,start-,project+\n" - "report.unblocked.filter=status:pending -BLOCKED\n" - "\n" - "report.blocking.description=Blocking tasks\n" - "report.blocking.labels=ID,UUID,A,Deps,Project,Tags,R,W,Sch,Due,Until,Description,Urg\n" - "report.blocking.columns=id,uuid.short,start.active,depends,project,tags,recur,wait,scheduled.remaining,due.relative,until.remaining,description.count,urgency\n" - "report.blocking.sort=urgency-,due+,entry+\n" - "report.blocking.filter= status:pending +BLOCKING\n" - "\n"; - -//////////////////////////////////////////////////////////////////////////////// -// DO NOT CALL Config::setDefaults. -// -// This is a default constructor, and as such is only used to: -// a) initialize a default Context constructor -// b) run unit tests -// -// In all real use cases, Config::load is called. -Config::Config () -: _original_file () -{ -} - -//////////////////////////////////////////////////////////////////////////////// -// Read the Configuration file and populate the *this map. The file format is -// simply lines with name=value pairs. Whitespace between name, = and value is -// not tolerated, but blank lines and comments starting with # are allowed. -// -// Nested files are now supported, with the following construct: -// include /absolute/path/to/file -// -void Config::load (const std::string& file, int nest /* = 1 */) -{ - Timer timer ("Config::load (" + file + ")"); - - if (nest > 10) - throw std::string (STRING_CONFIG_OVERNEST); - - // First time in, load the default values. - if (nest == 1) - { - setDefaults (); - _original_file = File (file); - } - - // Read the file, then parse the contents. - std::string contents; - if (File::read (file, contents) && contents.length ()) - parse (contents, nest); -} - -//////////////////////////////////////////////////////////////////////////////// -void Config::parse (const std::string& input, int nest /* = 1 */) -{ - // Shortcut case for default constructor. - if (input.length () == 0) - return; - - // Split the input into lines. - std::vector lines; - split (lines, input, "\n"); - - // Parse each line. - for (auto& line : lines) - { - // Remove comments. - auto pound = line.find ("#"); // no i18n - if (pound != std::string::npos) - line = line.substr (0, pound); - - line = Lexer::trim (line, " \t"); // no i18n - - // Skip empty lines. - if (line.length () > 0) - { - auto equal = line.find ("="); // no i18n - if (equal != std::string::npos) - { - std::string key = Lexer::trim (line.substr (0, equal), " \t"); // no i18n - std::string value = Lexer::trim (line.substr (equal+1, line.length () - equal), " \t"); // no i18n - - (*this)[key] = json::decode (value); - } - else - { - auto include = line.find ("include"); // no i18n. - if (include != std::string::npos) - { - Path included (Lexer::trim (line.substr (include + 7), " \t")); - if (included.is_absolute ()) - { - if (included.readable ()) - this->load (included, nest + 1); - else - throw format (STRING_CONFIG_READ_INCLUDE, included._data); - } - else - throw format (STRING_CONFIG_INCLUDE_PATH, included._data); - } - else - throw format (STRING_CONFIG_BAD_ENTRY, line); - } - } - } -} - -//////////////////////////////////////////////////////////////////////////////// -void Config::createDefaultRC (const std::string& rc, const std::string& data) -{ - // Override data.location in the defaults. - auto loc = _defaults.find ("data.location=~/.task"); - // loc+0^ +14^ +21^ - - ISO8601d now; - std::stringstream contents; - contents << "# [Created by " - << PACKAGE_STRING - << " " - << now.toString ("m/d/Y H:N:S") - << "]\n" - << _defaults.substr (0, loc + 14) - << data - << "\n\n# Color theme (uncomment one to use)\n" - << "#include " << TASK_RCDIR << "/light-16.theme\n" - << "#include " << TASK_RCDIR << "/light-256.theme\n" - << "#include " << TASK_RCDIR << "/dark-16.theme\n" - << "#include " << TASK_RCDIR << "/dark-256.theme\n" - << "#include " << TASK_RCDIR << "/dark-red-256.theme\n" - << "#include " << TASK_RCDIR << "/dark-green-256.theme\n" - << "#include " << TASK_RCDIR << "/dark-blue-256.theme\n" - << "#include " << TASK_RCDIR << "/dark-violets-256.theme\n" - << "#include " << TASK_RCDIR << "/dark-yellow-green.theme\n" - << "#include " << TASK_RCDIR << "/dark-gray-256.theme\n" - << "#include " << TASK_RCDIR << "/dark-gray-blue-256.theme\n" - << "#include " << TASK_RCDIR << "/solarized-dark-256.theme\n" - << "#include " << TASK_RCDIR << "/solarized-light-256.theme\n" - << "#include " << TASK_RCDIR << "/no-color.theme\n" - << "\n"; - - // Write out the new file. - if (! File::write (rc, contents.str ())) - throw format (STRING_CONFIG_BAD_WRITE, rc); -} - -//////////////////////////////////////////////////////////////////////////////// -void Config::createDefaultData (const std::string& data) -{ - Directory d (data); - if (! d.exists ()) - { - if (getBoolean ("exit.on.missing.db")) - throw std::string ("Error: rc.data.location does not exist - exiting according to rc.exit.on.missing.db setting."); - - d.create (); - - d += "hooks"; - d.create (); - } -} - -//////////////////////////////////////////////////////////////////////////////// -void Config::setDefaults () -{ - parse (_defaults); -} - -//////////////////////////////////////////////////////////////////////////////// -void Config::clear () -{ - std::map ::clear (); -} - -//////////////////////////////////////////////////////////////////////////////// -bool Config::has (const std::string& key) -{ - return (*this).find (key) != (*this).end (); -} - -//////////////////////////////////////////////////////////////////////////////// -// Return the configuration value given the specified key. -std::string Config::get (const std::string& key) -{ - auto found = find (key); - if (found != end ()) - return found->second; - - return ""; -} - -//////////////////////////////////////////////////////////////////////////////// -int Config::getInteger (const std::string& key) -{ - auto found = find (key); - if (found != end ()) - return strtoimax (found->second.c_str (), nullptr, 10); - - return 0; -} - -//////////////////////////////////////////////////////////////////////////////// -double Config::getReal (const std::string& key) -{ - //NOTE: Backwards compatible handling of next coefficient. - //TODO: Remove. - if (key == "urgency.user.tag.next.coefficient" and has ("urgency.next.coefficient")) - return getReal ("urgency.next.coefficient"); - - auto found = find (key); - if (found != end ()) - return strtod (found->second.c_str (), nullptr); - - return 0.0; -} - -//////////////////////////////////////////////////////////////////////////////// -bool Config::getBoolean (const std::string& key) -{ - auto found = find (key); - if (found != end ()) - { - std::string value = Lexer::lowerCase ((*this)[key]); - if (value == "t" || // TODO Deprecate - value == "true" || - value == "1" || - value == "+" || // TODO Deprecate - value == "y" || - value == "yes" || - value == "on" || - value == "enable" || // TODO Deprecate - value == "enabled") // TODO Deprecate - return true; - } - - return false; -} - -//////////////////////////////////////////////////////////////////////////////// -void Config::set (const std::string& key, const int value) -{ - (*this)[key] = format (value); -} - -//////////////////////////////////////////////////////////////////////////////// -void Config::set (const std::string& key, const double value) -{ - (*this)[key] = format (value, 1, 8); -} - -//////////////////////////////////////////////////////////////////////////////// -void Config::set (const std::string& key, const std::string& value) -{ - (*this)[key] = value; -} - -//////////////////////////////////////////////////////////////////////////////// -// Provide a vector of all configuration keys. -void Config::all (std::vector& items) const -{ - for (auto& it : *this) - items.push_back (it.first); -} - -//////////////////////////////////////////////////////////////////////////////// diff --git a/src/Config.h b/src/Config.h deleted file mode 100644 index a3a49dc54..000000000 --- a/src/Config.h +++ /dev/null @@ -1,70 +0,0 @@ -//////////////////////////////////////////////////////////////////////////////// -// -// Copyright 2006 - 2016, 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_CONFIG -#define INCLUDED_CONFIG - -#include -#include -#include -#include - -class Config : public std::map -{ -public: - Config (); - Config (const Config&); - Config& operator= (const Config&); - - void load (const std::string&, int nest = 1); - void parse (const std::string&, int nest = 1); - - void createDefaultRC (const std::string&, const std::string&); - void createDefaultData (const std::string&); - void setDefaults (); - void clear (); - - bool has (const std::string&); - std::string get (const std::string&); - int getInteger (const std::string&); - double getReal (const std::string&); - bool getBoolean (const std::string&); - - void set (const std::string&, const int); - void set (const std::string&, const double); - void set (const std::string&, const std::string&); - void all (std::vector &) const; - -public: - File _original_file; - -private: - static std::string _defaults; -}; - -#endif - -//////////////////////////////////////////////////////////////////////////////// diff --git a/src/Context.cpp b/src/Context.cpp index c1195be8c..b3f179242 100644 --- a/src/Context.cpp +++ b/src/Context.cpp @@ -1,6 +1,6 @@ //////////////////////////////////////////////////////////////////////////////// // -// Copyright 2006 - 2016, Paul Beckingham, Federico Hernandez. +// Copyright 2006 - 2020, 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 @@ -20,7 +20,7 @@ // 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 +// https://www.opensource.org/licenses/mit-license.php // //////////////////////////////////////////////////////////////////////////////// @@ -29,6 +29,7 @@ #include #include #include +#include #include #include #include @@ -37,15 +38,361 @@ #include #include #include -#include -#include -#include +#include +#include +#include +#include #include -#include + #ifdef HAVE_COMMIT #include #endif +#include +#include + +#ifdef SOLARIS +#include +#endif + +//////////////////////////////////////////////////////////////////////////////// +// This string is parsed and used as default values for configuration. +std::string configurationDefaults = + "# Taskwarrior program configuration file.\n" + "# For more documentation, see http://taskwarrior.org or try 'man task', 'man task-color',\n" + "# 'man task-sync' or 'man taskrc'\n" + "\n" + "# Here is an example of entries that use the default, override and blank values\n" + "# variable=foo -- By specifying a value, this overrides the default\n" + "# variable= -- By specifying no value, this means no default\n" + "# #variable=foo -- By commenting out the line, or deleting it, this uses the default\n" + "\n" + "# Use the command 'task show' to see all defaults and overrides\n" + "\n" + "# Files\n" + "data.location=~/.task\n" + "locking=1 # Use file-level locking\n" + "gc=1 # Garbage-collect data files - DO NOT CHANGE unless you are sure\n" + "exit.on.missing.db=0 # Whether to exit if ~/.task is not found\n" + "hooks=1 # Master control switch for hooks\n" + "\n" + "# Terminal\n" + "detection=1 # Detects terminal width\n" + "defaultwidth=80 # Without detection, assumed width\n" + "defaultheight=24 # Without detection, assumed height\n" + "avoidlastcolumn=0 # Fixes Cygwin width problem\n" + "hyphenate=1 # Hyphenates lines wrapped on non-word-breaks\n" + "#editor=vi # Preferred text editor\n" + "reserved.lines=1 # Assume a 1-line prompt\n" + "\n" + "# Miscellaneous\n" + "# # Comma-separated list. May contain any subset of:\n" + "verbose=blank,header,footnote,label,new-id,affected,edit,special,project,sync,unwait,override,recur\n" + "confirmation=1 # Confirmation on delete, big changes\n" + "recurrence=1 # Enable recurrence\n" + "recurrence.confirmation=prompt # Confirmation for propagating changes among recurring tasks (yes/no/prompt)\n" + "allow.empty.filter=1 # An empty filter gets a warning and requires confirmation\n" + "indent.annotation=2 # Indent spaces for annotations\n" + "indent.report=0 # Indent spaces for whole report\n" + "row.padding=0 # Left and right padding for each row of report\n" + "column.padding=1 # Spaces between each column in a report\n" + "bulk=3 # 3 or more tasks considered a bulk change and is confirmed\n" + "nag=You have more urgent tasks. # Nag message to keep you honest\n" // TODO + "search.case.sensitive=1 # Setting to no allows case insensitive searches\n" + "active.indicator=* # What to show as an active task indicator\n" + "tag.indicator=+ # What to show as a tag indicator\n" + "dependency.indicator=D # What to show as a dependency indicator\n" + "recurrence.indicator=R # What to show as a task recurrence indicator\n" + "recurrence.limit=1 # Number of future recurring pending tasks\n" + "undo.style=side # Undo style - can be 'side', or 'diff'\n" + "regex=1 # Assume all search/filter strings are regexes\n" + "xterm.title=0 # Sets xterm title for some commands\n" + "expressions=infix # Prefer infix over postfix expressions\n" + "json.array=1 # Enclose JSON output in [ ]\n" + "json.depends.array=0 # Encode dependencies as a JSON array\n" + "abbreviation.minimum=2 # Shortest allowed abbreviation\n" + "\n" + "# Dates\n" + "dateformat=Y-M-D # Preferred input and display date format\n" + "dateformat.holiday=YMD # Preferred input date format for holidays\n" + "dateformat.edit=Y-M-D H:N:S # Preferred display date format when editing\n" + "dateformat.info=Y-M-D H:N:S # Preferred display date format for information\n" + "dateformat.report= # Preferred display date format for reports\n" + "dateformat.annotation= # Preferred display date format for annotations\n" + "date.iso=1 # Enable ISO date support\n" + "weekstart=sunday # Sunday or Monday only\n" + "displayweeknumber=1 # Show week numbers on calendar\n" + "due=7 # Task is considered due in 7 days\n" + "\n" + "# Calendar controls\n" + "calendar.legend=1 # Display the legend on calendar\n" + "calendar.details=sparse # Calendar shows information for tasks w/due dates: full, sparse or none\n" + "calendar.details.report=list # Report to use when showing task information in cal\n" + "calendar.offset=0 # Apply an offset value to control the first month of the calendar\n" + "calendar.offset.value=-1 # The number of months the first month of the calendar is moved\n" + "calendar.holidays=none # Show public holidays on calendar:full, sparse or none\n" + "#monthsperline=3 # Number of calendar months on a line\n" + "\n" + "# Journal controls\n" + "journal.time=0 # Record start/stop commands as annotation\n" + "journal.time.start.annotation=Started task # Annotation description for the start journal entry\n" + "journal.time.stop.annotation=Stopped task # Annotation description for the stop journal entry\n" + "journal.info=1 # Display task journal with info command\n" + "\n" + "# Dependency controls\n" + "dependency.reminder=1 # Nags on dependency chain violations\n" + "dependency.confirmation=1 # Should dependency chain repair be confirmed?\n" + "\n" + "# Urgency Coefficients\n" + "urgency.user.tag.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.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" + "urgency.annotations.coefficient=1.0 # Urgency coefficient for annotations\n" + "urgency.tags.coefficient=1.0 # Urgency coefficient for tags\n" + "urgency.project.coefficient=1.0 # Urgency coefficient for projects\n" + "urgency.blocked.coefficient=-5.0 # Urgency coefficient for blocked tasks\n" + "urgency.waiting.coefficient=-3.0 # Urgency coefficient for waiting status\n" + "urgency.inherit=0 # Recursively inherit highest urgency value from blocked tasks\n" + "urgency.age.max=365 # Maximum age in days\n" + "\n" + "#urgency.user.project.foo.coefficient=5.0 # Urgency coefficients for 'foo' project\n" + "#urgency.user.tag.foo.coefficient=5.0 # Urgency coefficients for 'foo' tag\n" + "#urgency.uda.foo.coefficient=5.0 # Urgency coefficients for UDA 'foo'\n" + "\n" + "# Color controls.\n" + "color=1 # Enable color\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.,project.,overdue,scheduled,due.today,due,blocked,blocking,recurring,tagged,uda.\n" + "\n" + "# General decoration\n" + "rule.color.merge=1\n" + "color.label=\n" + "color.label.sort=\n" + "color.alternate=on gray2\n" + "color.header=color3\n" + "color.footnote=color3\n" + "color.warning=bold red\n" + "color.error=white on red\n" + "color.debug=color4\n" + "\n" + "# Task state\n" + "color.completed=\n" + "color.deleted=\n" + "color.active=rgb555 on rgb410\n" + "color.recurring=rgb013\n" + "color.scheduled=on rgb001\n" + "color.until=\n" + "color.blocked=white on color8\n" + "color.blocking=black on color15\n" + "\n" + "# Project\n" + "color.project.none=\n" + "\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" + "color.tag.none=\n" + "color.tagged=rgb031\n" + "\n" + "# Due\n" + "color.due.today=rgb400\n" + "color.due=color1\n" + "color.overdue=color9\n" + "\n" + "# Report: burndown\n" + "color.burndown.done=on rgb010\n" + "color.burndown.pending=on color9\n" + "color.burndown.started=on color11\n" + "\n" + "# Report: history\n" + "color.history.add=color0 on rgb500\n" + "color.history.delete=color0 on rgb550\n" + "color.history.done=color0 on rgb050\n" + "\n" + "# Report: summary\n" + "color.summary.background=white on color0\n" + "color.summary.bar=black on rgb141\n" + "\n" + "# Command: calendar\n" + "color.calendar.due.today=color15 on color1\n" + "color.calendar.due=color0 on color1\n" + "color.calendar.holiday=color0 on color11\n" + "color.calendar.overdue=color0 on color9\n" + "color.calendar.today=color15 on rgb013\n" + "color.calendar.weekend=on color235\n" + "color.calendar.weeknumber=rgb013\n" + "\n" + "# Command: sync\n" + "color.sync.added=rgb010\n" + "color.sync.changed=color11\n" + "color.sync.rejected=color9\n" + "\n" + "# Command: undo\n" + "color.undo.after=color2\n" + "color.undo.before=color1\n" + "\n" + "# 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" + "#default.project=foo # Default project for 'add' command\n" + "#default.due=eom # Default due date for 'add' command\n" + "#default.scheduled=eom # Default scheduled date for 'add' command\n" + "default.command=next # When no arguments are specified\n" + "default.timesheet.filter=( +PENDING and start.after:now-4wks ) or ( +COMPLETED and end.after:now-4wks )\n" + "\n" + "_forcecolor=0 # Forces color to be on, even for non TTY output\n" + "complete.all.tags=0 # Include old tag names in '_ags' command\n" + "list.all.projects=0 # Include old project names in 'projects' command\n" + "summary.all.projects=0 # Include old project names in 'summary' command\n" + "list.all.tags=0 # Include old tag names in 'tags' command\n" + "print.empty.columns=0 # Print columns which have no data for any task\n" + "debug=0 # Display diagnostics\n" + "debug.tls=0 # Sync diagnostics\n" + "sugar=1 # Syntactic sugar\n" + "obfuscate=0 # Obfuscate data for error reporting\n" + "fontunderline=1 # Uses underlines rather than -------\n" + "\n" + "# WARNING: Please read the documentation (man task-sync) before setting up\n" + "# Taskwarrior for Taskserver synchronization.\n" + "#taskd.ca=\n" + "#taskd.certificate=\n" + "#taskd.credentials=//\n" + "#taskd.server=:\n" + "taskd.trust=strict\n" + "#taskd.trust=ignore hostname\n" + "#taskd.trust=allow all\n" + "taskd.ciphers=NORMAL\n" + "\n" + "# Aliases - alternate names for commands\n" + "alias.rm=delete # Alias for the delete command\n" + "alias.history=history.monthly # Prefer monthly over annual history reports\n" + "alias.ghistory=ghistory.monthly # Prefer monthly graphical over annual history reports\n" + "alias.burndown=burndown.weekly # Prefer the weekly burndown chart\n" + "alias.shell=exec tasksh # Alias old shell command to new shell\n" + "\n" + "# Reports\n" + "\n" + "report.long.description=All details of tasks\n" + "report.long.labels=ID,A,Created,Mod,Deps,P,Project,Tags,Recur,Wait,Sched,Due,Until,Description\n" + "report.long.columns=id,start.active,entry,modified.age,depends,priority,project,tags,recur,wait.remaining,scheduled,due,until,description\n" + "report.long.filter=status:pending\n" + "report.long.sort=modified-\n" + "\n" + "report.list.description=Most details of tasks\n" + "report.list.labels=ID,Active,Age,D,P,Project,Tags,R,Sch,Due,Until,Description,Urg\n" + "report.list.columns=id,start.age,entry.age,depends.indicator,priority,project,tags,recur.indicator,scheduled.countdown,due,until.remaining,description.count,urgency\n" + "report.list.filter=status:pending\n" + "report.list.sort=start-,due+,project+,urgency-\n" + "\n" + "report.ls.description=Few details of tasks\n" + "report.ls.labels=ID,A,D,Project,Tags,R,Wait,S,Due,Until,Description\n" + "report.ls.columns=id,start.active,depends.indicator,project,tags,recur.indicator,wait.remaining,scheduled.countdown,due.countdown,until.countdown,description.count\n" + "report.ls.filter=status:pending\n" + "report.ls.sort=start-,description+\n" + "\n" + "report.minimal.description=Minimal details of tasks\n" + "report.minimal.labels=ID,Project,Tags,Description\n" + "report.minimal.columns=id,project,tags.count,description.count\n" + "report.minimal.filter=status:pending or status:waiting\n" + "report.minimal.sort=project+/,description+\n" + "\n" + "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\n" + "report.newest.sort=entry-\n" + "\n" + "report.oldest.description=Oldest tasks\n" + "report.oldest.labels=ID,Active,Created,Age,Mod,D,P,Project,Tags,R,Wait,Sch,Due,Until,Description\n" + "report.oldest.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.oldest.filter=status:pending or status:waiting\n" + "report.oldest.sort=entry+\n" + "\n" + "report.overdue.description=Overdue tasks\n" + "report.overdue.labels=ID,Active,Age,Deps,P,Project,Tag,R,S,Due,Until,Description,Urg\n" + "report.overdue.columns=id,start.age,entry.age,depends,priority,project,tags,recur.indicator,scheduled.countdown,due,until,description,urgency\n" + "report.overdue.filter=(status:pending or status:waiting) and +OVERDUE\n" + "report.overdue.sort=urgency-,due+\n" + "\n" + "report.active.description=Active tasks\n" + "report.active.labels=ID,Started,Active,Age,D,P,Project,Tags,Recur,W,Sch,Due,Until,Description\n" + "report.active.columns=id,start,start.age,entry.age,depends.indicator,priority,project,tags,recur,wait,scheduled.remaining,due,until,description\n" + "report.active.filter=status:pending and +ACTIVE\n" + "report.active.sort=project+,start+\n" + "\n" + "report.completed.description=Completed tasks\n" + "report.completed.labels=ID,UUID,Created,Completed,Age,Deps,P,Project,Tags,R,Due,Description\n" + "report.completed.columns=id,uuid.short,entry,end,entry.age,depends,priority,project,tags,recur.indicator,due,description\n" + "report.completed.filter=status:completed\n" + "report.completed.sort=end+\n" + "\n" + "report.recurring.description=Recurring Tasks\n" + "report.recurring.labels=ID,Active,Age,D,P,Project,Tags,Recur,Sch,Due,Until,Description,Urg\n" + "report.recurring.columns=id,start.age,entry.age,depends.indicator,priority,project,tags,recur,scheduled.countdown,due,until.remaining,description,urgency\n" + "report.recurring.filter=(status:pending or status:waiting) and (+PARENT or +CHILD)\n" + "report.recurring.sort=due+,urgency-,entry+\n" + "\n" + "report.waiting.description=Waiting (hidden) tasks\n" + "report.waiting.labels=ID,A,Age,D,P,Project,Tags,R,Wait,Remaining,Sched,Due,Until,Description\n" + "report.waiting.columns=id,start.active,entry.age,depends.indicator,priority,project,tags,recur.indicator,wait,wait.remaining,scheduled,due,until,description\n" + "report.waiting.filter=+WAITING\n" + "report.waiting.sort=due+,wait+,entry+\n" + "\n" + "report.all.description=All tasks\n" + "report.all.labels=ID,St,UUID,A,Age,Done,D,P,Project,Tags,R,Wait,Sch,Due,Until,Description\n" + "report.all.columns=id,status.short,uuid.short,start.active,entry.age,end.age,depends.indicator,priority,project.parent,tags.count,recur.indicator,wait.remaining,scheduled.remaining,due,until.remaining,description\n" + "report.all.sort=entry-\n" + "\n" + "report.next.description=Most urgent tasks\n" + "report.next.labels=ID,Active,Age,Deps,P,Project,Tag,Recur,S,Due,Until,Description,Urg\n" + "report.next.columns=id,start.age,entry.age,depends,priority,project,tags,recur,scheduled.countdown,due.relative,until.remaining,description,urgency\n" + "report.next.filter=status:pending limit:page\n" + "report.next.sort=urgency-\n" + "\n" + "report.ready.description=Most urgent actionable tasks\n" + "report.ready.labels=ID,Active,Age,D,P,Project,Tags,R,S,Due,Until,Description,Urg\n" + "report.ready.columns=id,start.age,entry.age,depends.indicator,priority,project,tags,recur.indicator,scheduled.countdown,due.countdown,until.remaining,description,urgency\n" + "report.ready.filter=+READY\n" + "report.ready.sort=start-,urgency-\n" + "\n" + "report.blocked.description=Blocked tasks\n" + "report.blocked.columns=id,depends,project,priority,due,start.active,entry.age,description\n" + "report.blocked.labels=ID,Deps,Proj,Pri,Due,Active,Age,Description\n" + "report.blocked.sort=due+,priority-,start-,project+\n" + "report.blocked.filter=status:pending +BLOCKED\n" + "\n" + "report.unblocked.description=Unblocked tasks\n" + "report.unblocked.columns=id,depends,project,priority,due,start.active,entry.age,description\n" + "report.unblocked.labels=ID,Deps,Proj,Pri,Due,Active,Age,Description\n" + "report.unblocked.sort=due+,priority-,start-,project+\n" + "report.unblocked.filter=status:pending -BLOCKED\n" + "\n" + "report.blocking.description=Blocking tasks\n" + "report.blocking.labels=ID,UUID,A,Deps,Project,Tags,R,W,Sch,Due,Until,Description,Urg\n" + "report.blocking.columns=id,uuid.short,start.active,depends,project,tags,recur,wait,scheduled.remaining,due.relative,until.remaining,description.count,urgency\n" + "report.blocking.sort=urgency-,due+,entry+\n" + "report.blocking.filter=status:pending +BLOCKING\n" + "\n" + "report.timesheet.filter=(+PENDING and start.after:now-4wks) or (+COMPLETED and end.after:now-4wks)\n" + "\n"; + // Supported modifiers, synonyms on the same line. static const char* modifierNames[] = { @@ -65,19 +412,18 @@ static const char* modifierNames[] = #define NUM_MODIFIER_NAMES (sizeof (modifierNames) / sizeof (modifierNames[0])) +Context* Context::context; + //////////////////////////////////////////////////////////////////////////////// -Context::Context () -: rc_file ("~/.taskrc") -, data_dir ("~/.task") -, config () -, tdb2 () -, determine_color_use (true) -, use_color (true) -, run_gc (true) -, verbosity_legacy (false) -, terminal_width (0) -, terminal_height (0) +Context& Context::getContext () { + return *Context::context; +} + +//////////////////////////////////////////////////////////////////////////////// +void Context::setContext (Context* context) +{ + Context::context = context; } //////////////////////////////////////////////////////////////////////////////// @@ -94,7 +440,6 @@ Context::~Context () int Context::initialize (int argc, const char** argv) { timer_total.start (); - timer_init.start (); int rc = 0; try @@ -116,11 +461,17 @@ int Context::initialize (int argc, const char** argv) if (override) { rc_file = File (override); - header (format (STRING_CONTEXT_RC_OVERRIDE, rc_file._data)); + header (format ("TASKRC override: {1}", rc_file._data)); + } + + // Artificial scope for timing purposes. + { + Timer timer; + config.parse (configurationDefaults); + config.load (rc_file._data); + debugTiming (format ("Config::load ({1})", rc_file._data), timer); } - config.clear (); - config.load (rc_file); CLI2::applyOverrides (argc, argv); //////////////////////////////////////////////////////////////////////////// @@ -141,7 +492,7 @@ int Context::initialize (int argc, const char** argv) { data_dir = Directory (override); config.set ("data.location", data_dir._data); - header (format (STRING_CONTEXT_DATA_OVERRIDE, data_dir._data)); + header (format ("TASKDATA override: {1}", data_dir._data)); } tdb2.set_location (data_dir); @@ -207,8 +558,8 @@ int Context::initialize (int argc, const char** argv) cli2.analyze (); // Extract a recomposed command line. - bool foundDefault = false; - bool foundAssumed = false; + auto foundDefault = false; + auto foundAssumed = false; std::string combined; for (auto& a : cli2._args) { @@ -228,7 +579,7 @@ int Context::initialize (int argc, const char** argv) header ("[" + combined + "]"); if (foundAssumed) - header (STRING_ASSUME_INFO); + header ("No command specified - assuming 'information'."); //////////////////////////////////////////////////////////////////////////// // @@ -253,7 +604,7 @@ int Context::initialize (int argc, const char** argv) catch (...) { - error (STRING_UNKNOWN_ERROR); + error ("Unknown error. Please report."); rc = 3; } @@ -265,9 +616,9 @@ int Context::initialize (int argc, const char** argv) { for (auto& d : debugMessages) if (color ()) - std::cerr << colorizeDebug (d) << "\n"; + std::cerr << colorizeDebug (d) << '\n'; else - std::cerr << d << "\n"; + std::cerr << d << '\n'; } // Dump all headers, controlled by 'header' verbosity token. @@ -275,9 +626,9 @@ int Context::initialize (int argc, const char** argv) { for (auto& h : headers) if (color ()) - std::cerr << colorizeHeader (h) << "\n"; + std::cerr << colorizeHeader (h) << '\n'; else - std::cerr << h << "\n"; + std::cerr << h << '\n'; } // Dump all footnotes, controlled by 'footnote' verbosity token. @@ -285,21 +636,21 @@ int Context::initialize (int argc, const char** argv) { for (auto& f : footnotes) if (color ()) - std::cerr << colorizeFootnote (f) << "\n"; + std::cerr << colorizeFootnote (f) << '\n'; else - std::cerr << f << "\n"; + std::cerr << f << '\n'; } // Dump all errors, non-maskable. // Colorized as footnotes. for (auto& e : errors) if (color ()) - std::cerr << colorizeFootnote (e) << "\n"; + std::cerr << colorizeFootnote (e) << '\n'; else - std::cerr << e << "\n"; + std::cerr << e << '\n'; } - timer_init.stop (); + time_init_us += timer_total.total_us (); return rc; } @@ -317,38 +668,38 @@ int Context::run () hooks.onExit (); // No chance to update data. timer_total.stop (); + time_total_us += timer_total.total_us (); std::stringstream s; s << "Perf " << PACKAGE_STRING - << " " + << ' ' #ifdef HAVE_COMMIT << COMMIT #else - << "-" + << '-' #endif - << " " - << ISO8601d ().toISO () + << ' ' + << Datetime ().toISO () - << " init:" << timer_init.total () - << " load:" << timer_load.total () - << " gc:" << timer_gc.total () - << " filter:" << timer_filter.total () - << " commit:" << timer_commit.total () - << " sort:" << timer_sort.total () - << " render:" << timer_render.total () - << " hooks:" << timer_hooks.total () - << " other:" << timer_total.total () - - timer_init.total () - - timer_load.total () - - timer_gc.total () - - timer_filter.total () - - timer_commit.total () - - timer_sort.total () - - timer_render.total () - - timer_hooks.total () - << " total:" << timer_total.total () - << "\n"; + << " init:" << time_init_us + << " load:" << time_load_us + << " gc:" << (time_gc_us > 0 ? time_gc_us - time_load_us : time_gc_us) + << " filter:" << time_filter_us + << " commit:" << time_commit_us + << " sort:" << time_sort_us + << " render:" << time_render_us + << " hooks:" << time_hooks_us + << " other:" << time_total_us - + time_init_us - + time_gc_us - + time_filter_us - + time_commit_us - + time_sort_us - + time_render_us - + time_hooks_us + << " total:" << time_total_us + << '\n'; debug (s.str ()); } @@ -366,7 +717,7 @@ int Context::run () catch (...) { - error (STRING_UNKNOWN_ERROR); + error ("Unknown error. Please report."); rc = 3; } @@ -375,9 +726,9 @@ int Context::run () { for (auto& d : debugMessages) if (color ()) - std::cerr << colorizeDebug (d) << "\n"; + std::cerr << colorizeDebug (d) << '\n'; else - std::cerr << d << "\n"; + std::cerr << d << '\n'; } // Dump all headers, controlled by 'header' verbosity token. @@ -385,9 +736,9 @@ int Context::run () { for (auto& h : headers) if (color ()) - std::cerr << colorizeHeader (h) << "\n"; + std::cerr << colorizeHeader (h) << '\n'; else - std::cerr << h << "\n"; + std::cerr << h << '\n'; } // Dump the report output. @@ -398,18 +749,18 @@ int Context::run () { for (auto& f : footnotes) if (color ()) - std::cerr << colorizeFootnote (f) << "\n"; + std::cerr << colorizeFootnote (f) << '\n'; else - std::cerr << f << "\n"; + std::cerr << f << '\n'; } // Dump all errors, non-maskable. // Colorized as footnotes. for (auto& e : errors) if (color ()) - std::cerr << colorizeError (e) << "\n"; + std::cerr << colorizeError (e) << '\n'; else - std::cerr << e << "\n"; + std::cerr << e << '\n'; return rc; } @@ -469,6 +820,70 @@ int Context::dispatch (std::string &out) return commands["help"]->execute (out); } +//////////////////////////////////////////////////////////////////////////////// +int Context::getWidth () +{ + // Determine window size. + auto width = config.getInteger ("defaultwidth"); + + // A zero width value means 'infinity', which is approximated here by 2^16. + if (width == 0) + return 65536; + + if (config.getBoolean ("detection")) + { + if (terminal_width == 0 && + terminal_height == 0) + { + unsigned short buff[4]; + if (ioctl (STDOUT_FILENO, TIOCGWINSZ, &buff) != -1) + { + terminal_height = buff[0]; + terminal_width = buff[1]; + } + } + + width = terminal_width; + + // Ncurses does this, and perhaps we need to as well, to avoid a problem on + // Cygwin where the display goes right up to the terminal width, and causes + // an odd color wrapping problem. + if (config.getBoolean ("avoidlastcolumn")) + --width; + } + + return width; +} + +//////////////////////////////////////////////////////////////////////////////// +int Context::getHeight () +{ + // Determine window size. + auto height = config.getInteger ("defaultheight"); + + // A zero height value means 'infinity', which is approximated here by 2^16. + if (height == 0) + return 65536; + + if (config.getBoolean ("detection")) + { + if (terminal_width == 0 && + terminal_height == 0) + { + unsigned short buff[4]; + if (ioctl (STDOUT_FILENO, TIOCGWINSZ, &buff) != -1) + { + terminal_height = buff[0]; + terminal_width = buff[1]; + } + } + + height = terminal_height; + } + + return height; +} + //////////////////////////////////////////////////////////////////////////////// bool Context::color () { @@ -519,7 +934,8 @@ bool Context::verbose (const std::string& token) if (verbosity.empty ()) { verbosity_legacy = config.getBoolean ("verbose"); - split (verbosity, config.get ("verbose"), ','); + for (auto& token : split (config.get ("verbose"), ',')) + verbosity.insert (token); // Regular feedback means almost everything. // This odd test is to see if a Boolean-false value is a real one, which @@ -542,6 +958,7 @@ bool Context::verbose (const std::string& token) v != "sync" && // v != "filter" && // v != "unwait" && // + v != "override" && // v != "recur") // { // This list emulates rc.verbose=off in version 1.9.4. @@ -553,7 +970,7 @@ bool Context::verbose (const std::string& token) if (! verbosity.count ("footnote")) { // TODO: Some of these may not use footnotes yet. They should. - for (auto flag : {"affected", "new-id", "new-uuid", "project", "unwait", "recur"}) + for (auto flag : {"affected", "new-id", "new-uuid", "project", "unwait", "override", "recur"}) { if (verbosity.count (flag)) { @@ -600,7 +1017,7 @@ void Context::getLimits (int& rows, int& lines) lines = 0; // This is an integer specified as a filter (limit:10). - std::string limit = config.get ("limit"); + auto limit = config.get ("limit"); if (limit != "") { if (limit == "page") @@ -610,7 +1027,7 @@ void Context::getLimits (int& rows, int& lines) } else { - rows = (int) strtol (limit.c_str (), NULL, 10); + rows = (int) strtol (limit.c_str (), nullptr, 10); lines = 0; } } @@ -621,21 +1038,23 @@ void Context::getLimits (int& rows, int& lines) // easier, it has been decoupled from Context. void Context::staticInitialization () { - CLI2::minimumMatchLength = config.getInteger ("abbreviation.minimum"); - Lexer::minimumMatchLength = config.getInteger ("abbreviation.minimum"); - ISO8601d::minimumMatchLength = config.getInteger ("abbreviation.minimum"); + CLI2::minimumMatchLength = config.getInteger ("abbreviation.minimum"); + Lexer::minimumMatchLength = config.getInteger ("abbreviation.minimum"); - Task::defaultProject = config.get ("default.project"); - Task::defaultDue = config.get ("default.due"); + Task::defaultProject = config.get ("default.project"); + Task::defaultDue = config.get ("default.due"); + Task::defaultScheduled = config.get ("default.scheduled"); - Task::searchCaseSensitive = Variant::searchCaseSensitive = config.getBoolean ("search.case.sensitive"); - Task::regex = Variant::searchUsingRegex = config.getBoolean ("regex"); - Lexer::dateFormat = Variant::dateFormat = config.get ("dateformat"); - ISO8601p::isoEnabled = ISO8601d::isoEnabled = config.getBoolean ("date.iso"); + Task::searchCaseSensitive = Variant::searchCaseSensitive = config.getBoolean ("search.case.sensitive"); + Task::regex = Variant::searchUsingRegex = config.getBoolean ("regex"); + Lexer::dateFormat = Variant::dateFormat = config.get ("dateformat"); - TDB2::debug_mode = config.getBoolean ("debug"); + Datetime::isoEnabled = config.getBoolean ("date.iso"); + Datetime::standaloneDateEnabled = false; + Datetime::standaloneTimeEnabled = false; + Duration::standaloneSecondsEnabled = false; - ISO8601d::weekstart = config.get ("weekstart"); + TDB2::debug_mode = config.getBoolean ("debug"); for (auto& rc : config) { @@ -643,8 +1062,7 @@ void Context::staticInitialization () rc.first.substr (rc.first.length () - 7, 7) == ".values") { std::string name = rc.first.substr (4, rc.first.length () - 7 - 4); - std::vector values; - split (values, rc.second, ','); + auto values = split (rc.second, ','); for (auto r = values.rbegin(); r != values.rend (); ++r) Task::customOrder[name].push_back (*r); @@ -670,9 +1088,7 @@ void Context::staticInitialization () Task::urgencyAgeMax = config.getReal ("urgency.age.max"); // Tag- and project-specific coefficients. - std::vector all; - config.all (all); - for (auto& var : all) + for (auto& var : config.all ()) if (var.substr (0, 13) == "urgency.user." || var.substr (0, 12) == "urgency.uda.") Task::coefficients[var] = config.getReal (var); @@ -685,14 +1101,60 @@ void Context::createDefaultConfig () if (rc_file._data != "" && ! rc_file.exists ()) { if (config.getBoolean ("confirmation") && - !confirm (format (STRING_CONTEXT_CREATE_RC, home_dir, rc_file._data))) - throw std::string (STRING_CONTEXT_NEED_RC); + ! confirm ( format ("A configuration file could not be found in {1}\n\nWould you like a sample {2} created, so Taskwarrior can proceed?", home_dir, rc_file._data))) + throw std::string ("Cannot proceed without rc file."); - config.createDefaultRC (rc_file, data_dir._original); + // Override data.location in the defaults. + auto loc = configurationDefaults.find ("data.location=~/.task"); + // loc+0^ +14^ +21^ + + Datetime now; + std::stringstream contents; + contents << "# [Created by " + << PACKAGE_STRING + << ' ' + << now.toString ("m/d/Y H:N:S") + << "]\n" + << configurationDefaults.substr (0, loc + 14) + << data_dir._original + << "\n\n# Color theme (uncomment one to use)\n" + << "#include " << TASK_RCDIR << "/light-16.theme\n" + << "#include " << TASK_RCDIR << "/light-256.theme\n" + << "#include " << TASK_RCDIR << "/dark-16.theme\n" + << "#include " << TASK_RCDIR << "/dark-256.theme\n" + << "#include " << TASK_RCDIR << "/dark-red-256.theme\n" + << "#include " << TASK_RCDIR << "/dark-green-256.theme\n" + << "#include " << TASK_RCDIR << "/dark-blue-256.theme\n" + << "#include " << TASK_RCDIR << "/dark-violets-256.theme\n" + << "#include " << TASK_RCDIR << "/dark-yellow-green.theme\n" + << "#include " << TASK_RCDIR << "/dark-gray-256.theme\n" + << "#include " << TASK_RCDIR << "/dark-gray-blue-256.theme\n" + << "#include " << TASK_RCDIR << "/solarized-dark-256.theme\n" + << "#include " << TASK_RCDIR << "/solarized-light-256.theme\n" + << "#include " << TASK_RCDIR << "/no-color.theme\n" + << '\n'; + + // Write out the new file. + if (! File::write (rc_file._data, contents.str ())) + throw format ("Could not write to '{1}'.", rc_file._data); } // Create data location, if necessary. - config.createDefaultData (data_dir); + Directory d (data_dir); + if (! d.exists ()) + { + if (config.getBoolean ("exit.on.missing.db")) + throw std::string ("Error: rc.data.location does not exist - exiting according to rc.exit.on.missing.db setting."); + + d.create (); + + if (config.has ("hooks.location")) + d = Directory (config.get ("hooks.location")); + else + d += "hooks"; + + d.create (); + } } //////////////////////////////////////////////////////////////////////////////// @@ -729,6 +1191,20 @@ void Context::decomposeSortField ( } } +//////////////////////////////////////////////////////////////////////////////// +void Context::debugTiming (const std::string& details, const Timer& timer) +{ + std::stringstream out; + out << "Timer " + << details + << ' ' + << std::setprecision (6) + << std::fixed + << timer.total_us () / 1.0e6 + << " sec"; + debug (out.str ()); +} + //////////////////////////////////////////////////////////////////////////////// // This capability is to answer the question of 'what did I just do to generate // this output?'. @@ -736,7 +1212,7 @@ void Context::updateXtermTitle () { if (config.getBoolean ("xterm.title") && isatty (STDOUT_FILENO)) { - std::string command = cli2.getCommand (); + auto command = cli2.getCommand (); std::string title; for (auto a = cli2._args.begin (); a != cli2._args.end (); ++a) @@ -747,7 +1223,7 @@ void Context::updateXtermTitle () title += a->attribute ("raw"); } - std::cout << "]0;task " << command << " " << title << ""; + std::cout << "]0;task " << command << ' ' << title << ""; } } @@ -755,7 +1231,7 @@ void Context::updateXtermTitle () // This function allows a clean output if the command is a helper subcommand. void Context::updateVerbosity () { - std::string command = cli2.getCommand (); + auto command = cli2.getCommand (); if (command != "" && command[0] == '_') { @@ -831,3 +1307,5 @@ void Context::debug (const std::string& input) } //////////////////////////////////////////////////////////////////////////////// + +// vim ts=2:sw=2 diff --git a/src/Context.h b/src/Context.h index a3ea489be..e863e6530 100644 --- a/src/Context.h +++ b/src/Context.h @@ -1,6 +1,6 @@ //////////////////////////////////////////////////////////////////////////////// // -// Copyright 2006 - 2016, Paul Beckingham, Federico Hernandez. +// Copyright 2006 - 2020, 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 @@ -20,7 +20,7 @@ // 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 +// https://www.opensource.org/licenses/mit-license.php // //////////////////////////////////////////////////////////////////////////////// @@ -29,7 +29,7 @@ #include #include -#include +#include #include #include #include @@ -41,12 +41,15 @@ class Context { public: - Context (); // Default constructor + Context () = default; // Default constructor ~Context (); // Destructor Context (const Context&); Context& operator= (const Context&); + static Context& getContext (); + static void setContext (Context*); + int initialize (int, const char**); // all startup int run (); int dispatch (std::string&); // command handler dispatch @@ -66,6 +69,7 @@ public: void error (const std::string&); // Error message sink - non-maskable void decomposeSortField (const std::string&, std::string&, bool&, bool&); + void debugTiming (const std::string&, const Timer&); private: void staticInitialization (); @@ -75,43 +79,40 @@ private: void loadAliases (); void propagateDebug (); + static Context* context; + public: - CLI2 cli2; - std::string home_dir; - File rc_file; - Path data_dir; - Config config; + CLI2 cli2 {}; + std::string home_dir {}; + File rc_file {"~/.taskrc"}; + Path data_dir {"~/.task"}; + Configuration config {}; + TDB2 tdb2 {}; + Hooks hooks {}; + bool determine_color_use {true}; + bool use_color {true}; + bool run_gc {true}; + bool verbosity_legacy {false}; + std::set verbosity {}; + std::vector headers {}; + std::vector footnotes {}; + std::vector errors {}; + std::vector debugMessages {}; + std::map commands {}; + std::map columns {}; + int terminal_width {0}; + int terminal_height {0}; - TDB2 tdb2; - Hooks hooks; - - bool determine_color_use; - bool use_color; - - bool run_gc; - - bool verbosity_legacy; - std::set verbosity; - std::vector headers; - std::vector footnotes; - std::vector errors; - std::vector debugMessages; - - std::map commands; - std::map columns; - - int terminal_width; - int terminal_height; - - Timer timer_total; - Timer timer_init; - Timer timer_load; - Timer timer_gc; - Timer timer_filter; - Timer timer_commit; - Timer timer_sort; - Timer timer_render; - Timer timer_hooks; + Timer timer_total {}; + long time_total_us {0}; + long time_init_us {0}; + long time_load_us {0}; + long time_gc_us {0}; + long time_filter_us {0}; + long time_commit_us {0}; + long time_sort_us {0}; + long time_render_us {0}; + long time_hooks_us {0}; }; #endif diff --git a/src/DOM.cpp b/src/DOM.cpp index 4d49cf352..d310f21f9 100644 --- a/src/DOM.cpp +++ b/src/DOM.cpp @@ -1,6 +1,6 @@ //////////////////////////////////////////////////////////////////////////////// // -// Copyright 2006 - 2016, Paul Beckingham, Federico Hernandez. +// Copyright 2006 - 2020, 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 @@ -20,7 +20,7 @@ // 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 +// https://www.opensource.org/licenses/mit-license.php // //////////////////////////////////////////////////////////////////////////////// @@ -30,13 +30,13 @@ #include #include #include +#include #include -#include -#include -#include -#include - -extern Context context; +#include +#include +#include +#include +#include //////////////////////////////////////////////////////////////////////////////// // DOM Supported References: @@ -44,11 +44,19 @@ extern Context context; // Configuration: // rc. // +// Taskwarrior: +// tw.syncneeded +// tw.program +// tw.args +// tw.width +// tw.height +// tw.version +// // System: -// context.program -// context.args -// context.width -// context.height +// context.program // 2017-02-25 Deprecated in 2.6.0 +// context.args // 2017-02-25 Deprecated in 2.6.0 +// context.width // 2017-02-25 Deprecated in 2.6.0 +// context.height // 2017-02-25 Deprecated in 2.6.0 // system.version // system.os // @@ -58,16 +66,15 @@ bool getDOM (const std::string& name, Variant& value) if (name == "") return false; - int len = name.length (); - Nibbler n (name); + auto len = name.length (); // rc. --> context.config if (len > 3 && ! name.compare (0, 3, "rc.", 3)) { - std::string key = name.substr (3); - auto c = context.config.find (key); - if (c != context.config.end ()) + auto key = name.substr (3); + auto c = Context::getContext ().config.find (key); + if (c != Context::getContext ().config.end ()) { value = Variant (c->second); return true; @@ -76,22 +83,83 @@ bool getDOM (const std::string& name, Variant& value) return false; } + // tw.* + if (len > 3 && + ! name.compare (0, 3, "tw.", 3)) + { + if (name == "tw.syncneeded") + { + value = Variant (0); + for (const auto& line : Context::getContext ().tdb2.backlog.get_lines ()) + { + if (line[0] == '{') + { + value = Variant (1); + break; + } + } + + return true; + } + else if (name == "tw.program") + { + value = Variant (Context::getContext ().cli2.getBinary ()); + return true; + } + else if (name == "tw.args") + { + std::string commandLine; + for (auto& arg : Context::getContext ().cli2._original_args) + { + if (commandLine != "") + commandLine += ' '; + + commandLine += arg.attribute("raw"); + } + + value = Variant (commandLine); + return true; + } + else if (name == "tw.width") + { + value = Variant (static_cast (Context::getContext ().terminal_width + ? Context::getContext ().terminal_width + : Context::getContext ().getWidth ())); + return true; + } + else if (name == "tw.height") + { + value = Variant (static_cast (Context::getContext ().terminal_height + ? Context::getContext ().terminal_height + : Context::getContext ().getHeight ())); + return true; + } + + else if (name == "tw.version") + { + value = Variant (VERSION); + return true; + } + + return false; + } + // context.* if (len > 8 && ! name.compare (0, 8, "context.", 8)) { if (name == "context.program") { - value = Variant (context.cli2.getBinary ()); + value = Variant (Context::getContext ().cli2.getBinary ()); return true; } else if (name == "context.args") { std::string commandLine; - for (auto& arg : context.cli2._original_args) + for (auto& arg : Context::getContext ().cli2._original_args) { if (commandLine != "") - commandLine += " "; + commandLine += ' '; commandLine += arg.attribute("raw"); } @@ -101,23 +169,21 @@ bool getDOM (const std::string& name, Variant& value) } else if (name == "context.width") { - value = Variant (static_cast (context.terminal_width - ? context.terminal_width - : context.getWidth ())); + value = Variant (static_cast (Context::getContext ().terminal_width + ? Context::getContext ().terminal_width + : Context::getContext ().getWidth ())); return true; } else if (name == "context.height") { - value = Variant (static_cast (context.terminal_height - ? context.terminal_height - : context.getHeight ())); + value = Variant (static_cast (Context::getContext ().terminal_height + ? Context::getContext ().terminal_height + : Context::getContext ().getHeight ())); return true; } - else - throw format (STRING_DOM_UNREC, name); - } - // TODO stats. + return false; + } // system. --> Implement locally. if (len > 7 && @@ -133,33 +199,11 @@ bool getDOM (const std::string& name, Variant& value) // OS type. else if (name == "system.os") { -#if defined (DARWIN) - value = Variant ("Darwin"); -#elif defined (SOLARIS) - value = Variant ("Solaris"); -#elif defined (CYGWIN) - value = Variant ("Cygwin"); -#elif defined (HAIKU) - value = Variant ("Haiku"); -#elif defined (OPENBSD) - value = Variant ("OpenBSD"); -#elif defined (FREEBSD) - value = Variant ("FreeBSD"); -#elif defined (NETBSD) - value = Variant ("NetBSD"); -#elif defined (LINUX) - value = Variant ("Linux"); -#elif defined (KFREEBSD) - value = Variant ("GNU/kFreeBSD"); -#elif defined (GNUHURD) - value = Variant ("GNU/Hurd"); -#else - value = Variant (STRING_DOM_UNKNOWN); -#endif + value = Variant (osName ()); return true; } - else - throw format (STRING_DOM_UNREC, name); + + return false; } // Empty string if nothing is found. @@ -189,10 +233,11 @@ bool getDOM (const std::string& name, Variant& value) // .second // // Annotations (entry is a date): +// annotations.count // annotations..entry // annotations..description // -// This code emphasizes speed, hence 'id' and 'urgecny' being evaluated first +// This code emphasizes speed, hence 'id' and 'urgency' being evaluated first // as special cases. bool getDOM (const std::string& name, const Task& task, Variant& value) { @@ -214,31 +259,29 @@ bool getDOM (const std::string& name, const Task& task, Variant& value) } // split name on '.' - std::vector elements; - split (elements, name, '.'); + auto elements = split (name, '.'); Task ref (task); - Nibbler n (elements[0]); - n.save (); - int id; - std::string uuid; - - // If elements[0] is a UUID, load that task (if necessary), and clobber ref. - if (n.getPartialUUID (uuid) && n.depleted ()) + Lexer lexer (elements[0]); + std::string token; + Lexer::Type type; + if (lexer.token (token, type)) { - if (uuid != ref.get ("uuid")) - context.tdb2.get (uuid, ref); - - // Eat elements[0]/UUID. - elements.erase (elements.begin ()); - } - else - { - // If elements[0] is a ID, load that task (if necessary), and clobber ref. - if (n.getInt (id) && n.depleted ()) + if (type == Lexer::Type::uuid && + token.length () == elements[0].length ()) { - if (id != ref.id) - context.tdb2.get (id, ref); + if (token != ref.get ("uuid")) + Context::getContext ().tdb2.get (token, ref); + + // Eat elements[0]/UUID. + elements.erase (elements.begin ()); + } + else if (type == Lexer::Type::number && + token.find ('.') == std::string::npos) + { + auto id = strtol (token.c_str (), nullptr, 10); + if (id && id != ref.id) + Context::getContext ().tdb2.get (id, ref); // Eat elements[0]/ID. elements.erase (elements.begin ()); @@ -248,7 +291,7 @@ bool getDOM (const std::string& name, const Task& task, Variant& value) auto size = elements.size (); std::string canonical; - if ((size == 1 || size == 2) && context.cli2.canonicalize (canonical, "attribute", elements[0])) + if ((size == 1 || size == 2) && Context::getContext ().cli2.canonicalize (canonical, "attribute", elements[0])) { // Now that 'ref' is the contextual task, and any ID/UUID is chopped off the // elements vector, DOM resolution is now simple. @@ -264,7 +307,7 @@ bool getDOM (const std::string& name, const Task& task, Variant& value) return true; } - Column* column = context.columns[canonical]; + Column* column = Context::getContext ().columns[canonical]; if (ref.data.size () && size == 1 && column) { @@ -286,12 +329,12 @@ bool getDOM (const std::string& name, const Task& task, Variant& value) { auto period = ref.get (canonical); - ISO8601p iso; + Duration iso; std::string::size_type cursor = 0; if (iso.parse (period, cursor)) - value = Variant ((time_t) iso, Variant::type_duration); + value = Variant (iso.toTime_t (), Variant::type_duration); else - value = Variant ((time_t) ISO8601p (ref.get (canonical)), Variant::type_duration); + value = Variant (Duration (ref.get (canonical)).toTime_t (), Variant::type_duration); } else if (column->type () == "numeric") value = Variant (ref.get_float (canonical)); @@ -309,7 +352,7 @@ bool getDOM (const std::string& name, const Task& task, Variant& value) if (ref.data.size () && size == 2 && column && column->type () == "date") { - ISO8601d date (ref.get_date (canonical)); + Datetime date (ref.get_date (canonical)); if (elements[1] == "year") { value = Variant (static_cast (date.year ())); return true; } else if (elements[1] == "month") { value = Variant (static_cast (date.month ())); return true; } else if (elements[1] == "day") { value = Variant (static_cast (date.day ())); return true; } @@ -322,12 +365,17 @@ bool getDOM (const std::string& name, const Task& task, Variant& value) } } + if (ref.data.size () && size == 2 && elements[0] == "annotations" && elements[1] == "count") + { + value = Variant (static_cast (ref.getAnnotationCount ())); + return true; + } + if (ref.data.size () && size == 3 && elements[0] == "annotations") { - std::map annos; - ref.getAnnotations (annos); + auto annos = ref.getAnnotations (); - int a = strtol (elements[1].c_str (), NULL, 10); + int a = strtol (elements[1].c_str (), nullptr, 10); int count = 0; // Count off the 'a'th annotation. @@ -353,10 +401,9 @@ bool getDOM (const std::string& name, const Task& task, Variant& value) if (ref.data.size () && size == 4 && elements[0] == "annotations" && elements[2] == "entry") { - std::map annos; - ref.getAnnotations (annos); + auto annos = ref.getAnnotations (); - int a = strtol (elements[1].c_str (), NULL, 10); + int a = strtol (elements[1].c_str (), nullptr, 10); int count = 0; // Count off the 'a'th annotation. @@ -373,7 +420,7 @@ bool getDOM (const std::string& name, const Task& task, Variant& value) // ..entry.hour // ..entry.minute // ..entry.second - ISO8601d date (i.first.substr (11)); + Datetime date (i.first.substr (11)); if (elements[3] == "year") { value = Variant (static_cast (date.year ())); return true; } else if (elements[3] == "month") { value = Variant (static_cast (date.month ())); return true; } else if (elements[3] == "day") { value = Variant (static_cast (date.day ())); return true; } @@ -392,3 +439,232 @@ bool getDOM (const std::string& name, const Task& task, Variant& value) } //////////////////////////////////////////////////////////////////////////////// +// DOM Class +// +// References are paths into a tree structure. For example: +// +// 1.due.month.number +// 1.due.day.number +// +// Are represented internally as: +// +// 1 +// +- due +// +- day +// | +- number +// +- month +// +- number +// +// The tree is augmented by other elements: +// +// 1 +// +- due +// | +- day +// | | +- number +// | +- month +// | +- number +// +- system +// +- os +// +// Each node in the tree has a name ("due", "system", "day"), and each node may +// have a data source attached to it. +// +// The DOM class is independent of the project, in that it knows nothing about +// the internal data or program structure. It knows only that certain DOM path +// elements have handlers which will provide the data. +// +// The DOM class is therefore responsible for maintaining a tree of named nodes +// with associated proividers. When a reference value is requested, the DOM +// class will decompose the reference path, and navigate the tree to the lowest +// level provider, and call it. +// +// This makes the DOM class a reusible object. + +//////////////////////////////////////////////////////////////////////////////// +DOM::~DOM () +{ + delete _node; +} + +//////////////////////////////////////////////////////////////////////////////// +void DOM::addSource ( + const std::string& reference, + bool (*provider)(const std::string&, Variant&)) +{ + if (_node == nullptr) + _node = new DOM::Node (); + + _node->addSource (reference, provider); +} + +//////////////////////////////////////////////////////////////////////////////// +bool DOM::valid (const std::string& reference) const +{ + return _node && _node->find (reference) != nullptr; +} + +//////////////////////////////////////////////////////////////////////////////// +Variant DOM::get (const std::string& reference) const +{ + Variant v (""); + + if (_node) + { + auto node = _node->find (reference); + if (node != nullptr && + node->_provider != nullptr) + { + if (node->_provider (reference, v)) + return v; + } + } + + return v; +} + +//////////////////////////////////////////////////////////////////////////////// +int DOM::count () const +{ + if (_node) + return _node->count (); + + return 0; +} + +//////////////////////////////////////////////////////////////////////////////// +std::vector DOM::decomposeReference (const std::string& reference) +{ + return split (reference, '.'); +} + +//////////////////////////////////////////////////////////////////////////////// +std::string DOM::dump () const +{ + if (_node) + return _node->dump (); + + return ""; +} + +//////////////////////////////////////////////////////////////////////////////// +DOM::Node::~Node () +{ + for (auto& branch : _branches) + delete branch; +} + +//////////////////////////////////////////////////////////////////////////////// +void DOM::Node::addSource ( + const std::string& reference, + bool (*provider)(const std::string&, Variant&)) +{ + auto cursor = this; + for (const auto& element : DOM::decomposeReference (reference)) + { + auto found {false}; + for (auto& branch : cursor->_branches) + { + if (branch->_name == element) + { + cursor = branch; + found = true; + break; + } + } + + if (! found) + { + auto branch = new DOM::Node (); + branch->_name = element; + cursor->_branches.push_back (branch); + cursor = branch; + } + } + + cursor->_provider = provider; +} + +//////////////////////////////////////////////////////////////////////////////// +// A valid reference is one that has a provider function. +bool DOM::Node::valid (const std::string& reference) const +{ + return find (reference) != nullptr; +} + +//////////////////////////////////////////////////////////////////////////////// +const DOM::Node* DOM::Node::find (const std::string& reference) const +{ + auto cursor = this; + for (const auto& element : DOM::decomposeReference (reference)) + { + auto found {false}; + for (auto& branch : cursor->_branches) + { + if (branch->_name == element) + { + cursor = branch; + found = true; + break; + } + } + + if (! found) + break; + } + + if (reference.length () && cursor != this) + return cursor; + + return nullptr; +} + +//////////////////////////////////////////////////////////////////////////////// +int DOM::Node::count () const +{ + // Recurse and count the branches. + int total {0}; + for (auto& branch : _branches) + { + if (branch->_provider) + ++total; + total += branch->count (); + } + + return total; +} + +//////////////////////////////////////////////////////////////////////////////// +std::string DOM::Node::dumpNode ( + const DOM::Node* node, + int depth) const +{ + std::stringstream out; + + // Indent. + out << std::string (depth * 2, ' '); + + out << "\033[31m" << node->_name << "\033[0m"; + + if (node->_provider) + out << " 0x" << std::hex << (long long) (void*) node->_provider; + + out << '\n'; + + // Recurse for branches. + for (auto& b : node->_branches) + out << dumpNode (b, depth + 1); + + return out.str (); +} + +//////////////////////////////////////////////////////////////////////////////// +std::string DOM::Node::dump () const +{ + std::stringstream out; + out << "DOM::Node (" << count () << " nodes)\n" + << dumpNode (this, 1); + + return out.str (); +} + +//////////////////////////////////////////////////////////////////////////////// diff --git a/src/DOM.h b/src/DOM.h index ecbc6fe8d..c6b22cfc4 100644 --- a/src/DOM.h +++ b/src/DOM.h @@ -1,6 +1,6 @@ //////////////////////////////////////////////////////////////////////////////// // -// Copyright 2006 - 2016, Paul Beckingham, Federico Hernandez. +// Copyright 2006 - 2020, 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 @@ -20,7 +20,7 @@ // 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 +// https://www.opensource.org/licenses/mit-license.php // //////////////////////////////////////////////////////////////////////////////// @@ -31,7 +31,46 @@ #include #include +// 2017-04-22 Deprecated, use DOM::get. bool getDOM (const std::string&, Variant&); bool getDOM (const std::string&, const Task&, Variant&); +class DOM +{ +public: + ~DOM (); + void addSource (const std::string&, bool (*)(const std::string&, Variant&)); + bool valid (const std::string&) const; +/* + // TODO Task object should register a generic provider. + Variant get (const Task&, const std::string&) const; +*/ + Variant get (const std::string&) const; + int count () const; + static std::vector decomposeReference (const std::string&); + std::string dump () const; + +private: + class Node + { + public: + ~Node (); + void addSource (const std::string&, bool (*)(const std::string&, Variant&)); + bool valid (const std::string&) const; + const DOM::Node* find (const std::string&) const; + int count () const; + std::string dumpNode (const DOM::Node*, int) const; + std::string dump () const; + + public: + std::string _name {"Unknown"}; + bool (*_provider)(const std::string&, Variant&) {nullptr}; + std::vector _branches {}; + }; + +private: + DOM::Node* _node {nullptr}; +}; + #endif +//////////////////////////////////////////////////////////////////////////////// diff --git a/src/Dates.cpp b/src/Dates.cpp deleted file mode 100644 index a0b5035c2..000000000 --- a/src/Dates.cpp +++ /dev/null @@ -1,519 +0,0 @@ -//////////////////////////////////////////////////////////////////////////////// -// -// Copyright 2013 - 2016, 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 -#include -#include -#include -#include -#include -#include -#include -#include -#include - -//////////////////////////////////////////////////////////////////////////////// -static bool isMonth (const std::string& name, int& i) -{ - i = ISO8601d::monthOfYear (name) - 1; - return i != -2 ? true : false; -} - -//////////////////////////////////////////////////////////////////////////////// -static bool isDay (const std::string& name, int& i) -{ - i = ISO8601d::dayOfWeek (name); - return i != -1 ? true : false; -} - -//////////////////////////////////////////////////////////////////////////////// -static void easter (struct tm* t) -{ - int Y = t->tm_year + 1900; - int a = Y % 19; - int b = Y / 100; - int c = Y % 100; - int d = b / 4; - int e = b % 4; - int f = (b + 8) / 25; - int g = (b - f + 1) / 3; - int h = (19 * a + b - d - g + 15) % 30; - int i = c / 4; - int k = c % 4; - int L = (32 + 2 * e + 2 * i - h - k) % 7; - int m = (a + 11 * h + 22 * L) / 451; - int month = (h + L - 7 * m + 114) / 31; - int day = ((h + L - 7 * m + 114) % 31) + 1; - - t->tm_isdst = -1; // Requests that mktime determine summer time effect. - t->tm_mday = day; - t->tm_mon = month - 1; - t->tm_year = Y - 1900; - t->tm_isdst = -1; - t->tm_hour = t->tm_min = t->tm_sec = 0; -} - -//////////////////////////////////////////////////////////////////////////////// -static void midsommar (struct tm* t) -{ - t->tm_mon = 5; // June. - t->tm_mday = 20; // Saturday after 20th. - t->tm_hour = t->tm_min = t->tm_sec = 0; // Midnight. - t->tm_isdst = -1; // Probably DST, but check. - - time_t then = mktime (t); // Obtain the weekday of June 20th. - struct tm* mid = localtime (&then); - t->tm_mday += 6 - mid->tm_wday; // How many days after 20th. -} - -//////////////////////////////////////////////////////////////////////////////// -static void midsommarafton (struct tm* t) -{ - t->tm_mon = 5; // June. - t->tm_mday = 19; // Saturday after 20th. - t->tm_hour = t->tm_min = t->tm_sec = 0; // Midnight. - t->tm_isdst = -1; // Probably DST, but check. - - time_t then = mktime (t); // Obtain the weekday of June 19th. - struct tm* mid = localtime (&then); - t->tm_mday += 5 - mid->tm_wday; // How many days after 19th. -} - -//////////////////////////////////////////////////////////////////////////////// -// Note how these are all single words: -// -// -// Nth -// socy, eocy -// socq, eocq -// socm, eocm -// som, eom -// soq, eoq -// soy, eoy -// socw, eocw -// sow, eow -// soww, eoww -// sod, eod -// yesterday -// today -// now -// tomorrow -// later = midnight, Jan 18th, 2038. -// someday = midnight, Jan 18th, 2038. -// easter -// eastermonday -// ascension -// pentecost -// goodfriday -// midsommar = midnight, 1st Saturday after 20th June -// midsommarafton = midnight, 1st Friday after 19th June -// -bool namedDates (const std::string& name, Variant& value) -{ - time_t now = time (NULL); - struct tm* t = localtime (&now); - int i; - - int minimum = CLI2::minimumMatchLength; - if (minimum == 0) - minimum = 3; - - // Dynamics. - if (closeEnough ("now", name, minimum)) - { - value = Variant (now, Variant::type_date); - } - - else if (closeEnough ("today", name, minimum)) - { - t->tm_hour = t->tm_min = t->tm_sec = 0; - t->tm_isdst = -1; - value = Variant (mktime (t), Variant::type_date); - } - - else if (closeEnough ("sod", name, minimum)) - { - t->tm_mday++; - t->tm_hour = t->tm_min = t->tm_sec = 0; - t->tm_isdst = -1; - value = Variant (mktime (t), Variant::type_date); - } - - else if (closeEnough ("eod", name, minimum)) - { - t->tm_mday++; - t->tm_hour = t->tm_min = 0; - t->tm_sec = -1; - t->tm_isdst = -1; - value = Variant (mktime (t), Variant::type_date); - } - - else if (closeEnough ("tomorrow", name, minimum)) - { - t->tm_mday++; - t->tm_hour = t->tm_min = t->tm_sec = 0; - t->tm_isdst = -1; - value = Variant (mktime (t), Variant::type_date); - } - - else if (closeEnough ("yesterday", name, minimum)) - { - t->tm_hour = t->tm_min = t->tm_sec = 0; - t->tm_isdst = -1; - value = Variant (mktime (t) - 86400, Variant::type_date); - } - - else if (isDay (name, i)) - { - if (t->tm_wday >= i) - t->tm_mday += i - t->tm_wday + 7; - else - t->tm_mday += i - t->tm_wday; - - t->tm_hour = t->tm_min = t->tm_sec = 0; - t->tm_isdst = -1; - value = Variant (mktime (t), Variant::type_date); - } - - else if (isMonth (name, i)) - { - if (t->tm_mon >= i) - t->tm_year++; - - t->tm_mon = i; - t->tm_mday = 1; - t->tm_hour = t->tm_min = t->tm_sec = 0; - t->tm_isdst = -1; - value = Variant (mktime (t), Variant::type_date); - } - - else if (closeEnough ("later", name, minimum) || - closeEnough ("someday", name, std::max (minimum, 4))) - { - t->tm_hour = t->tm_min = t->tm_sec = 0; - t->tm_year = 138; - t->tm_mon = 0; - t->tm_mday = 18; - t->tm_isdst = -1; - value = Variant (mktime (t), Variant::type_date); - } - - else if (closeEnough ("eoy", name, minimum)) - { - t->tm_hour = t->tm_min = 0; - t->tm_sec = -1; - t->tm_mon = 0; - t->tm_mday = 1; - t->tm_year++; - t->tm_isdst = -1; - value = Variant (mktime (t), Variant::type_date); - } - - else if (closeEnough ("soy", name, minimum)) - { - t->tm_hour = t->tm_min = t->tm_sec = 0; - t->tm_mon = 0; - t->tm_mday = 1; - t->tm_year++; - t->tm_isdst = -1; - value = Variant (mktime (t), Variant::type_date); - } - - else if (closeEnough ("eoq", name, minimum)) - { - t->tm_hour = t->tm_min = 0; - t->tm_sec = -1; - t->tm_mon += 3 - (t->tm_mon % 3); - if (t->tm_mon > 11) - { - t->tm_mon -= 12; - ++t->tm_year; - } - - t->tm_mday = 1; - t->tm_isdst = -1; - value = Variant (mktime (t), Variant::type_date); - } - - else if (closeEnough ("soq", name, minimum)) - { - t->tm_hour = t->tm_min = t->tm_sec = 0; - t->tm_mon += 3 - (t->tm_mon % 3); - if (t->tm_mon > 11) - { - t->tm_mon -= 12; - ++t->tm_year; - } - - t->tm_mday = 1; - t->tm_isdst = -1; - value = Variant (mktime (t), Variant::type_date); - } - - else if (closeEnough ("socm", name, minimum)) - { - t->tm_hour = t->tm_min = t->tm_sec = 0; - t->tm_mday = 1; - t->tm_isdst = -1; - value = Variant (mktime (t), Variant::type_date); - } - - else if (closeEnough ("som", name, minimum)) - { - t->tm_hour = t->tm_min = t->tm_sec = 0; - - t->tm_mon++; - if (t->tm_mon == 12) - { - t->tm_year++; - t->tm_mon = 0; - } - - t->tm_mday = 1; - t->tm_isdst = -1; - value = Variant (mktime (t), Variant::type_date); - } - - else if (closeEnough ("eom", name, minimum) || - closeEnough ("eocm", name, minimum)) - { - t->tm_hour = 24; - t->tm_min = 0; - t->tm_sec = -1; - t->tm_mday = ISO8601d::daysInMonth (t->tm_mon + 1, t->tm_year + 1900); - t->tm_isdst = -1; - value = Variant (mktime (t), Variant::type_date); - } - - else if (closeEnough ("socw", name, minimum)) - { - t->tm_hour = t->tm_min = t->tm_sec = 0; - int extra = t->tm_wday * 86400; - t->tm_isdst = -1; - value = Variant (mktime (t) - extra, Variant::type_date); - } - - else if (closeEnough ("eow", name, minimum) || - closeEnough ("eocw", name, minimum)) - { - t->tm_hour = t->tm_min = 0; - t->tm_sec = -1; - int extra = (7 - t->tm_wday) * 86400; - t->tm_isdst = -1; - value = Variant (mktime (t) + extra, Variant::type_date); - } - - else if (closeEnough ("sow", name, minimum)) - { - t->tm_hour = t->tm_min = t->tm_sec = 0; - int extra = (7 - t->tm_wday) * 86400; - t->tm_isdst = -1; - value = Variant (mktime (t) + extra, Variant::type_date); - } - - else if (closeEnough ("soww", name, minimum)) - { - t->tm_hour = t->tm_min = t->tm_sec = 0; - int days = (8 - t->tm_wday) % 7; - int extra = days * 86400; - t->tm_isdst = -1; - value = Variant (mktime (t) + extra, Variant::type_date); - } - - else if (closeEnough ("eoww", name, minimum)) - { - t->tm_hour = 24; - t->tm_min = 0; - t->tm_sec = -1; - int extra = (5 - t->tm_wday) * 86400; - if (extra < 0) - extra += 7 * 86400; - - t->tm_isdst = -1; - value = Variant (mktime (t) + extra, Variant::type_date); - } - - // Support "21st" to indicate the next date that is the 21st day. - // 1st - // 2nd - // 3rd - // 4th - else if (( - name.length () == 3 && - Lexer::isDigit (name[0]) && - ((name[1] == 's' && name[2] == 't') || - (name[1] == 'n' && name[2] == 'd') || - (name[1] == 'r' && name[2] == 'd') || - (name[1] == 't' && name[2] == 'h')) - ) - || - ( - name.length () == 4 && - 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') || - (name[2] == 't' && name[3] == 'h')) - ) - ) - { - int number; - std::string ordinal; - - if (Lexer::isDigit (name[1])) - { - number = strtol (name.substr (0, 2).c_str (), NULL, 10); - ordinal = Lexer::lowerCase (name.substr (2)); - } - else - { - number = strtol (name.substr (0, 1).c_str (), NULL, 10); - ordinal = Lexer::lowerCase (name.substr (1)); - } - - // Sanity check. - if (number <= 31) - { - int remainder1 = number % 10; - int remainder2 = number % 100; - if ((remainder2 != 11 && remainder1 == 1 && ordinal == "st") || - (remainder2 != 12 && remainder1 == 2 && ordinal == "nd") || - (remainder2 != 13 && remainder1 == 3 && ordinal == "rd") || - ((remainder2 == 11 || - remainder2 == 12 || - remainder2 == 13 || - remainder1 == 0 || - remainder1 > 3) && ordinal == "th")) - { - int y = t->tm_year + 1900; - int m = t->tm_mon + 1; - int d = t->tm_mday; - - // If it is this month. - if (d < number && - number <= ISO8601d::daysInMonth (m, y)) - { - t->tm_hour = t->tm_min = t->tm_sec = 0; - t->tm_mon = m - 1; - t->tm_mday = number; - t->tm_year = y - 1900; - t->tm_isdst = -1; - value = Variant (mktime (t), Variant::type_date); - } - else - { - if (++m > 12) - { - m = 1; - y++; - } - - t->tm_hour = t->tm_min = t->tm_sec = 0; - t->tm_mon = m - 1; - t->tm_mday = number; - t->tm_year = y - 1900; - t->tm_isdst = -1; - value = Variant (mktime (t), Variant::type_date); - } - } - } - } - - else if (closeEnough ("easter", name, minimum) || - closeEnough ("eastermonday", name, minimum) || - closeEnough ("ascension", name, minimum) || - closeEnough ("pentecost", name, minimum) || - closeEnough ("goodfriday", name, minimum)) - { - Variant valueNow = Variant (mktime (t), Variant::type_date); - easter (t); - value = Variant (mktime (t), Variant::type_date); - - // If the result is earlier this year, then recalc for next year. - if (value < valueNow) - { - t = localtime (&now); - t->tm_year++; - easter (t); - } - - if (closeEnough ("goodfriday", name, minimum)) t->tm_mday -= 2; - - // DO NOT REMOVE THIS USELESS-LOOKING LINE. - // It is here to capture an exact match for 'easter', to prevent 'easter' - // being a partial match for 'eastermonday'. - else if (closeEnough ("easter", name, minimum)) ; - else if (closeEnough ("eastermonday", name, minimum)) t->tm_mday += 1; - else if (closeEnough ("ascension", name, minimum)) t->tm_mday += 39; - else if (closeEnough ("pentecost", name, minimum)) t->tm_mday += 49; - - value = Variant (mktime (t), Variant::type_date); - } - - else if (closeEnough ("midsommar", name, minimum)) - { - Variant valueNow = Variant (mktime (t), Variant::type_date); - midsommar (t); - value = Variant (mktime (t), Variant::type_date); - - // If the result is earlier this year, then recalc for next year. - if (value < valueNow) - { - t = localtime (&now); - t->tm_year++; - midsommar (t); - } - - value = Variant (mktime (t), Variant::type_date); - } - - else if (closeEnough ("midsommarafton", name, minimum)) - { - Variant valueNow = Variant (mktime (t), Variant::type_date); - midsommarafton (t); - value = Variant (mktime (t), Variant::type_date); - - // If the result is earlier this year, then recalc for next year. - if (value < valueNow) - { - t = localtime (&now); - t->tm_year++; - midsommarafton (t); - } - - value = Variant (mktime (t), Variant::type_date); - } - - else - return false; - - value.source (name); - return true; -} - -//////////////////////////////////////////////////////////////////////////////// - diff --git a/src/Eval.cpp b/src/Eval.cpp index 7a4d9fc61..6afc1e31e 100644 --- a/src/Eval.cpp +++ b/src/Eval.cpp @@ -1,6 +1,6 @@ //////////////////////////////////////////////////////////////////////////////// // -// Copyright 2013 - 2016, Paul Beckingham, Federico Hernandez. +// Copyright 2013 - 2020, 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 @@ -20,7 +20,7 @@ // 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 +// https://www.opensource.org/licenses/mit-license.php // //////////////////////////////////////////////////////////////////////////////// @@ -31,10 +31,9 @@ #include #include #include -#include -#include +#include +#include -extern Context context; extern Task& contextTask; //////////////////////////////////////////////////////////////////////////////// @@ -127,15 +126,15 @@ void Eval::evaluateInfixExpression (const std::string& e, Variant& v) const // Parse for syntax checking and operator replacement. if (_debug) - context.debug ("FILTER Infix " + dump (tokens)); + Context::getContext ().debug ("FILTER Infix " + dump (tokens)); infixParse (tokens); if (_debug) - context.debug ("FILTER Infix parsed " + dump (tokens)); + Context::getContext ().debug ("FILTER Infix parsed " + dump (tokens)); // Convert infix --> postfix. infixToPostfix (tokens); if (_debug) - context.debug ("FILTER Postfix " + dump (tokens)); + Context::getContext ().debug ("FILTER Postfix " + dump (tokens)); // Call the postfix evaluator. evaluatePostfixStack (tokens, v); @@ -153,7 +152,7 @@ void Eval::evaluatePostfixExpression (const std::string& e, Variant& v) const tokens.push_back (std::pair (token, type)); if (_debug) - context.debug ("FILTER Postfix " + dump (tokens)); + Context::getContext ().debug ("FILTER Postfix " + dump (tokens)); // Call the postfix evaluator. evaluatePostfixStack (tokens, v); @@ -167,15 +166,15 @@ void Eval::compileExpression ( // Parse for syntax checking and operator replacement. if (_debug) - context.debug ("FILTER Infix " + dump (_compiled)); + Context::getContext ().debug ("FILTER Infix " + dump (_compiled)); infixParse (_compiled); if (_debug) - context.debug ("FILTER Infix parsed " + dump (_compiled)); + Context::getContext ().debug ("FILTER Infix parsed " + dump (_compiled)); // Convert infix --> postfix. infixToPostfix (_compiled); if (_debug) - context.debug ("FILTER Postfix " + dump (_compiled)); + Context::getContext ().debug ("FILTER Postfix " + dump (_compiled)); } //////////////////////////////////////////////////////////////////////////////// @@ -220,7 +219,7 @@ void Eval::evaluatePostfixStack ( Variant& result) const { if (tokens.size () == 0) - throw std::string (STRING_EVAL_NO_EXPRESSION); + throw std::string ("No expression to evaluate."); // This is stack used by the postfix evaluator. std::vector values; @@ -231,20 +230,20 @@ void Eval::evaluatePostfixStack ( token.first == "!") { if (values.size () < 1) - throw std::string (STRING_EVAL_NO_EVAL); + throw std::string ("The expression could not be evaluated."); Variant right = values.back (); values.pop_back (); Variant result = ! right; values.push_back (result); if (_debug) - context.debug (format ("Eval {1} ↓'{2}' → ↑'{3}'", token.first, (std::string) right, (std::string) result)); + Context::getContext ().debug (format ("Eval {1} ↓'{2}' → ↑'{3}'", token.first, (std::string) right, (std::string) result)); } else if (token.second == Lexer::Type::op && token.first == "_neg_") { if (values.size () < 1) - throw std::string (STRING_EVAL_NO_EVAL); + throw std::string ("The expression could not be evaluated."); Variant right = values.back (); values.pop_back (); @@ -254,21 +253,21 @@ void Eval::evaluatePostfixStack ( values.push_back (result); if (_debug) - context.debug (format ("Eval {1} ↓'{2}' → ↑'{3}'", token.first, (std::string) right, (std::string) result)); + Context::getContext ().debug (format ("Eval {1} ↓'{2}' → ↑'{3}'", token.first, (std::string) right, (std::string) result)); } else if (token.second == Lexer::Type::op && token.first == "_pos_") { // The _pos_ operator is a NOP. if (_debug) - context.debug (format ("[{1}] eval op {2} NOP", values.size (), token.first)); + Context::getContext ().debug (format ("[{1}] eval op {2} NOP", values.size (), token.first)); } // Binary operators. else if (token.second == Lexer::Type::op) { if (values.size () < 2) - throw std::string (STRING_EVAL_NO_EVAL); + throw std::string ("The expression could not be evaluated."); Variant right = values.back (); values.pop_back (); @@ -302,12 +301,12 @@ void Eval::evaluatePostfixStack ( else if (token.first == "_hastag_") result = left.operator_hastag (right, contextTask); else if (token.first == "_notag_") result = left.operator_notag (right, contextTask); else - throw format (STRING_EVAL_UNSUPPORTED, token.first); + throw format ("Unsupported operator '{1}'.", token.first); values.push_back (result); if (_debug) - context.debug (format ("Eval ↓'{1}' {2} ↓'{3}' → ↑'{4}'", (std::string) left, token.first, (std::string) right, (std::string) result)); + Context::getContext ().debug (format ("Eval ↓'{1}' {2} ↓'{3}' → ↑'{4}'", (std::string) left, token.first, (std::string) right, (std::string) result)); } // Literals and identifiers. @@ -321,18 +320,18 @@ void Eval::evaluatePostfixStack ( { v.cast (Variant::type_integer); if (_debug) - context.debug (format ("Eval literal number ↑'{1}'", (std::string) v)); + Context::getContext ().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)); + Context::getContext ().debug (format ("Eval literal decimal ↑'{1}'", (std::string) v)); } break; case Lexer::Type::op: - throw std::string (STRING_EVAL_OP_EXPECTED); + throw std::string ("Operator expected."); break; case Lexer::Type::dom: @@ -344,18 +343,18 @@ void Eval::evaluatePostfixStack ( if ((*source) (token.first, v)) { if (_debug) - context.debug (format ("Eval identifier source '{1}' → ↑'{2}'", token.first, (std::string) v)); + Context::getContext ().debug (format ("Eval identifier source '{1}' → ↑'{2}'", token.first, (std::string) v)); found = true; break; } } // An identifier that fails lookup is a string. - if (!found) + if (! found) { v.cast (Variant::type_string); if (_debug) - context.debug (format ("Eval identifier source failed '{1}'", token.first)); + Context::getContext ().debug (format ("Eval identifier source failed '{1}'", token.first)); } } break; @@ -363,20 +362,20 @@ void Eval::evaluatePostfixStack ( case Lexer::Type::date: v.cast (Variant::type_date); if (_debug) - context.debug (format ("Eval literal date ↑'{1}'", (std::string) v)); + Context::getContext ().debug (format ("Eval literal date ↑'{1}'", (std::string) v)); break; case Lexer::Type::duration: v.cast (Variant::type_duration); if (_debug) - context.debug (format ("Eval literal duration ↑'{1}'", (std::string) v)); + Context::getContext ().debug (format ("Eval literal duration ↑'{1}'", (std::string) v)); break; // Nothing to do. case Lexer::Type::string: default: if (_debug) - context.debug (format ("Eval literal string ↑'{1}'", (std::string) v)); + Context::getContext ().debug (format ("Eval literal string ↑'{1}'", (std::string) v)); break; } @@ -387,7 +386,7 @@ void Eval::evaluatePostfixStack ( // If there is more than one variant left on the stack, then the original // expression was not valid. if (values.size () != 1) - throw std::string (STRING_EVAL_NO_EVAL); + throw std::string ("The value is not an expression."); result = values[0]; } @@ -795,7 +794,7 @@ void Eval::infixToPostfix ( { if (op_stack.back ().first == "(" || op_stack.back ().first == ")") - throw std::string (STRING_PAREN_MISMATCH); + throw std::string ("Mismatched parentheses in expression"); postfix.push_back (op_stack.back ()); op_stack.pop_back (); diff --git a/src/Eval.h b/src/Eval.h index abf53a45f..c65c628f4 100644 --- a/src/Eval.h +++ b/src/Eval.h @@ -1,6 +1,6 @@ //////////////////////////////////////////////////////////////////////////////// // -// Copyright 2013 - 2016, Paul Beckingham, Federico Hernandez. +// Copyright 2013 - 2020, 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 @@ -20,7 +20,7 @@ // 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 +// https://www.opensource.org/licenses/mit-license.php // //////////////////////////////////////////////////////////////////////////////// diff --git a/src/FS.cpp b/src/FS.cpp deleted file mode 100644 index 04a84b80b..000000000 --- a/src/FS.cpp +++ /dev/null @@ -1,972 +0,0 @@ -//////////////////////////////////////////////////////////////////////////////// -// -// Copyright 2006 - 2016, 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 -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#if defined SOLARIS || defined NETBSD || defined FREEBSD -#include -#endif - -#if defined __APPLE__ -#include -#endif - -// Fixes build with musl libc. -#ifndef GLOB_TILDE -#define GLOB_TILDE 0 -#endif - -#ifndef GLOB_BRACE -#define GLOB_BRACE 0 -#endif - -//////////////////////////////////////////////////////////////////////////////// -Path::Path () -{ -} - -//////////////////////////////////////////////////////////////////////////////// -Path::Path (const Path& other) -{ - if (this != &other) - { - _original = other._original; - _data = other._data; - } -} - -//////////////////////////////////////////////////////////////////////////////// -Path::Path (const std::string& in) -{ - _original = in; - _data = expand (in); -} - -//////////////////////////////////////////////////////////////////////////////// -Path& Path::operator= (const Path& other) -{ - if (this != &other) - { - this->_original = other._original; - this->_data = other._data; - } - - return *this; -} - -//////////////////////////////////////////////////////////////////////////////// -bool Path::operator== (const Path& other) -{ - return _data == other._data; -} - -//////////////////////////////////////////////////////////////////////////////// -Path& Path::operator+= (const std::string& dir) -{ - _data += "/" + dir; - return *this; -} - -//////////////////////////////////////////////////////////////////////////////// -Path::operator std::string () const -{ - return _data; -} - -//////////////////////////////////////////////////////////////////////////////// -std::string Path::name () const -{ - if (_data.length ()) - { - auto slash = _data.rfind ('/'); - if (slash != std::string::npos) - return _data.substr (slash + 1, std::string::npos); - } - - return _data; -} - -//////////////////////////////////////////////////////////////////////////////// -std::string Path::parent () const -{ - if (_data.length ()) - { - auto slash = _data.rfind ('/'); - if (slash != std::string::npos) - return _data.substr (0, slash); - } - - return ""; -} - -//////////////////////////////////////////////////////////////////////////////// -std::string Path::extension () const -{ - if (_data.length ()) - { - auto dot = _data.rfind ('.'); - if (dot != std::string::npos) - return _data.substr (dot + 1, std::string::npos); - } - - return ""; -} - -//////////////////////////////////////////////////////////////////////////////// -bool Path::exists () const -{ - return access (_data.c_str (), F_OK) ? false : true; -} - -//////////////////////////////////////////////////////////////////////////////// -bool Path::is_directory () const -{ - struct stat s {}; - if (! stat (_data.c_str (), &s) && - S_ISDIR (s.st_mode)) - return true; - - return false; -} - -//////////////////////////////////////////////////////////////////////////////// -bool Path::is_absolute () const -{ - if (_data.length () && _data[0] == '/') - return true; - - return false; -} - -//////////////////////////////////////////////////////////////////////////////// -bool Path::is_link () const -{ - struct stat s {}; - if (! lstat (_data.c_str (), &s) && - S_ISLNK (s.st_mode)) - return true; - - return false; -} - -//////////////////////////////////////////////////////////////////////////////// -bool Path::readable () const -{ - return access (_data.c_str (), R_OK) ? false : true; -} - -//////////////////////////////////////////////////////////////////////////////// -bool Path::writable () const -{ - return access (_data.c_str (), W_OK) ? false : true; -} - -//////////////////////////////////////////////////////////////////////////////// -bool Path::executable () const -{ - return access (_data.c_str (), X_OK) ? false : true; -} - -//////////////////////////////////////////////////////////////////////////////// -bool Path::rename (const std::string& new_name) -{ - auto expanded = expand (new_name); - if (_data != expanded) - { - if (std::rename (_data.c_str (), expanded.c_str ()) == 0) - { - _data = expanded; - return true; - } - } - - return false; -} - -//////////////////////////////////////////////////////////////////////////////// -// ~ --> /home/user -// ~foo/x --> /home/foo/s -// ~/x --> /home/foo/x -// ./x --> $PWD/x -// x --> $PWD/x -std::string Path::expand (const std::string& in) -{ - std::string copy = in; - - auto tilde = copy.find ("~"); - std::string::size_type slash; - - if (tilde != std::string::npos) - { - const char *home = getenv("HOME"); - if (home == nullptr) - { - struct passwd* pw = getpwuid (getuid ()); - home = pw->pw_dir; - } - - // Convert: ~ --> /home/user - if (copy.length () == 1) - copy = home; - - // Convert: ~/x --> /home/user/x - else if (copy.length () > tilde + 1 && - copy[tilde + 1] == '/') - { - copy.replace (tilde, 1, home); - } - - // Convert: ~foo/x --> /home/foo/x - else if ((slash = copy.find ("/", tilde)) != std::string::npos) - { - std::string name = copy.substr (tilde + 1, slash - tilde - 1); - struct passwd* pw = getpwnam (name.c_str ()); - if (pw) - copy.replace (tilde, slash - tilde, pw->pw_dir); - } - } - - // Relative paths - else if (in.length () > 2 && - in.substr (0, 2) == "./") - { - copy = Directory::cwd () + in.substr (1); - } - else if (in.length () > 1 && - in[0] != '.' && - in[0] != '/') - { - copy = Directory::cwd () + "/" + in; - } - - return copy; -} - -//////////////////////////////////////////////////////////////////////////////// -std::vector Path::glob (const std::string& pattern) -{ - std::vector results; - - glob_t g; -#ifdef SOLARIS - if (!::glob (pattern.c_str (), GLOB_ERR, nullptr, &g)) -#else - if (!::glob (pattern.c_str (), GLOB_ERR | GLOB_BRACE | GLOB_TILDE, nullptr, &g)) -#endif - for (int i = 0; i < (int) g.gl_pathc; ++i) - results.push_back (g.gl_pathv[i]); - - globfree (&g); - return results; -} - -//////////////////////////////////////////////////////////////////////////////// -File::File () -: Path::Path () -, _fh (nullptr) -, _h (-1) -, _locked (false) -{ -} - -//////////////////////////////////////////////////////////////////////////////// -File::File (const Path& other) -: Path::Path (other) -, _fh (nullptr) -, _h (-1) -, _locked (false) -{ -} - -//////////////////////////////////////////////////////////////////////////////// -File::File (const File& other) -: Path::Path (other) -, _fh (nullptr) -, _h (-1) -, _locked (false) -{ -} - -//////////////////////////////////////////////////////////////////////////////// -File::File (const std::string& in) -: Path::Path (in) -, _fh (nullptr) -, _h (-1) -, _locked (false) -{ -} - -//////////////////////////////////////////////////////////////////////////////// -File::~File () -{ - if (_fh) - close (); -} - -//////////////////////////////////////////////////////////////////////////////// -File& File::operator= (const File& other) -{ - if (this != &other) - Path::operator= (other); - - _locked = false; - return *this; -} - -//////////////////////////////////////////////////////////////////////////////// -bool File::create (int mode /* = 0640 */) -{ - if (open ()) - { - fchmod (_h, mode); - close (); - return true; - } - - return false; -} - -//////////////////////////////////////////////////////////////////////////////// -bool File::remove () const -{ - return unlink (_data.c_str ()) == 0 ? true : false; -} - -//////////////////////////////////////////////////////////////////////////////// -std::string File::removeBOM (const std::string& input) -{ - if (input[0] && input[0] == '\xEF' && - input[1] && input[1] == '\xBB' && - input[2] && input[2] == '\xBF') - return input.substr (3); - - return input; -} - -//////////////////////////////////////////////////////////////////////////////// -bool File::open () -{ - if (_data != "") - { - if (! _fh) - { - bool already_exists = exists (); - if (already_exists) - if (!readable () || !writable ()) - throw std::string (format (STRING_FILE_PERMS, _data)); - - _fh = fopen (_data.c_str (), (already_exists ? "r+" : "w+")); - if (_fh) - { - _h = fileno (_fh); - _locked = false; - return true; - } - } - else - return true; - } - - return false; -} - -//////////////////////////////////////////////////////////////////////////////// -void File::close () -{ - if (_fh) - { - if (_locked) - unlock (); - - fclose (_fh); - _fh = nullptr; - _h = -1; - _locked = false; - } -} - -//////////////////////////////////////////////////////////////////////////////// -bool File::lock () -{ - _locked = false; - if (_fh && _h != -1) - { - // l_type l_whence l_start l_len l_pid - struct flock fl = {F_WRLCK, SEEK_SET, 0, 0, 0 }; - fl.l_pid = getpid (); - if (fcntl (_h, F_SETLKW, &fl) == 0) - _locked = true; - } - - return _locked; -} - -//////////////////////////////////////////////////////////////////////////////// -void File::unlock () -{ - if (_locked) - { - // l_type l_whence l_start l_len l_pid - struct flock fl = {F_UNLCK, SEEK_SET, 0, 0, 0 }; - fl.l_pid = getpid (); - - fcntl (_h, F_SETLK, &fl); - _locked = false; - } -} - -//////////////////////////////////////////////////////////////////////////////// -// Opens if necessary. -void File::read (std::string& contents) -{ - contents = ""; - contents.reserve (size ()); - - std::ifstream in (_data.c_str ()); - if (in.good ()) - { - bool first = true; - std::string line; - line.reserve (512 * 1024); - while (getline (in, line)) - { - // Detect forbidden BOM on first line. - if (first) - { - line = File::removeBOM (line); - first = false; - } - - contents += line + "\n"; - } - - in.close (); - } -} - -//////////////////////////////////////////////////////////////////////////////// -// Opens if necessary. -void File::read (std::vector & contents) -{ - contents.clear (); - - std::ifstream in (_data.c_str ()); - if (in.good ()) - { - bool first = true; - std::string line; - line.reserve (512 * 1024); - while (getline (in, line)) - { - // Detect forbidden BOM on first line. - if (first) - { - line = File::removeBOM (line); - first = false; - } - - contents.push_back (line); - } - - in.close (); - } -} - -//////////////////////////////////////////////////////////////////////////////// -// Opens if necessary. -void File::append (const std::string& line) -{ - if (!_fh) - open (); - - if (_fh) - { - fseek (_fh, 0, SEEK_END); - fputs (line.c_str (), _fh); - } -} - -//////////////////////////////////////////////////////////////////////////////// -// Opens if necessary. -void File::append (const std::vector & lines) -{ - if (!_fh) - open (); - - if (_fh) - { - fseek (_fh, 0, SEEK_END); - for (auto& line : lines) - fputs (line.c_str (), _fh); - } -} - -//////////////////////////////////////////////////////////////////////////////// -void File::write_raw (const std::string& line) -{ - if (!_fh) - open (); - - if (_fh) - fputs (line.c_str (), _fh); -} - -//////////////////////////////////////////////////////////////////////////////// -void File::truncate () -{ - if (!_fh) - open (); - - if (_fh) - (void) ftruncate (_h, 0); -} - -//////////////////////////////////////////////////////////////////////////////// -// S_IFMT 0170000 type of file -// S_IFIFO 0010000 named pipe (fifo) -// S_IFCHR 0020000 character special -// S_IFDIR 0040000 directory -// S_IFBLK 0060000 block special -// S_IFREG 0100000 regular -// S_IFLNK 0120000 symbolic link -// S_IFSOCK 0140000 socket -// S_IFWHT 0160000 whiteout -// S_ISUID 0004000 set user id on execution -// S_ISGID 0002000 set group id on execution -// S_ISVTX 0001000 save swapped text even after use -// S_IRUSR 0000400 read permission, owner -// S_IWUSR 0000200 write permission, owner -// S_IXUSR 0000100 execute/search permission, owner -mode_t File::mode () -{ - struct stat s; - if (!stat (_data.c_str (), &s)) - return s.st_mode; - - return 0; -} - -//////////////////////////////////////////////////////////////////////////////// -size_t File::size () const -{ - struct stat s; - if (!stat (_data.c_str (), &s)) - return s.st_size; - - return 0; -} - -//////////////////////////////////////////////////////////////////////////////// -time_t File::mtime () const -{ - struct stat s; - if (!stat (_data.c_str (), &s)) - return s.st_mtime; - - return 0; -} - -//////////////////////////////////////////////////////////////////////////////// -time_t File::ctime () const -{ - struct stat s; - if (!stat (_data.c_str (), &s)) - return s.st_ctime; - - return 0; -} - -//////////////////////////////////////////////////////////////////////////////// -time_t File::btime () const -{ - struct stat s; - if (!stat (_data.c_str (), &s)) -#ifdef HAVE_ST_BIRTHTIME - return s.st_birthtime; -#else - return s.st_ctime; -#endif - - return 0; -} - -//////////////////////////////////////////////////////////////////////////////// -bool File::create (const std::string& name, int mode /* = 0640 */) -{ - std::string full_name = expand (name); - std::ofstream out (full_name.c_str ()); - if (out.good ()) - { - out.close (); - chmod (full_name.c_str (), mode); - return true; - } - - return false; -} - -//////////////////////////////////////////////////////////////////////////////// -bool File::read (const std::string& name, std::string& contents) -{ - contents = ""; - - std::ifstream in (name.c_str ()); - if (in.good ()) - { - bool first = true; - std::string line; - line.reserve (1024); - while (getline (in, line)) - { - // Detect forbidden BOM on first line. - if (first) - { - line = File::removeBOM (line); - first = false; - } - - contents += line + "\n"; - } - - in.close (); - return true; - } - - return false; -} - -//////////////////////////////////////////////////////////////////////////////// -bool File::read (const std::string& name, std::vector & contents) -{ - contents.clear (); - - std::ifstream in (name.c_str ()); - if (in.good ()) - { - bool first = true; - std::string line; - line.reserve (1024); - while (getline (in, line)) - { - // Detect forbidden BOM on first line. - if (first) - { - line = File::removeBOM (line); - first = false; - } - - contents.push_back (line); - } - - in.close (); - return true; - } - - return false; -} - -//////////////////////////////////////////////////////////////////////////////// -bool File::write (const std::string& name, const std::string& contents) -{ - std::ofstream out (expand (name).c_str (), - std::ios_base::out | std::ios_base::trunc); - if (out.good ()) - { - out << contents; - out.close (); - return true; - } - - return false; -} - -//////////////////////////////////////////////////////////////////////////////// -bool File::write ( - const std::string& name, - const std::vector & lines, - bool addNewlines /* = true */) -{ - std::ofstream out (expand (name).c_str (), - std::ios_base::out | std::ios_base::trunc); - if (out.good ()) - { - for (auto& line : lines) - { - out << line; - - if (addNewlines) - out << "\n"; - } - - out.close (); - return true; - } - - return false; -} - -//////////////////////////////////////////////////////////////////////////////// -bool File::remove (const std::string& name) -{ - return unlink (expand (name).c_str ()) == 0 ? true : false; -} - -//////////////////////////////////////////////////////////////////////////////// -bool File::copy (const std::string& from, const std::string& to) -{ - // 'from' must exist. - if (! access (from.c_str (), F_OK)) - { - std::ifstream src (from, std::ios::binary); - std::ofstream dst (to, std::ios::binary); - - dst << src.rdbuf (); - return true; - } - - return false; -} - -//////////////////////////////////////////////////////////////////////////////// -bool File::move (const std::string& from, const std::string& to) -{ - auto expanded = expand (to); - if (from != expanded) - if (std::rename (from.c_str (), to.c_str ()) == 0) - return true; - - return false; -} - -//////////////////////////////////////////////////////////////////////////////// -Directory::Directory () -{ -} - -//////////////////////////////////////////////////////////////////////////////// -Directory::Directory (const Directory& other) -: File::File (other) -{ -} - -//////////////////////////////////////////////////////////////////////////////// -Directory::Directory (const File& other) -: File::File (other) -{ -} - -//////////////////////////////////////////////////////////////////////////////// -Directory::Directory (const Path& other) -: File::File (other) -{ -} - -//////////////////////////////////////////////////////////////////////////////// -Directory::Directory (const std::string& in) -: File::File (in) -{ -} - -//////////////////////////////////////////////////////////////////////////////// -Directory& Directory::operator= (const Directory& other) -{ - if (this != &other) - File::operator= (other); - - return *this; -} - -//////////////////////////////////////////////////////////////////////////////// -bool Directory::create (int mode /* = 0755 */) -{ - return mkdir (_data.c_str (), mode) == 0 ? true : false; -} - -//////////////////////////////////////////////////////////////////////////////// -bool Directory::remove () const -{ - return remove_directory (_data); -} - -//////////////////////////////////////////////////////////////////////////////// -bool Directory::remove_directory (const std::string& dir) const -{ - DIR* dp = opendir (dir.c_str ()); - if (dp != nullptr) - { - struct dirent* de; - while ((de = readdir (dp)) != nullptr) - { - if (!strcmp (de->d_name, ".") || - !strcmp (de->d_name, "..")) - continue; - -#if defined (SOLARIS) || defined (HAIKU) - struct stat s; - lstat ((dir + "/" + de->d_name).c_str (), &s); - if (S_ISDIR (s.st_mode)) - remove_directory (dir + "/" + de->d_name); - else - unlink ((dir + "/" + de->d_name).c_str ()); -#else - if (de->d_type == DT_UNKNOWN) - { - struct stat s; - lstat ((dir + "/" + de->d_name).c_str (), &s); - if (S_ISDIR (s.st_mode)) - de->d_type = DT_DIR; - } - if (de->d_type == DT_DIR) - remove_directory (dir + "/" + de->d_name); - else - unlink ((dir + "/" + de->d_name).c_str ()); -#endif - } - - closedir (dp); - } - - return rmdir (dir.c_str ()) ? false : true; -} - -//////////////////////////////////////////////////////////////////////////////// -std::vector Directory::list () -{ - std::vector files; - list (_data, files, false); - return files; -} - -//////////////////////////////////////////////////////////////////////////////// -std::vector Directory::listRecursive () -{ - std::vector files; - list (_data, files, true); - return files; -} - -//////////////////////////////////////////////////////////////////////////////// -std::string Directory::cwd () -{ -#ifdef HAVE_GET_CURRENT_DIR_NAME - char *buf = get_current_dir_name (); - if (buf == nullptr) - throw std::bad_alloc (); - std::string result (buf); - free (buf); - return result; -#else - char buf[PATH_MAX]; - getcwd (buf, PATH_MAX - 1); - return std::string (buf); -#endif -} - -//////////////////////////////////////////////////////////////////////////////// -bool Directory::up () -{ - if (_data == "/") - return false; - - auto slash = _data.rfind ('/'); - if (slash == 0) - { - _data = "/"; // Root dir should retain the slash. - return true; - } - else if (slash != std::string::npos) - { - _data = _data.substr (0, slash); - return true; - } - - return false; -} - -//////////////////////////////////////////////////////////////////////////////// -bool Directory::cd () const -{ - return chdir (_data.c_str ()) == 0 ? true : false; -} - -//////////////////////////////////////////////////////////////////////////////// -void Directory::list ( - const std::string& base, - std::vector & results, - bool recursive) -{ - DIR* dp = opendir (base.c_str ()); - if (dp != nullptr) - { - struct dirent* de; - while ((de = readdir (dp)) != nullptr) - { - if (!strcmp (de->d_name, ".") || - !strcmp (de->d_name, "..")) - continue; - -#if defined (SOLARIS) || defined (HAIKU) - struct stat s; - stat ((base + "/" + de->d_name).c_str (), &s); - if (recursive && S_ISDIR (s.st_mode)) - list (base + "/" + de->d_name, results, recursive); - else - results.push_back (base + "/" + de->d_name); -#else - if (recursive && de->d_type == DT_UNKNOWN) - { - struct stat s; - lstat ((base + "/" + de->d_name).c_str (), &s); - if (S_ISDIR (s.st_mode)) - de->d_type = DT_DIR; - } - if (recursive && de->d_type == DT_DIR) - list (base + "/" + de->d_name, results, recursive); - else - results.push_back (base + "/" + de->d_name); -#endif - } - - closedir (dp); - } -} - -//////////////////////////////////////////////////////////////////////////////// diff --git a/src/FS.h b/src/FS.h deleted file mode 100644 index 3d14800e1..000000000 --- a/src/FS.h +++ /dev/null @@ -1,145 +0,0 @@ -//////////////////////////////////////////////////////////////////////////////// -// -// Copyright 2006 - 2016, 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_FS -#define INCLUDED_FS - -#include -#include -#include -#include - -class Path -{ -public: - Path (); - explicit Path (const Path&); - Path (const std::string&); - - Path& operator= (const Path&); - bool operator== (const Path&); - Path& operator+= (const std::string&); - operator std::string () const; - - std::string name () const; - std::string parent () const; - std::string extension () const; - bool exists () const; - bool is_directory () const; - bool is_absolute () const; - bool is_link () const; - bool readable () const; - bool writable () const; - bool executable () const; - bool rename (const std::string&); - - // Statics - static std::string expand (const std::string&); - static std::vector glob (const std::string&); - -public: - std::string _original; - std::string _data; -}; - -class File : public Path -{ -public: - File (); - explicit File (const Path&); - explicit File (const File&); - File (const std::string&); - virtual ~File (); - - File& operator= (const File&); - - virtual bool create (int mode = 0640); - virtual bool remove () const; - - bool open (); - void close (); - - bool lock (); - void unlock (); - - void read (std::string&); - void read (std::vector &); - - void append (const std::string&); - void append (const std::vector &); - void write_raw (const std::string&); - - void truncate (); - - virtual mode_t mode (); - virtual size_t size () const; - virtual time_t mtime () const; - virtual time_t ctime () const; - virtual time_t btime () const; - - static bool create (const std::string&, int mode = 0640); - static bool read (const std::string&, std::string&); - static bool read (const std::string&, std::vector &); - static bool write (const std::string&, const std::string&); - static bool write (const std::string&, const std::vector &, bool addNewlines = true); - static bool remove (const std::string&); - static bool copy (const std::string&, const std::string&); - static bool move (const std::string&, const std::string&); - static std::string removeBOM (const std::string&); - -private: - FILE* _fh; - int _h; - bool _locked; -}; - -class Directory : public File -{ -public: - Directory (); - explicit Directory (const Directory&); - explicit Directory (const File&); - explicit Directory (const Path&); - Directory (const std::string&); - - Directory& operator= (const Directory&); - - virtual bool create (int mode = 0755); - virtual bool remove () const; - - std::vector list (); - std::vector listRecursive (); - - static std::string cwd (); - bool up (); - bool cd () const; - -private: - void list (const std::string&, std::vector &, bool); - bool remove_directory (const std::string&) const; -}; - -#endif diff --git a/src/Filter.cpp b/src/Filter.cpp index a6bcdddb9..321b57aee 100644 --- a/src/Filter.cpp +++ b/src/Filter.cpp @@ -1,6 +1,6 @@ //////////////////////////////////////////////////////////////////////////////// // -// Copyright 2006 - 2016, Paul Beckingham, Federico Hernandez. +// Copyright 2006 - 2020, 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 @@ -20,7 +20,7 @@ // 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 +// https://www.opensource.org/licenses/mit-license.php // //////////////////////////////////////////////////////////////////////////////// @@ -28,15 +28,12 @@ #include #include #include +#include #include #include #include -#include -#include -#include -#include - -extern Context context; +#include +#include //////////////////////////////////////////////////////////////////////////////// // Const iterator that can be derefenced into a Task by domSource. @@ -59,13 +56,13 @@ bool domSource (const std::string& identifier, Variant& value) // Take an input set of tasks and filter into a subset. void Filter::subset (const std::vector & input, std::vector & output) { - context.timer_filter.start (); + Timer timer; _startCount = (int) input.size (); - context.cli2.prepareFilter (); + Context::getContext ().cli2.prepareFilter (); std::vector > precompiled; - for (auto& a : context.cli2._args) + for (auto& a : Context::getContext ().cli2._args) if (a.hasTag ("FILTER")) precompiled.push_back (std::pair (a.getToken (), a._lextype)); @@ -73,11 +70,10 @@ void Filter::subset (const std::vector & input, std::vector & output { Eval eval; eval.addSource (domSource); - eval.addSource (namedDates); // Debug output from Eval during compilation is useful. During evaluation // it is mostly noise. - eval.debug (context.config.getInteger ("debug.parser") >= 3 ? true : false); + eval.debug (Context::getContext ().config.getInteger ("debug.parser") >= 3 ? true : false); eval.compileExpression (precompiled); for (auto& task : input) @@ -97,20 +93,19 @@ void Filter::subset (const std::vector & input, std::vector & output output = input; _endCount = (int) output.size (); - context.debug (format ("Filtered {1} tasks --> {2} tasks [list subset]", _startCount, _endCount)); - context.timer_filter.stop (); + Context::getContext ().debug (format ("Filtered {1} tasks --> {2} tasks [list subset]", _startCount, _endCount)); + Context::getContext ().time_filter_us += timer.total_us (); } //////////////////////////////////////////////////////////////////////////////// // Take the set of all tasks and filter into a subset. void Filter::subset (std::vector & output) { - context.timer_filter.start (); - - context.cli2.prepareFilter (); + Timer timer; + Context::getContext ().cli2.prepareFilter (); std::vector > precompiled; - for (auto& a : context.cli2._args) + for (auto& a : Context::getContext ().cli2._args) if (a.hasTag ("FILTER")) precompiled.push_back (std::pair (a.getToken (), a._lextype)); @@ -119,18 +114,17 @@ void Filter::subset (std::vector & output) if (precompiled.size ()) { - context.timer_filter.stop (); - auto pending = context.tdb2.pending.get_tasks (); - context.timer_filter.start (); + Timer timer_pending; + auto pending = Context::getContext ().tdb2.pending.get_tasks (); + Context::getContext ().time_filter_us -= timer_pending.total_us (); _startCount = (int) pending.size (); Eval eval; eval.addSource (domSource); - eval.addSource (namedDates); // Debug output from Eval during compilation is useful. During evaluation // it is mostly noise. - eval.debug (context.config.getInteger ("debug.parser") >= 3 ? true : false); + eval.debug (Context::getContext ().config.getInteger ("debug.parser") >= 3 ? true : false); eval.compileExpression (precompiled); output.clear (); @@ -148,9 +142,9 @@ void Filter::subset (std::vector & output) shortcut = pendingOnly (); if (! shortcut) { - context.timer_filter.stop (); - auto completed = context.tdb2.completed.get_tasks (); - context.timer_filter.start (); + Timer timer_completed; + auto completed = Context::getContext ().tdb2.completed.get_tasks (); + Context::getContext ().time_filter_us -= timer_completed.total_us (); _startCount += (int) completed.size (); for (auto& task : completed) @@ -170,26 +164,25 @@ void Filter::subset (std::vector & output) else { safety (); - context.timer_filter.stop (); - for (auto& task : context.tdb2.pending.get_tasks ()) + Timer pending_completed; + for (auto& task : Context::getContext ().tdb2.pending.get_tasks ()) output.push_back (task); - for (auto& task : context.tdb2.completed.get_tasks ()) + for (auto& task : Context::getContext ().tdb2.completed.get_tasks ()) output.push_back (task); - - context.timer_filter.start (); + Context::getContext ().time_filter_us -= pending_completed.total_us (); } _endCount = (int) output.size (); - context.debug (format ("Filtered {1} tasks --> {2} tasks [{3}]", _startCount, _endCount, (shortcut ? "pending only" : "all tasks"))); - context.timer_filter.stop (); + Context::getContext ().debug (format ("Filtered {1} tasks --> {2} tasks [{3}]", _startCount, _endCount, (shortcut ? "pending only" : "all tasks"))); + Context::getContext ().time_filter_us += timer.total_us (); } //////////////////////////////////////////////////////////////////////////////// bool Filter::hasFilter () const { - for (const auto& a : context.cli2._args) + for (const auto& a : Context::getContext ().cli2._args) if (a.hasTag ("FILTER")) return true; @@ -203,7 +196,7 @@ bool Filter::hasFilter () const bool Filter::pendingOnly () const { // When GC is off, there are no shortcuts. - if (! context.config.getBoolean ("gc")) + if (! Context::getContext ().config.getBoolean ("gc")) return false; // To skip loading completed.data, there should be: @@ -216,13 +209,13 @@ bool Filter::pendingOnly () const int countPending = 0; int countWaiting = 0; int countRecurring = 0; - int countId = (int) context.cli2._id_ranges.size (); - int countUUID = (int) context.cli2._uuid_list.size (); + int countId = (int) Context::getContext ().cli2._id_ranges.size (); + int countUUID = (int) Context::getContext ().cli2._uuid_list.size (); int countOr = 0; int countXor = 0; int countNot = 0; - for (const auto& a : context.cli2._args) + for (const auto& a : Context::getContext ().cli2._args) { if (a.hasTag ("FILTER")) { @@ -268,7 +261,7 @@ void Filter::safety () const { bool readonly = true; bool filter = false; - for (const auto& a : context.cli2._args) + for (const auto& a : Context::getContext ().cli2._args) { if (a.hasTag ("CMD") && ! a.hasTag ("READONLY")) @@ -281,16 +274,16 @@ void Filter::safety () const if (! readonly && ! filter) { - if (! context.config.getBoolean ("allow.empty.filter")) - throw std::string (STRING_TASK_SAFETY_ALLOW); + if (! Context::getContext ().config.getBoolean ("allow.empty.filter")) + throw std::string ("You did not specify a filter, and with the 'allow.empty.filter' value, no action is taken."); // If user is willing to be asked, this can be avoided. - if (context.config.getBoolean ("confirmation") && - confirm (STRING_TASK_SAFETY_VALVE)) + if (Context::getContext ().config.getBoolean ("confirmation") && + confirm ("This command has no filter, and will modify all (including completed and deleted) tasks. Are you sure?")) return; // Sound the alarm. - throw std::string (STRING_TASK_SAFETY_FAIL); + throw std::string ("Command prevented from running."); } } } diff --git a/src/Filter.h b/src/Filter.h index 604f06ab8..e6ee3a29f 100644 --- a/src/Filter.h +++ b/src/Filter.h @@ -1,6 +1,6 @@ //////////////////////////////////////////////////////////////////////////////// // -// Copyright 2006 - 2016, Paul Beckingham, Federico Hernandez. +// Copyright 2006 - 2020, 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 @@ -20,7 +20,7 @@ // 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 +// https://www.opensource.org/licenses/mit-license.php // //////////////////////////////////////////////////////////////////////////////// diff --git a/src/Hooks.cpp b/src/Hooks.cpp index ff07f28a4..d4f5a3897 100644 --- a/src/Hooks.cpp +++ b/src/Hooks.cpp @@ -1,6 +1,6 @@ //////////////////////////////////////////////////////////////////////////////// // -// Copyright 2006 - 2016, Paul Beckingham, Federico Hernandez. +// Copyright 2006 - 2020, 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 @@ -20,7 +20,7 @@ // 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 +// https://www.opensource.org/licenses/mit-license.php // //////////////////////////////////////////////////////////////////////////////// @@ -39,22 +39,43 @@ #include #include #include +#include #include #include -#include +#include +#include +#include #include -#include -extern Context context; +#define STRING_HOOK_ERROR_OBJECT "Hook Error: JSON Object '{...}' expected from hook script: {1}" +#define STRING_HOOK_ERROR_NODESC "Hook Error: JSON Object missing 'description' attribute from hook script: {1}" +#define STRING_HOOK_ERROR_NOUUID "Hook Error: JSON Object missing 'uuid' attribute from hook script: {1}" +#define STRING_HOOK_ERROR_SYNTAX "Hook Error: JSON syntax error in: {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}, in hook script: {3}" +#define STRING_HOOK_ERROR_SAME1 "Hook Error: JSON must be for the same task: {1}, in hook script: {2}" +#define STRING_HOOK_ERROR_SAME2 "Hook Error: JSON must be for the same task: {1} != {2}, in hook script: {3}" +#define STRING_HOOK_ERROR_NOFEEDBACK "Hook Error: Expected feedback from failing hook script: {1}" //////////////////////////////////////////////////////////////////////////////// void Hooks::initialize () { - _debug = context.config.getInteger ("debug.hooks"); + _debug = Context::getContext ().config.getInteger ("debug.hooks"); + + // Scan + // /hooks + Directory d; + if (Context::getContext ().config.has ("hooks.location")) + { + d = Directory (Context::getContext ().config.get ("hooks.location")); + } + else + { + d = Directory (Context::getContext ().config.get ("data.location")); + d += "hooks"; + } - // Scan /hooks - Directory d (context.config.get ("data.location")); - d += "hooks"; if (d.is_directory () && d.readable ()) { @@ -73,17 +94,17 @@ void Hooks::initialize () name.substr (0, 9) == "on-modify" || name.substr (0, 9) == "on-launch" || name.substr (0, 7) == "on-exit") - context.debug ("Found hook script " + i); + Context::getContext ().debug ("Found hook script " + i); else - context.debug ("Found misnamed hook script " + i); + Context::getContext ().debug ("Found misnamed hook script " + i); } } } } else if (_debug >= 1) - context.debug ("Hook directory not readable: " + d._data); + Context::getContext ().debug ("Hook directory not readable: " + d._data); - _enabled = context.config.getBoolean ("hooks"); + _enabled = Context::getContext ().config.getBoolean ("hooks"); } //////////////////////////////////////////////////////////////////////////////// @@ -111,7 +132,7 @@ void Hooks::onLaunch () const if (! _enabled) return; - context.timer_hooks.start (); + Timer timer; std::vector matchingScripts = scripts ("on-launch"); if (matchingScripts.size ()) @@ -126,25 +147,25 @@ void Hooks::onLaunch () const std::vector outputFeedback; separateOutput (output, outputJSON, outputFeedback); - assertNTasks (outputJSON, 0); + assertNTasks (outputJSON, 0, script); if (status == 0) { for (auto& message : outputFeedback) - context.footnote (message); + Context::getContext ().footnote (message); } else { - assertFeedback (outputFeedback); + assertFeedback (outputFeedback, script); for (auto& message : outputFeedback) - context.error (message); + Context::getContext ().error (message); throw 0; // This is how hooks silently terminate processing. } } } - context.timer_hooks.stop (); + Context::getContext ().time_hooks_us += timer.total_us (); } //////////////////////////////////////////////////////////////////////////////// @@ -164,14 +185,14 @@ void Hooks::onExit () const if (! _enabled) return; - context.timer_hooks.start (); + Timer timer; std::vector matchingScripts = scripts ("on-exit"); if (matchingScripts.size ()) { // Get the set of changed tasks. std::vector tasks; - context.tdb2.get_changes (tasks); + Context::getContext ().tdb2.get_changes (tasks); // Convert to a vector of strings. std::vector input; @@ -188,25 +209,25 @@ void Hooks::onExit () const std::vector outputFeedback; separateOutput (output, outputJSON, outputFeedback); - assertNTasks (outputJSON, 0); + assertNTasks (outputJSON, 0, script); if (status == 0) { for (auto& message : outputFeedback) - context.footnote (message); + Context::getContext ().footnote (message); } else { - assertFeedback (outputFeedback); + assertFeedback (outputFeedback, script); for (auto& message : outputFeedback) - context.error (message); + Context::getContext ().error (message); throw 0; // This is how hooks silently terminate processing. } } } - context.timer_hooks.stop (); + Context::getContext ().time_hooks_us += timer.total_us (); } //////////////////////////////////////////////////////////////////////////////// @@ -226,7 +247,7 @@ void Hooks::onAdd (Task& task) const if (! _enabled) return; - context.timer_hooks.start (); + Timer timer; std::vector matchingScripts = scripts ("on-add"); if (matchingScripts.size ()) @@ -247,21 +268,21 @@ void Hooks::onAdd (Task& task) const if (status == 0) { - assertNTasks (outputJSON, 1); - assertValidJSON (outputJSON); - assertSameTask (outputJSON, task); + assertNTasks (outputJSON, 1, script); + assertValidJSON (outputJSON, script); + assertSameTask (outputJSON, task, script); // Propagate forward to the next script. input[0] = outputJSON[0]; for (auto& message : outputFeedback) - context.footnote (message); + Context::getContext ().footnote (message); } else { - assertFeedback (outputFeedback); + assertFeedback (outputFeedback, script); for (auto& message : outputFeedback) - context.error (message); + Context::getContext ().error (message); throw 0; // This is how hooks silently terminate processing. } @@ -271,7 +292,7 @@ void Hooks::onAdd (Task& task) const task = Task (input[0]); } - context.timer_hooks.stop (); + Context::getContext ().time_hooks_us += timer.total_us (); } //////////////////////////////////////////////////////////////////////////////// @@ -292,7 +313,7 @@ void Hooks::onModify (const Task& before, Task& after) const if (! _enabled) return; - context.timer_hooks.start (); + Timer timer; std::vector matchingScripts = scripts ("on-modify"); if (matchingScripts.size ()) @@ -314,21 +335,21 @@ void Hooks::onModify (const Task& before, Task& after) const if (status == 0) { - assertNTasks (outputJSON, 1); - assertValidJSON (outputJSON); - assertSameTask (outputJSON, before); + assertNTasks (outputJSON, 1, script); + assertValidJSON (outputJSON, script); + assertSameTask (outputJSON, before, script); // Propagate accepted changes forward to the next script. input[1] = outputJSON[0]; for (auto& message : outputFeedback) - context.footnote (message); + Context::getContext ().footnote (message); } else { - assertFeedback (outputFeedback); + assertFeedback (outputFeedback, script); for (auto& message : outputFeedback) - context.error (message); + Context::getContext ().error (message); throw 0; // This is how hooks silently terminate processing. } @@ -337,7 +358,7 @@ void Hooks::onModify (const Task& before, Task& after) const after = Task (input[1]); } - context.timer_hooks.stop (); + Context::getContext ().time_hooks_us += timer.total_us (); } //////////////////////////////////////////////////////////////////////////////// @@ -387,7 +408,9 @@ bool Hooks::isJSON (const std::string& input) const } //////////////////////////////////////////////////////////////////////////////// -void Hooks::assertValidJSON (const std::vector & input) const +void Hooks::assertValidJSON ( + const std::vector & input, + const std::string& script) const { for (auto& i : input) { @@ -395,7 +418,7 @@ void Hooks::assertValidJSON (const std::vector & input) const i[0] != '{' || i[i.length () - 1] != '}') { - context.error (STRING_HOOK_ERROR_OBJECT); + Context::getContext ().error (format (STRING_HOOK_ERROR_OBJECT, Path (script).name ())); throw 0; } @@ -404,19 +427,19 @@ void Hooks::assertValidJSON (const std::vector & input) const json::value* root = json::parse (i); if (root->type () != json::j_object) { - context.error (STRING_HOOK_ERROR_OBJECT); + Context::getContext ().error (format (STRING_HOOK_ERROR_OBJECT, Path (script).name ())); throw 0; } if (((json::object*)root)->_data.find ("description") == ((json::object*)root)->_data.end ()) { - context.error (STRING_HOOK_ERROR_NODESC); + Context::getContext ().error (format (STRING_HOOK_ERROR_NODESC, Path (script).name ())); throw 0; } if (((json::object*)root)->_data.find ("uuid") == ((json::object*)root)->_data.end ()) { - context.error (STRING_HOOK_ERROR_NOUUID); + Context::getContext ().error (format (STRING_HOOK_ERROR_NOUUID, Path (script).name ())); throw 0; } @@ -425,32 +448,38 @@ void Hooks::assertValidJSON (const std::vector & input) const catch (const std::string& e) { - context.error (format (STRING_HOOK_ERROR_SYNTAX, i)); + Context::getContext ().error (format (STRING_HOOK_ERROR_SYNTAX, i)); if (_debug) - context.error (STRING_HOOK_ERROR_JSON + e); + Context::getContext ().error (STRING_HOOK_ERROR_JSON + e); throw 0; } catch (...) { - context.error (STRING_HOOK_ERROR_NOPARSE + i); + Context::getContext ().error (STRING_HOOK_ERROR_NOPARSE + i); throw 0; } } } //////////////////////////////////////////////////////////////////////////////// -void Hooks::assertNTasks (const std::vector & input, unsigned int n) const +void Hooks::assertNTasks ( + const std::vector & input, + unsigned int n, + const std::string& script) const { if (input.size () != n) { - context.error (format (STRING_HOOK_ERROR_BAD_NUM, n, (int) input.size ())); + Context::getContext ().error (format (STRING_HOOK_ERROR_BAD_NUM, n, (int) input.size (), Path (script).name ())); throw 0; } } //////////////////////////////////////////////////////////////////////////////// -void Hooks::assertSameTask (const std::vector & input, const Task& task) const +void Hooks::assertSameTask ( + const std::vector & input, + const Task& task, + const std::string& script) const { std::string uuid = task.get ("uuid"); @@ -463,15 +492,17 @@ void Hooks::assertSameTask (const std::vector & input, const Task& if (u == root_obj->_data.end () || u->second->type () != json::j_string) { - context.error (format (STRING_HOOK_ERROR_SAME1, uuid)); + Context::getContext ().error (format (STRING_HOOK_ERROR_SAME1, uuid, Path (script).name ())); throw 0; } json::string* up = (json::string*) u->second; - std::string json_uuid = json::decode (unquoteText (up->dump ())); + auto text = up->dump (); + Lexer::dequote (text); + std::string json_uuid = json::decode (text); if (json_uuid != uuid) { - context.error (format (STRING_HOOK_ERROR_SAME2, uuid, json_uuid)); + Context::getContext ().error (format (STRING_HOOK_ERROR_SAME2, uuid, json_uuid, Path (script).name ())); throw 0; } @@ -480,7 +511,9 @@ void Hooks::assertSameTask (const std::vector & input, const Task& } //////////////////////////////////////////////////////////////////////////////// -void Hooks::assertFeedback (const std::vector & input) const +void Hooks::assertFeedback ( + const std::vector & input, + const std::string& script) const { bool foundSomething = false; for (auto& i : input) @@ -489,7 +522,7 @@ void Hooks::assertFeedback (const std::vector & input) const if (! foundSomething) { - context.error (STRING_HOOK_ERROR_NOFEEDBACK); + Context::getContext ().error (format (STRING_HOOK_ERROR_NOFEEDBACK, Path (script).name ())); throw 0; } } @@ -507,13 +540,13 @@ std::vector & Hooks::buildHookScriptArgs (std::vector args.push_back ("args:" + std::string (v)); // Command to be executed. - args.push_back ("command:" + context.cli2.getCommand ()); + args.push_back ("command:" + Context::getContext ().cli2.getCommand ()); // rc file used after applying all overrides. - args.push_back ("rc:" + context.rc_file._data); + args.push_back ("rc:" + Context::getContext ().rc_file._data); // Directory containing *.data files. - args.push_back ("data:" + context.data_dir._data); + args.push_back ("data:" + Context::getContext ().data_dir._data); // Taskwarrior version, same as returned by "task --version" args.push_back ("version:" + std::string(VERSION)); @@ -528,13 +561,13 @@ int Hooks::callHookScript ( std::vector & output) const { if (_debug >= 1) - context.debug ("Hook: Calling " + script); + Context::getContext ().debug ("Hook: Calling " + script); if (_debug >= 2) { - context.debug ("Hook: input"); + Context::getContext ().debug ("Hook: input"); for (const auto& i : input) - context.debug (" " + i); + Context::getContext ().debug (" " + i); } std::string inputStr; @@ -545,9 +578,9 @@ int Hooks::callHookScript ( buildHookScriptArgs (args); if (_debug >= 2) { - context.debug ("Hooks: args"); + Context::getContext ().debug ("Hooks: args"); for (const auto& arg: args) - context.debug (" " + arg); + Context::getContext ().debug (" " + arg); } // Measure time for each hook if running in debug @@ -555,25 +588,24 @@ int Hooks::callHookScript ( std::string outputStr; if (_debug >= 2) { - Timer timer_per_hook("Hooks::execute (" + script + ")"); - timer_per_hook.start(); - + Timer timer; status = execute (script, args, inputStr, outputStr); + Context::getContext ().debugTiming (format ("Hooks::execute ({1})", script), timer); } else status = execute (script, args, inputStr, outputStr); - split (output, outputStr, '\n'); + output = split (outputStr, '\n'); if (_debug >= 2) { - context.debug ("Hook: output"); + Context::getContext ().debug ("Hook: output"); for (const auto& i : output) if (i != "") - context.debug (" " + i); + Context::getContext ().debug (" " + i); - context.debug (format ("Hook: Completed with status {1}", status)); - context.debug (" "); // Blank line + Context::getContext ().debug (format ("Hook: Completed with status {1}", status)); + Context::getContext ().debug (" "); // Blank line } return status; diff --git a/src/Hooks.h b/src/Hooks.h index 2c76e292e..a4890d7c3 100644 --- a/src/Hooks.h +++ b/src/Hooks.h @@ -1,6 +1,6 @@ //////////////////////////////////////////////////////////////////////////////// // -// Copyright 2006 - 2016, Paul Beckingham, Federico Hernandez. +// Copyright 2006 - 2020, 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 @@ -20,7 +20,7 @@ // 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 +// https://www.opensource.org/licenses/mit-license.php // //////////////////////////////////////////////////////////////////////////////// @@ -47,10 +47,10 @@ private: std::vector scripts (const std::string&) const; void separateOutput (const std::vector &, std::vector &, std::vector &) const; bool isJSON (const std::string&) const; - void assertValidJSON (const std::vector &) const; - void assertNTasks (const std::vector &, unsigned int) const; - void assertSameTask (const std::vector &, const Task&) const; - void assertFeedback (const std::vector &) const; + void assertValidJSON (const std::vector &, const std::string&) const; + void assertNTasks (const std::vector &, unsigned int, const std::string&) const; + void assertSameTask (const std::vector &, const Task&, const std::string&) const; + void assertFeedback (const std::vector &, const std::string&) const; std::vector & buildHookScriptArgs (std::vector &) const; int callHookScript (const std::string&, const std::vector &, std::vector &) const; diff --git a/src/ISO8601.cpp b/src/ISO8601.cpp deleted file mode 100644 index bf3282627..000000000 --- a/src/ISO8601.cpp +++ /dev/null @@ -1,2069 +0,0 @@ -//////////////////////////////////////////////////////////////////////////////// -// -// Copyright 2006 - 2016, 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 -#include -#include -#include -#include -#include -#include -#include -#ifdef PRODUCT_TASKWARRIOR -#include -#endif -#include -#include -#include - -#define DAY 86400 -#define HOUR 3600 -#define MINUTE 60 -#define SECOND 1 - -static struct -{ - std::string unit; - int seconds; - bool standalone; -} durations[] = -{ - // These are sorted by first character, then length, so that Nibbler::getOneOf - // returns a maximal match. - {"annual", 365 * DAY, true}, - {"biannual", 730 * DAY, true}, - {"bimonthly", 61 * DAY, true}, - {"biweekly", 14 * DAY, true}, - {"biyearly", 730 * DAY, true}, - {"daily", 1 * DAY, true}, - {"days", 1 * DAY, false}, - {"day", 1 * DAY, true}, - {"d", 1 * DAY, false}, - {"fortnight", 14 * DAY, true}, - {"hours", 1 * HOUR, false}, - {"hour", 1 * HOUR, true}, - {"hrs", 1 * HOUR, false}, - {"hr", 1 * HOUR, true}, - {"h", 1 * HOUR, false}, - {"minutes", 1 * MINUTE, false}, - {"minute", 1 * MINUTE, true}, - {"mins", 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, true}, - {"mos", 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, true}, - {"q", 91 * DAY, false}, - {"semiannual", 183 * DAY, true}, - {"sennight", 14 * DAY, false}, - {"seconds", 1 * SECOND, false}, - {"second", 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, false}, - {"wk", 7 * DAY, true}, - {"w", 7 * DAY, false}, - {"yearly", 365 * DAY, true}, - {"years", 365 * DAY, false}, - {"year", 365 * DAY, true}, - {"yrs", 365 * DAY, false}, - {"yr", 365 * DAY, true}, - {"y", 365 * DAY, false}, -}; - -#define NUM_DURATIONS (sizeof (durations) / sizeof (durations[0])) - -std::string ISO8601d::weekstart = STRING_DATE_SUNDAY; -int ISO8601d::minimumMatchLength = 3; -bool ISO8601d::isoEnabled = true; -bool ISO8601p::isoEnabled = true; - -//////////////////////////////////////////////////////////////////////////////// -ISO8601d::ISO8601d () -{ - clear (); - _date = time (NULL); -} - -//////////////////////////////////////////////////////////////////////////////// -ISO8601d::ISO8601d (const std::string& input, const std::string& format /*= ""*/) -{ - clear (); - std::string::size_type start = 0; - if (! parse (input, start, format)) - throw ::format (STRING_DATE_INVALID_FORMAT, input, format); -} - -//////////////////////////////////////////////////////////////////////////////// -ISO8601d::ISO8601d (const time_t t) -{ - clear (); - _date = t; -} - -//////////////////////////////////////////////////////////////////////////////// -ISO8601d::ISO8601d (const int m, const int d, const int y) -{ - clear (); - - // Error if not valid. - struct tm t {}; - t.tm_isdst = -1; // Requests that mktime determine summer time effect. - t.tm_mday = d; - t.tm_mon = m - 1; - t.tm_year = y - 1900; - - _date = mktime (&t); -} - -//////////////////////////////////////////////////////////////////////////////// -ISO8601d::ISO8601d (const int m, const int d, const int y, - const int hr, const int mi, const int se) -{ - clear (); - - // Error if not valid. - struct tm t {}; - t.tm_isdst = -1; // Requests that mktime determine summer time effect. - t.tm_mday = d; - t.tm_mon = m - 1; - t.tm_year = y - 1900; - t.tm_hour = hr; - t.tm_min = mi; - t.tm_sec = se; - - _date = mktime (&t); -} - -//////////////////////////////////////////////////////////////////////////////// -ISO8601d::~ISO8601d () -{ -} - -//////////////////////////////////////////////////////////////////////////////// -// Supported: -// -// result ::= date 'T' time 'Z' # UTC -// | date 'T' time # Local -// | date-ext 'T' time-ext 'Z' # UTC -// | date-ext 'T' time-ext offset-ext # Specified TZ -// | date-ext 'T' time-ext # Local -// | date-ext # Local -// | time-ext 'Z' -// | time-ext offset-ext Not needed -// | time-ext -// ; -// -// date-ext ::= ±YYYYY-MM-DD Νot needed -// | ±YYYYY-Www-D Νot needed -// | ±YYYYY-Www Νot needed -// | ±YYYYY-DDD Νot needed -// | YYYY-MM-DD -// | YYYY-DDD -// | YYYY-Www-D -// | YYYY-Www -// ; -// -// time-ext ::= hh:mm:ss[,ss] -// | hh:mm[,mm] -// | hh[,hh] Ambiguous (number) -// ; -// -// time-utc-ext ::= hh:mm[:ss] 'Z' ; -// -// offset-ext ::= ±hh[:mm] ; -// -// Not yet supported: -// -// recurrence ::= -// | 'R' [n] '/' designated '/' datetime-ext # duration end -// | 'R' [n] '/' designated '/' datetime # duration end -// | 'R' [n] '/' designated # duration -// | 'R' [n] '/' datetime-ext '/' designated # start duration -// | 'R' [n] '/' datetime-ext '/' datetime-ext # start end -// | 'R' [n] '/' datetime '/' designated # start duration -// | 'R' [n] '/' datetime '/' datetime # start end -// ; -// -bool ISO8601d::parse ( - const std::string& input, - std::string::size_type& start, - const std::string& format /* = "" */) -{ - auto i = start; - Nibbler n (input.substr (i)); - - // Parse epoch first, as it's the most common scenario. - if (parse_epoch (n)) - { - // ::validate and ::resolve are not needed in this case. - start = n.cursor (); - return true; - } - - else if (parse_formatted (n, format)) - { - // Check the values and determine time_t. - if (validate ()) - { - start = n.cursor (); - resolve (); - return true; - } - } - - // Allow parse_date_time and parse_date_time_ext regardless of - // ISO8601d::isoEnabled setting, because these formats are relied upon by - // the 'import' command, JSON parser and hook system. - else if (parse_date_time (n) || // Strictest first. - parse_date_time_ext (n) || - (ISO8601d::isoEnabled && - (parse_date_ext (n) || - parse_time_utc_ext (n) || - parse_time_off_ext (n) || - parse_time_ext (n)))) // Time last, as it is the most permissive. - { - // Check the values and determine time_t. - if (validate ()) - { - start = n.cursor (); - resolve (); - return true; - } - } - - else if (parse_named (n)) - { - // ::validate and ::resolve are not needed in this case. - start = n.cursor (); - return true; - } - - return false; -} - -//////////////////////////////////////////////////////////////////////////////// -void ISO8601d::clear () -{ - _year = 0; - _month = 0; - _week = 0; - _weekday = 0; - _julian = 0; - _day = 0; - _seconds = 0; - _offset = 0; - _utc = false; - _date = 0; -} - -//////////////////////////////////////////////////////////////////////////////// -bool ISO8601d::parse_formatted (Nibbler& n, const std::string& format) -{ - // Short-circuit on missing format. - if (format == "") - return false; - - n.save (); - - int month = -1; // So we can check later. - int day = -1; - int year = -1; - int hour = -1; - int minute = -1; - int second = -1; - - // For parsing, unused. - int wday = -1; - int week = -1; - - for (unsigned int f = 0; f < format.length (); ++f) - { - switch (format[f]) - { - case 'm': - if (n.getDigit (month)) - { - if (month == 0) - n.getDigit (month); - - if (month == 1) - if (n.getDigit (month)) - month += 10; - } - else - { - n.restore (); - return false; - } - break; - - case 'M': - if (! n.getDigit2 (month)) - { - n.restore (); - return false; - } - break; - - case 'd': - if (n.getDigit (day)) - { - if (day == 0) - n.getDigit (day); - - if (day == 1 || day == 2 || day == 3) - { - int tens = day; - if (n.getDigit (day)) - day += 10 * tens; - } - } - else - { - n.restore (); - return false; - } - break; - - case 'D': - if (! n.getDigit2 (day)) - { - n.restore (); - return false; - } - break; - - case 'y': - if (! n.getDigit2 (year)) - { - n.restore (); - return false; - } - year += 2000; - break; - - case 'Y': - if (! n.getDigit4 (year)) - { - n.restore (); - return false; - } - break; - - case 'h': - if (n.getDigit (hour)) - { - if (hour == 0) - n.getDigit (hour); - - if (hour == 1 || hour == 2) - { - int tens = hour; - if (n.getDigit (hour)) - hour += 10 * tens; - } - } - else - { - n.restore (); - return false; - } - break; - - case 'H': - if (! n.getDigit2 (hour)) - { - n.restore (); - return false; - } - break; - - case 'n': - if (n.getDigit (minute)) - { - if (minute == 0) - n.getDigit (minute); - - if (minute < 6) - { - int tens = minute; - if (n.getDigit (minute)) - minute += 10 * tens; - } - } - else - { - n.restore (); - return false; - } - break; - - case 'N': - if (! n.getDigit2 (minute)) - { - n.restore (); - return false; - } - break; - - case 's': - if (n.getDigit (second)) - { - if (second == 0) - n.getDigit (second); - - if (second < 6) - { - int tens = second; - if (n.getDigit (second)) - second += 10 * tens; - } - } - else - { - n.restore (); - return false; - } - break; - - case 'S': - if (! n.getDigit2 (second)) - { - n.restore (); - return false; - } - break; - - case 'v': - if (n.getDigit (week)) - { - if (week == 0) - n.getDigit (week); - - if (week < 6) - { - int tens = week; - if (n.getDigit (week)) - week += 10 * tens; - } - } - else - { - n.restore (); - return false; - } - break; - - case 'V': - if (! n.getDigit2 (week)) - { - n.restore (); - return false; - } - break; - - case 'a': - { - auto cursor = n.cursor (); - wday = ISO8601d::dayOfWeek (n.str ().substr (cursor, 3)); - if (wday == -1) - { - n.restore (); - return false; - } - - n.skipN (3); - } - break; - - case 'A': - { - std::string dayName; - if (n.getUntil (format[f + 1], dayName)) - { - wday = ISO8601d::dayOfWeek (Lexer::lowerCase (dayName)); - if (wday == -1) - { - n.restore (); - return false; - } - } - } - break; - - case 'b': - { - auto cursor = n.cursor (); - month = ISO8601d::monthOfYear (n.str ().substr (cursor, 3)); - if (month == -1) - { - n.restore (); - return false; - } - - n.skipN (3); - } - break; - - case 'B': - { - std::string monthName; - if (n.getUntil (format[f + 1], monthName)) - { - month = ISO8601d::monthOfYear (Lexer::lowerCase (monthName)); - if (month == -1) - { - n.restore (); - return false; - } - } - } - break; - - default: - if (! n.skip (format[f])) - { - n.restore (); - return false; - } - break; - } - } - - // It is possible that the format='Y-M-D', and the input is Y-M-DTH:N:SZ, and - // this should not be considered a match. - if (! n.depleted () && ! Lexer::isWhitespace (n.next ())) - { - n.restore (); - return false; - } - - // Missing values are filled in from the current date. - if (year == -1) - { - ISO8601d now; - year = now.year (); - if (month == -1) - { - month = now.month (); - if (day == -1) - { - day = now.day (); - if (hour == -1) - { - hour = now.hour (); - if (minute == -1) - { - minute = now.minute (); - if (second == -1) - second = now.second (); - } - } - } - } - } - - // Any remaining undefined values are assigned defaults. - if (month == -1) month = 1; - if (day == -1) day = 1; - if (hour == -1) hour = 0; - if (minute == -1) minute = 0; - if (second == -1) second = 0; - - _year = year; - _month = month; - _day = day; - _seconds = (hour * 3600) + (minute * 60) + second; - - return true; -} - -//////////////////////////////////////////////////////////////////////////////// -bool ISO8601d::parse_named (Nibbler& n) -{ -#ifdef PRODUCT_TASKWARRIOR - n.save (); - std::string token; - if (n.getUntilWS (token)) - { - Variant v; - if (namedDates (token, v)) - { - _date = v.get_date (); - return true; - } - } - - n.restore (); -#endif - - return false; -} - -//////////////////////////////////////////////////////////////////////////////// -// Valid epoch values are unsigned integers after 1980-01-01T00:00:00Z. This -// restriction means that '12' will not be identified as an epoch date. -bool ISO8601d::parse_epoch (Nibbler& n) -{ - n.save (); - - int epoch; - if (n.getUnsignedInt (epoch) && - n.depleted () && - epoch >= 315532800) - { - _date = static_cast (epoch); - return true; - } - - n.restore (); - return false; -} - -//////////////////////////////////////////////////////////////////////////////// -bool ISO8601d::parse_date_time (Nibbler& n) -{ - n.save (); - int year, month, day, hour, minute, second; - if (n.getDigit4 (year) && - n.getDigit2 (month) && month && - n.getDigit2 (day) && day && - n.skip ('T') && - n.getDigit2 (hour) && - n.getDigit2 (minute) && minute < 60 && - n.getDigit2 (second) && second < 60) - { - if (n.skip ('Z')) - _utc = true; - - _year = year; - _month = month; - _day = day; - _seconds = (((hour * 60) + minute) * 60) + second; - - return true; - } - - _year = 0; - _month = 0; - _day = 0; - _seconds = 0; - - n.restore (); - return false; -} - -//////////////////////////////////////////////////////////////////////////////// -// date-ext 'T' time-ext 'Z' -// date-ext 'T' time-ext offset-ext -// date-ext 'T' time-ext -bool ISO8601d::parse_date_time_ext (Nibbler& n) -{ - n.save (); - if (parse_date_ext (n)) - { - if (n.skip ('T') && - parse_time_ext (n)) - { - if (n.skip ('Z')) - _utc = true; - else if (parse_off_ext (n)) - ; - - if (! Lexer::isDigit (n.next ())) - return true; - } - - // Restore date_ext - _year = 0; - _month = 0; - _week = 0; - _weekday = 0; - _julian = 0; - _day = 0; - } - - n.restore (); - return false; -} - -//////////////////////////////////////////////////////////////////////////////// -// YYYY-MM-DD -// YYYY-DDD -// YYYY-Www-D -// YYYY-Www -bool ISO8601d::parse_date_ext (Nibbler& n) -{ - Nibbler backup (n); - int year; - if (n.getDigit4 (year) && - n.skip ('-')) - { - int month; - int day; - if (n.skip ('W') && - n.getDigit2 (_week) && _week) - { - if (n.skip ('-') && - n.getDigit (_weekday)) - { - } - - _year = year; - if (!Lexer::isDigit (n.next ())) - return true; - } - else if (n.getDigit3 (_julian) && _julian) - { - _year = year; - if (!Lexer::isDigit (n.next ())) - return true; - } - else if (n.getDigit2 (month) && month && - n.skip ('-') && - n.getDigit2 (day) && day) - { - _year = year; - _month = month; - _day = day; - if (!Lexer::isDigit (n.next ())) - return true; - } - } - - n = backup; - return false; -} - -//////////////////////////////////////////////////////////////////////////////// -// ±hh[:mm] -bool ISO8601d::parse_off_ext (Nibbler& n) -{ - Nibbler backup (n); - std::string sign; - if (n.getN (1, sign) && (sign == "+" || sign == "-")) - { - int offset; - int hh; - int mm; - if (n.getDigit2 (hh) && hh <= 12 && - !n.getDigit (mm)) - { - offset = hh * 3600; - - if (n.skip (':')) - { - if (n.getDigit2 (mm) && mm < 60) - { - offset += mm * 60; - } - else - { - n = backup; - return false; - } - } - - _offset = (sign == "-") ? -offset : offset; - if (!Lexer::isDigit (n.next ())) - return true; - } - } - - n = backup; - return false; -} - -//////////////////////////////////////////////////////////////////////////////// -// hh:mm[:ss] -bool ISO8601d::parse_time_ext (Nibbler& n) -{ - Nibbler backup (n); - int seconds = 0; - int hh; - int mm; - int ss; - if (n.getDigit2 (hh) && hh <= 24 && - n.skip (':') && - n.getDigit2 (mm) && mm < 60) - { - seconds = (hh * 3600) + (mm * 60); - - if (n.skip (':')) - { - if (n.getDigit2 (ss) && ss < 60) - { - seconds += ss; - _seconds = seconds; - - if (!Lexer::isDigit (n.next ())) - return true; - } - - n = backup; - return false; - } - - _seconds = seconds; - if (!Lexer::isDigit (n.next ())) - return true; - } - - n = backup; - return false; -} - -//////////////////////////////////////////////////////////////////////////////// -// time-ext 'Z' -bool ISO8601d::parse_time_utc_ext (Nibbler& n) -{ - n.save (); - if (parse_time_ext (n) && - n.skip ('Z')) - { - _utc = true; - if (!Lexer::isDigit (n.next ())) - return true; - } - - n.restore (); - return false; -} - -//////////////////////////////////////////////////////////////////////////////// -// time-ext offset-ext -bool ISO8601d::parse_time_off_ext (Nibbler& n) -{ - Nibbler backup (n); - if (parse_time_ext (n) && - parse_off_ext (n)) - { - if (!Lexer::isDigit (n.next ())) - return true; - } - - n = backup; - return false; -} - -//////////////////////////////////////////////////////////////////////////////// -// Validation via simple range checking. -bool ISO8601d::validate () -{ - // _year; - if ((_year && (_year < 1900 || _year > 2200)) || - (_month && (_month < 1 || _month > 12)) || - (_week && (_week < 1 || _week > 53)) || - (_weekday && (_weekday < 0 || _weekday > 6)) || - (_julian && (_julian < 1 || _julian > ISO8601d::daysInYear (_year))) || - (_day && (_day < 1 || _day > ISO8601d::daysInMonth (_month, _year))) || - (_seconds && (_seconds < 1 || _seconds > 86400)) || - (_offset && (_offset < -86400 || _offset > 86400))) - return false; - - return true; -} - -//////////////////////////////////////////////////////////////////////////////// -// int tm_sec; seconds (0 - 60) -// int tm_min; minutes (0 - 59) -// int tm_hour; hours (0 - 23) -// int tm_mday; day of month (1 - 31) -// int tm_mon; month of year (0 - 11) -// int tm_year; year - 1900 -// int tm_wday; day of week (Sunday = 0) -// int tm_yday; day of year (0 - 365) -// int tm_isdst; is summer time in effect? -// char *tm_zone; abbreviation of timezone name -// long tm_gmtoff; offset from UTC in seconds -void ISO8601d::resolve () -{ - // Don't touch the original values. - int year = _year; - int month = _month; - int week = _week; - int weekday = _weekday; - int julian = _julian; - int day = _day; - int seconds = _seconds; - int offset = _offset; - bool utc = _utc; - - // Get current time. - time_t now = time (NULL); - - // A UTC offset needs to be accommodated. Once the offset is subtracted, - // only local and UTC times remain. - if (offset) - { - seconds -= offset; - now -= offset; - utc = true; - } - - // Get 'now' in the relevant location. - struct tm* t_now = utc ? gmtime (&now) : localtime (&now); - - int seconds_now = (t_now->tm_hour * 3600) + - (t_now->tm_min * 60) + - t_now->tm_sec; - - // Project forward one day if the specified seconds are earlier in the day - // than the current seconds. - if (year == 0 && - month == 0 && - day == 0 && - week == 0 && - weekday == 0 && - seconds < seconds_now) - { - seconds += 86400; - } - - // Convert week + weekday --> julian. - if (week) - { - julian = (week * 7) + weekday - dayOfWeek (year, 1, 4) - 3; - } - - // Provide default values for year, month, day. - else - { - // Default values for year, month, day: - // - // y m d --> y m d - // y m - --> y m 1 - // y - - --> y 1 1 - // - - - --> now now now - // - if (year == 0) - { - year = t_now->tm_year + 1900; - month = t_now->tm_mon + 1; - day = t_now->tm_mday; - } - else - { - if (month == 0) - { - month = 1; - day = 1; - } - else if (day == 0) - day = 1; - } - } - - if (julian) - { - month = 1; - day = julian; - } - - struct tm t {}; - t.tm_isdst = -1; // Requests that mktime/gmtime determine summer time effect. - t.tm_year = year - 1900; - t.tm_mon = month - 1; - t.tm_mday = day; - - if (seconds > 86400) - { - int days = seconds / 86400; - t.tm_mday += days; - seconds %= 86400; - } - - t.tm_hour = seconds / 3600; - t.tm_min = (seconds % 3600) / 60; - t.tm_sec = seconds % 60; - - _date = utc ? timegm (&t) : mktime (&t); -} - -//////////////////////////////////////////////////////////////////////////////// -time_t ISO8601d::toEpoch () const -{ - return _date; -} - -//////////////////////////////////////////////////////////////////////////////// -std::string ISO8601d::toEpochString () const -{ - std::stringstream epoch; - epoch << _date; - return epoch.str (); -} - -//////////////////////////////////////////////////////////////////////////////// -// 19980119T070000Z = YYYYMMDDThhmmssZ -std::string ISO8601d::toISO () const -{ - struct tm* t = gmtime (&_date); - - std::stringstream iso; - iso << std::setw (4) << std::setfill ('0') << t->tm_year + 1900 - << std::setw (2) << std::setfill ('0') << t->tm_mon + 1 - << std::setw (2) << std::setfill ('0') << t->tm_mday - << "T" - << std::setw (2) << std::setfill ('0') << t->tm_hour - << std::setw (2) << std::setfill ('0') << t->tm_min - << std::setw (2) << std::setfill ('0') << t->tm_sec - << "Z"; - - return iso.str (); -} - -//////////////////////////////////////////////////////////////////////////////// -// 1998-01-19T07:00:00 = YYYY-MM-DDThh:mm:ss -std::string ISO8601d::toISOLocalExtended () const -{ - struct tm* t = localtime (&_date); - - std::stringstream iso; - iso << std::setw (4) << std::setfill ('0') << t->tm_year + 1900 - << "-" - << std::setw (2) << std::setfill ('0') << t->tm_mon + 1 - << "-" - << std::setw (2) << std::setfill ('0') << t->tm_mday - << "T" - << std::setw (2) << std::setfill ('0') << t->tm_hour - << ":" - << std::setw (2) << std::setfill ('0') << t->tm_min - << ":" - << std::setw (2) << std::setfill ('0') << t->tm_sec; - - return iso.str (); -} - -//////////////////////////////////////////////////////////////////////////////// -double ISO8601d::toJulian () const -{ - return (_date / 86400.0) + 2440587.5; -} - -//////////////////////////////////////////////////////////////////////////////// -void ISO8601d::toMDY (int& m, int& d, int& y) const -{ - struct tm* t = localtime (&_date); - - m = t->tm_mon + 1; - d = t->tm_mday; - y = t->tm_year + 1900; -} - -//////////////////////////////////////////////////////////////////////////////// -const std::string ISO8601d::toString ( - const std::string& format /*= "m/d/Y" */) const -{ - std::stringstream formatted; - for (unsigned int i = 0; i < format.length (); ++i) - { - int c = format[i]; - switch (c) - { - case 'm': formatted << this->month (); break; - case 'M': formatted << std::setw (2) << std::setfill ('0') << this->month (); break; - case 'd': formatted << this->day (); break; - case 'D': formatted << std::setw (2) << std::setfill ('0') << this->day (); break; - case 'y': formatted << std::setw (2) << std::setfill ('0') << (this->year () % 100); break; - case 'Y': formatted << this->year (); break; - case 'a': formatted << ISO8601d::dayNameShort (dayOfWeek ()); break; - case 'A': formatted << ISO8601d::dayName (dayOfWeek ()); break; - case 'b': formatted << ISO8601d::monthNameShort (month ()); break; - case 'B': formatted << ISO8601d::monthName (month ()); break; - case 'v': formatted << ISO8601d::weekOfYear (ISO8601d::dayOfWeek (ISO8601d::weekstart)); break; - case 'V': formatted << std::setw (2) << std::setfill ('0') << ISO8601d::weekOfYear (ISO8601d::dayOfWeek (ISO8601d::weekstart)); break; - case 'h': formatted << this->hour (); break; - case 'H': formatted << std::setw (2) << std::setfill ('0') << this->hour (); break; - case 'n': formatted << this->minute (); break; - case 'N': formatted << std::setw (2) << std::setfill ('0') << this->minute (); break; - case 's': formatted << this->second (); break; - case 'S': formatted << std::setw (2) << std::setfill ('0') << this->second (); break; - case 'j': formatted << this->dayOfYear (); break; - case 'J': formatted << std::setw (3) << std::setfill ('0') << this->dayOfYear (); break; - default: formatted << static_cast (c); break; - } - } - - return formatted.str (); -} - -//////////////////////////////////////////////////////////////////////////////// -ISO8601d ISO8601d::startOfDay () const -{ - return ISO8601d (month (), day (), year ()); -} - -//////////////////////////////////////////////////////////////////////////////// -ISO8601d ISO8601d::startOfWeek () const -{ - ISO8601d sow (_date); - sow -= (dayOfWeek () * 86400); - return ISO8601d (sow.month (), sow.day (), sow.year ()); -} - -//////////////////////////////////////////////////////////////////////////////// -ISO8601d ISO8601d::startOfMonth () const -{ - return ISO8601d (month (), 1, year ()); -} - -//////////////////////////////////////////////////////////////////////////////// -ISO8601d ISO8601d::startOfYear () const -{ - return ISO8601d (1, 1, year ()); -} - -//////////////////////////////////////////////////////////////////////////////// -bool ISO8601d::valid (const std::string& input, const std::string& format /*= ""*/) -{ - try - { - ISO8601d test (input, format); - } - - catch (...) - { - return false; - } - - return true; -} - -//////////////////////////////////////////////////////////////////////////////// -bool ISO8601d::valid (const int m, const int d, const int y, const int hr, - const int mi, const int se) -{ - if (hr < 0 || hr > 23) - return false; - - if (mi < 0 || mi > 59) - return false; - - if (se < 0 || se > 59) - return false; - - return ISO8601d::valid (m, d, y); -} - -//////////////////////////////////////////////////////////////////////////////// -bool ISO8601d::valid (const int m, const int d, const int y) -{ - // Check that the year is valid. - if (y < 0) - return false; - - // Check that the month is valid. - if (m < 1 || m > 12) - return false; - - // Finally check that the days fall within the acceptable range for this - // month, and whether or not this is a leap year. - if (d < 1 || d > ISO8601d::daysInMonth (m, y)) - return false; - - return true; -} - -//////////////////////////////////////////////////////////////////////////////// -// Julian -bool ISO8601d::valid (const int d, const int y) -{ - // Check that the year is valid. - if (y < 0) - return false; - - if (d < 1 || d > ISO8601d::daysInYear (y)) - return false; - - return true; -} - -//////////////////////////////////////////////////////////////////////////////// -// Static -bool ISO8601d::leapYear (int year) -{ - return ((! (year % 4)) && (year % 100)) || - ! (year % 400); -} - -//////////////////////////////////////////////////////////////////////////////// -// Static -int ISO8601d::daysInMonth (int month, int year) -{ - static int days[12] = {31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31}; - - if (month == 2 && ISO8601d::leapYear (year)) - return 29; - - return days[month - 1]; -} - -//////////////////////////////////////////////////////////////////////////////// -// Static -int ISO8601d::daysInYear (int year) -{ - return ISO8601d::leapYear (year) ? 366 : 365; -} - -//////////////////////////////////////////////////////////////////////////////// -// Static -std::string ISO8601d::monthName (int month) -{ - static const char* months[12] = - { - STRING_DATE_JANUARY, - STRING_DATE_FEBRUARY, - STRING_DATE_MARCH, - STRING_DATE_APRIL, - STRING_DATE_MAY, - STRING_DATE_JUNE, - STRING_DATE_JULY, - STRING_DATE_AUGUST, - STRING_DATE_SEPTEMBER, - STRING_DATE_OCTOBER, - STRING_DATE_NOVEMBER, - STRING_DATE_DECEMBER, - }; - - assert (month > 0); - assert (month <= 12); - return Lexer::ucFirst (months[month - 1]); -} - -//////////////////////////////////////////////////////////////////////////////// -// Static -std::string ISO8601d::monthNameShort (int month) -{ - static const char* months[12] = - { - STRING_DATE_JANUARY, - STRING_DATE_FEBRUARY, - STRING_DATE_MARCH, - STRING_DATE_APRIL, - STRING_DATE_MAY, - STRING_DATE_JUNE, - STRING_DATE_JULY, - STRING_DATE_AUGUST, - STRING_DATE_SEPTEMBER, - STRING_DATE_OCTOBER, - STRING_DATE_NOVEMBER, - STRING_DATE_DECEMBER, - }; - - assert (month > 0); - assert (month <= 12); - return Lexer::ucFirst (months[month - 1]).substr (0, 3); -} - -//////////////////////////////////////////////////////////////////////////////// -// Static -std::string ISO8601d::dayName (int dow) -{ - static const char* days[7] = - { - STRING_DATE_SUNDAY, - STRING_DATE_MONDAY, - STRING_DATE_TUESDAY, - STRING_DATE_WEDNESDAY, - STRING_DATE_THURSDAY, - STRING_DATE_FRIDAY, - STRING_DATE_SATURDAY, - }; - - return Lexer::ucFirst (days[dow]); -} - -//////////////////////////////////////////////////////////////////////////////// -// Static -std::string ISO8601d::dayNameShort (int dow) -{ - static const char* days[7] = - { - STRING_DATE_SUNDAY, - STRING_DATE_MONDAY, - STRING_DATE_TUESDAY, - STRING_DATE_WEDNESDAY, - STRING_DATE_THURSDAY, - STRING_DATE_FRIDAY, - STRING_DATE_SATURDAY, - }; - - return Lexer::ucFirst (days[dow]).substr (0, 3); -} - -//////////////////////////////////////////////////////////////////////////////// -// Static -int ISO8601d::dayOfWeek (const std::string& input) -{ - if (ISO8601d::minimumMatchLength== 0) - ISO8601d::minimumMatchLength = 3; - - if (closeEnough (STRING_DATE_SUNDAY, input, ISO8601d::minimumMatchLength)) return 0; - else if (closeEnough (STRING_DATE_MONDAY, input, ISO8601d::minimumMatchLength)) return 1; - else if (closeEnough (STRING_DATE_TUESDAY, input, ISO8601d::minimumMatchLength)) return 2; - else if (closeEnough (STRING_DATE_WEDNESDAY, input, ISO8601d::minimumMatchLength)) return 3; - else if (closeEnough (STRING_DATE_THURSDAY, input, ISO8601d::minimumMatchLength)) return 4; - else if (closeEnough (STRING_DATE_FRIDAY, input, ISO8601d::minimumMatchLength)) return 5; - else if (closeEnough (STRING_DATE_SATURDAY, input, ISO8601d::minimumMatchLength)) return 6; - - return -1; -} - -//////////////////////////////////////////////////////////////////////////////// -// Using Zeller's Congruence. -// Static -int ISO8601d::dayOfWeek (int year, int month, int day) -{ - int adj = (14 - month) / 12; - int m = month + 12 * adj - 2; - int y = year - adj; - return (day + (13 * m - 1) / 5 + y + y / 4 - y / 100 + y / 400) % 7; -} - -//////////////////////////////////////////////////////////////////////////////// -// Static -int ISO8601d::monthOfYear (const std::string& input) -{ - if (ISO8601d::minimumMatchLength== 0) - ISO8601d::minimumMatchLength= 3; - - if (closeEnough (STRING_DATE_JANUARY, input, ISO8601d::minimumMatchLength)) return 1; - else if (closeEnough (STRING_DATE_FEBRUARY, input, ISO8601d::minimumMatchLength)) return 2; - else if (closeEnough (STRING_DATE_MARCH, input, ISO8601d::minimumMatchLength)) return 3; - else if (closeEnough (STRING_DATE_APRIL, input, ISO8601d::minimumMatchLength)) return 4; - else if (closeEnough (STRING_DATE_MAY, input, ISO8601d::minimumMatchLength)) return 5; - else if (closeEnough (STRING_DATE_JUNE, input, ISO8601d::minimumMatchLength)) return 6; - else if (closeEnough (STRING_DATE_JULY, input, ISO8601d::minimumMatchLength)) return 7; - else if (closeEnough (STRING_DATE_AUGUST, input, ISO8601d::minimumMatchLength)) return 8; - else if (closeEnough (STRING_DATE_SEPTEMBER, input, ISO8601d::minimumMatchLength)) return 9; - else if (closeEnough (STRING_DATE_OCTOBER, input, ISO8601d::minimumMatchLength)) return 10; - else if (closeEnough (STRING_DATE_NOVEMBER, input, ISO8601d::minimumMatchLength)) return 11; - else if (closeEnough (STRING_DATE_DECEMBER, input, ISO8601d::minimumMatchLength)) return 12; - - return -1; -} - -//////////////////////////////////////////////////////////////////////////////// -// Static -int ISO8601d::length (const std::string& format) -{ - int len = 0; - for (auto& i : format) - { - switch (i) - { - case 'm': - case 'M': - case 'd': - case 'D': - case 'y': - case 'v': - case 'V': - case 'h': - case 'H': - case 'n': - case 'N': - case 's': - case 'S': len += 2; break; - case 'b': - case 'j': - case 'J': - case 'a': len += 3; break; - case 'Y': len += 4; break; - case 'A': - case 'B': len += 10; break; - - // Calculate the width, don't assume a single character width. - default: len += mk_wcwidth (i); break; - } - } - - return len; -} - -//////////////////////////////////////////////////////////////////////////////// -int ISO8601d::month () const -{ - struct tm* t = localtime (&_date); - return t->tm_mon + 1; -} - -//////////////////////////////////////////////////////////////////////////////// -int ISO8601d::week () const -{ - return ISO8601d::weekOfYear (ISO8601d::dayOfWeek (ISO8601d::weekstart)); -} - -//////////////////////////////////////////////////////////////////////////////// -int ISO8601d::day () const -{ - struct tm* t = localtime (&_date); - return t->tm_mday; -} - -//////////////////////////////////////////////////////////////////////////////// -int ISO8601d::year () const -{ - struct tm* t = localtime (&_date); - return t->tm_year + 1900; -} - -//////////////////////////////////////////////////////////////////////////////// -int ISO8601d::weekOfYear (int weekStart) const -{ - struct tm* t = localtime (&_date); - char weekStr[3]; - - if (weekStart == 0) - strftime(weekStr, sizeof(weekStr), "%U", t); - else if (weekStart == 1) - strftime(weekStr, sizeof(weekStr), "%V", t); - else - throw std::string (STRING_DATE_BAD_WEEKSTART); - - int weekNumber = atoi (weekStr); - - if (weekStart == 0) - weekNumber += 1; - - return weekNumber; -} - -//////////////////////////////////////////////////////////////////////////////// -int ISO8601d::dayOfWeek () const -{ - struct tm* t = localtime (&_date); - return t->tm_wday; -} - -//////////////////////////////////////////////////////////////////////////////// -int ISO8601d::dayOfYear () const -{ - struct tm* t = localtime (&_date); - return t->tm_yday + 1; -} - -//////////////////////////////////////////////////////////////////////////////// -int ISO8601d::hour () const -{ - struct tm* t = localtime (&_date); - return t->tm_hour; -} - -//////////////////////////////////////////////////////////////////////////////// -int ISO8601d::minute () const -{ - struct tm* t = localtime (&_date); - return t->tm_min; -} - -//////////////////////////////////////////////////////////////////////////////// -int ISO8601d::second () const -{ - struct tm* t = localtime (&_date); - return t->tm_sec; -} - -//////////////////////////////////////////////////////////////////////////////// -bool ISO8601d::operator== (const ISO8601d& rhs) const -{ - return rhs._date == _date; -} - -//////////////////////////////////////////////////////////////////////////////// -bool ISO8601d::operator!= (const ISO8601d& rhs) const -{ - return rhs._date != _date; -} - -//////////////////////////////////////////////////////////////////////////////// -bool ISO8601d::operator< (const ISO8601d& rhs) const -{ - return _date < rhs._date; -} - -//////////////////////////////////////////////////////////////////////////////// -bool ISO8601d::operator> (const ISO8601d& rhs) const -{ - return _date > rhs._date; -} - -//////////////////////////////////////////////////////////////////////////////// -bool ISO8601d::operator<= (const ISO8601d& rhs) const -{ - return _date <= rhs._date; -} - -//////////////////////////////////////////////////////////////////////////////// -bool ISO8601d::operator>= (const ISO8601d& rhs) const -{ - return _date >= rhs._date; -} - -//////////////////////////////////////////////////////////////////////////////// -bool ISO8601d::sameHour (const ISO8601d& rhs) const -{ - return this->year () == rhs.year () && - this->month () == rhs.month () && - this->day () == rhs.day () && - this->hour () == rhs.hour (); -} - -//////////////////////////////////////////////////////////////////////////////// -bool ISO8601d::sameDay (const ISO8601d& rhs) const -{ - return this->year () == rhs.year () && - this->month () == rhs.month () && - this->day () == rhs.day (); -} - -//////////////////////////////////////////////////////////////////////////////// -bool ISO8601d::sameWeek (const ISO8601d& rhs) const -{ - return this->year () == rhs.year () && - this->week () == rhs.week (); -} - -//////////////////////////////////////////////////////////////////////////////// -bool ISO8601d::sameMonth (const ISO8601d& rhs) const -{ - return this->year () == rhs.year () && - this->month () == rhs.month (); -} - -//////////////////////////////////////////////////////////////////////////////// -bool ISO8601d::sameYear (const ISO8601d& rhs) const -{ - return this->year () == rhs.year (); -} - -//////////////////////////////////////////////////////////////////////////////// -ISO8601d ISO8601d::operator+ (const int delta) -{ - return ISO8601d (_date + delta); -} - -//////////////////////////////////////////////////////////////////////////////// -ISO8601d ISO8601d::operator- (const int delta) -{ - return ISO8601d (_date - delta); -} - -//////////////////////////////////////////////////////////////////////////////// -ISO8601d& ISO8601d::operator+= (const int delta) -{ - _date += (time_t) delta; - return *this; -} - -//////////////////////////////////////////////////////////////////////////////// -ISO8601d& ISO8601d::operator-= (const int delta) -{ - _date -= (time_t) delta; - return *this; -} - -//////////////////////////////////////////////////////////////////////////////// -time_t ISO8601d::operator- (const ISO8601d& rhs) -{ - return _date - rhs._date; -} - -//////////////////////////////////////////////////////////////////////////////// -// Prefix decrement by one day. -void ISO8601d::operator-- () -{ - ISO8601d yesterday = startOfDay () - 1; - yesterday = ISO8601d (yesterday.month (), - yesterday.day (), - yesterday.year (), - hour (), - minute (), - second ()); - _date = yesterday._date; -} - -//////////////////////////////////////////////////////////////////////////////// -// Postfix decrement by one day. -void ISO8601d::operator-- (int) -{ - ISO8601d yesterday = startOfDay () - 1; - yesterday = ISO8601d (yesterday.month (), - yesterday.day (), - yesterday.year (), - hour (), - minute (), - second ()); - _date = yesterday._date; -} - -//////////////////////////////////////////////////////////////////////////////// -// Prefix increment by one day. -void ISO8601d::operator++ () -{ - ISO8601d tomorrow = (startOfDay () + 90001).startOfDay (); - tomorrow = ISO8601d (tomorrow.month (), - tomorrow.day (), - tomorrow.year (), - hour (), - minute (), - second ()); - _date = tomorrow._date; -} - -//////////////////////////////////////////////////////////////////////////////// -// Postfix increment by one day. -void ISO8601d::operator++ (int) -{ - ISO8601d tomorrow = (startOfDay () + 90001).startOfDay (); - tomorrow = ISO8601d (tomorrow.month (), - tomorrow.day (), - tomorrow.year (), - hour (), - minute (), - second ()); - _date = tomorrow._date; -} - -//////////////////////////////////////////////////////////////////////////////// -/* -std::string ISO8601d::dump () const -{ - std::stringstream s; - s << "ISO8601d" - << " y" << _year - << " m" << _month - << " w" << _week - << " wd" << _weekday - << " j" << _julian - << " d" << _day - << " s" << _seconds - << " off" << _offset - << " utc" << _utc - << " =" << _date - << " " << (_date ? toISO () : ""); - - return s.str (); -} -*/ - -//////////////////////////////////////////////////////////////////////////////// -ISO8601p::ISO8601p () -{ - clear (); -} - -//////////////////////////////////////////////////////////////////////////////// -ISO8601p::ISO8601p (time_t input) -{ - clear (); - _period = input; -} - -//////////////////////////////////////////////////////////////////////////////// -ISO8601p::ISO8601p (const std::string& input) -{ - clear (); - - if (Lexer::isAllDigits (input)) - { - time_t value = (time_t) strtol (input.c_str (), NULL, 10); - if (value == 0 || value > 60) - { - _period = value; - return; - } - } - - std::string::size_type idx = 0; - parse (input, idx); -} - -//////////////////////////////////////////////////////////////////////////////// -ISO8601p::~ISO8601p () -{ -} - -//////////////////////////////////////////////////////////////////////////////// -ISO8601p& ISO8601p::operator= (const ISO8601p& other) -{ - if (this != &other) - { - _year = other._year; - _month = other._month; - _day = other._day; - _hours = other._hours; - _minutes = other._minutes; - _seconds = other._seconds; - _period = other._period; - } - - return *this; -} - -//////////////////////////////////////////////////////////////////////////////// -bool ISO8601p::operator< (const ISO8601p& other) -{ - return _period < other._period; -} - -//////////////////////////////////////////////////////////////////////////////// -bool ISO8601p::operator> (const ISO8601p& other) -{ - return _period > other._period; -} - -//////////////////////////////////////////////////////////////////////////////// -ISO8601p::operator std::string () const -{ - std::stringstream s; - s << _period; - return s.str (); -} - -//////////////////////////////////////////////////////////////////////////////// -ISO8601p::operator time_t () const -{ - return _period; -} - -//////////////////////////////////////////////////////////////////////////////// -// Supported: -// -// duration ::= designated # duration -// -// designated ::= 'P' [nn 'Y'] [nn 'M'] [nn 'D'] ['T' [nn 'H'] [nn 'M'] [nn 'S']] -// -// Not supported: -// -// duration ::= designated '/' datetime-ext # duration end -// | degignated '/' datetime # duration end -// | designated # duration -// | 'P' datetime-ext '/' datetime-ext # start end -// | 'P' datetime '/' datetime # start end -// | 'P' datetime-ext # start -// | 'P' datetime # start -// | datetime-ext '/' designated # start duration -// | datetime-ext '/' 'P' datetime-ext # start end -// | datetime-ext '/' datetime-ext # start end -// | datetime '/' designated # start duration -// | datetime '/' 'P' datetime # start end -// | datetime '/' datetime # start end -// ; -// -bool ISO8601p::parse (const std::string& input, std::string::size_type& start) -{ - // Attempt and ISO parse first. - auto original_start = start; - Nibbler n (input.substr (original_start)); - n.save (); - - if (parse_designated (n)) - { - // Check the values and determine time_t. - if (validate ()) - { - // Record cursor position. - start = n.cursor (); - - resolve (); - return true; - } - } - - // Attempt a legacy format parse next. - n.restore (); - - // Static and so preserved between calls. - static std::vector 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; - - if (n.getOneOf (units, unit)) - { - if (n.depleted () || - Lexer::isWhitespace (n.next ()) || - Lexer::isSingleCharOperator (n.next ())) - { - start = original_start + n.cursor (); - - // Linear lookup - should instead be logarithmic. - for (unsigned int i = 0; i < NUM_DURATIONS; i++) - { - if (durations[i].unit == unit && - durations[i].standalone == true) - { - _period = static_cast (durations[i].seconds); - return true; - } - } - } - } - - else if (n.getNumber (number) && - number.find ('e') == std::string::npos && - number.find ('E') == std::string::npos && - (number.find ('+') == std::string::npos || number.find ('+') == 0) && - (number.find ('-') == std::string::npos || number.find ('-') == 0)) - { - n.skipWS (); - if (n.getOneOf (units, unit)) - { - // The "d" unit is a special case, because it is the only one that can - // legitimately occur at the beginning of a UUID, and be followed by an - // operator: - // - // 1111111d-0000-0000-0000-000000000000 - // - // Because Lexer::isDuration is higher precedence than Lexer::isUUID, - // the above UUID looks like: - // - // <1111111d> <-> ... - // duration op ... - // - // So as a special case, durations, with units of "d" are rejected if the - // quantity exceeds 10000. - // - if (unit == "d" && - strtol (number.c_str (), NULL, 10) > 10000) - return false; - - if (n.depleted () || - Lexer::isWhitespace (n.next ()) || - Lexer::isSingleCharOperator (n.next ())) - { - start = original_start + n.cursor (); - double quantity = strtod (number.c_str (), NULL); - - // Linear lookup - should instead be logarithmic. - double seconds = 1; - for (unsigned int i = 0; i < NUM_DURATIONS; i++) - { - if (durations[i].unit == unit) - { - seconds = durations[i].seconds; - _period = static_cast (quantity * static_cast (seconds)); - return true; - } - } - } - } - } - - return false; -} - -//////////////////////////////////////////////////////////////////////////////// -void ISO8601p::clear () -{ - _year = 0; - _month = 0; - _day = 0; - _hours = 0; - _minutes = 0; - _seconds = 0; - _period = 0; -} - -//////////////////////////////////////////////////////////////////////////////// -const std::string ISO8601p::format () const -{ - if (_period) - { - time_t t = _period; - int seconds = t % 60; t /= 60; - int minutes = t % 60; t /= 60; - int hours = t % 24; t /= 24; - int days = t; - - std::stringstream s; - s << 'P'; - if (days) s << days << 'D'; - - if (hours || minutes || seconds) - { - s << 'T'; - if (hours) s << hours << 'H'; - if (minutes) s << minutes << 'M'; - if (seconds) s << seconds << 'S'; - } - - return s.str (); - } - else - { - return "PT0S"; - } -} - -//////////////////////////////////////////////////////////////////////////////// -// Range Representation -// --------- --------------------- -// >= 365d {n.n}y -// >= 90d {n}mo -// >= 14d {n}w -// >= 1d {n}d -// >= 1h {n}h -// >= 1min {n}min -// {n}s -// -const std::string ISO8601p::formatVague () const -{ - float days = (float) _period / 86400.0; - - std::stringstream formatted; - if (_period >= 86400 * 365) formatted << std::fixed << std::setprecision (1) << (days / 365) << "y"; - else if (_period >= 86400 * 90) formatted << static_cast (days / 30) << "mo"; - else if (_period >= 86400 * 14) formatted << static_cast (days / 7) << "w"; - else if (_period >= 86400) formatted << static_cast (days) << "d"; - else if (_period >= 3600) formatted << static_cast (_period / 3600) << "h"; - else if (_period >= 60) formatted << static_cast (_period / 60) << "min"; - else if (_period >= 1) formatted << static_cast (_period) << "s"; - - return formatted.str (); -} - -//////////////////////////////////////////////////////////////////////////////// -// 'P' [nn 'Y'] [nn 'M'] [nn 'D'] ['T' [nn 'H'] [nn 'M'] [nn 'S']] -bool ISO8601p::parse_designated (Nibbler& n) -{ - Nibbler backup (n); - - if (n.skip ('P')) - { - int value; - n.save (); - if (n.getUnsignedInt (value) && n.skip ('Y')) - _year = value; - else - n.restore (); - - n.save (); - if (n.getUnsignedInt (value) && n.skip ('M')) - _month = value; - else - n.restore (); - - n.save (); - if (n.getUnsignedInt (value) && n.skip ('D')) - _day = value; - else - n.restore (); - - if (n.skip ('T')) - { - n.save (); - if (n.getUnsignedInt (value) && n.skip ('H')) - _hours = value; - else - n.restore (); - - n.save (); - if (n.getUnsignedInt (value) && n.skip ('M')) - _minutes = value; - else - n.restore (); - - n.save (); - if (n.getUnsignedInt (value) && n.skip ('S')) - _seconds = value; - else - n.restore (); - } - - return true; - } - - n = backup; - return false; -} - -//////////////////////////////////////////////////////////////////////////////// -bool ISO8601p::validate () -{ - return _year || - _month || - _day || - _hours || - _minutes || - _seconds; -} - -//////////////////////////////////////////////////////////////////////////////// -// Allow un-normalized values. -void ISO8601p::resolve () -{ - _period = (_year * 365 * 86400) + - (_month * 30 * 86400) + - (_day * 86400) + - (_hours * 3600) + - (_minutes * 60) + - _seconds; -} - -//////////////////////////////////////////////////////////////////////////////// -/* -std::string ISO8601p::dump () const -{ - std::stringstream s; - s << "ISO8601p" - << " y" << _year - << " mo" << _month - << " d" << _day - << " h" << _hours - << " mi" << _minutes - << " s" << _seconds - << " =" << _period - << " " << (_period ? format () : ""); - - return s.str (); -} -*/ - -//////////////////////////////////////////////////////////////////////////////// diff --git a/src/ISO8601.h b/src/ISO8601.h deleted file mode 100644 index c7b7cd027..000000000 --- a/src/ISO8601.h +++ /dev/null @@ -1,178 +0,0 @@ -//////////////////////////////////////////////////////////////////////////////// -// -// Copyright 2006 - 2016, 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_ISO8601 -#define INCLUDED_ISO8601 - -#include -#include - -// Date -class ISO8601d -{ -public: - static std::string weekstart; - static int minimumMatchLength; - static bool isoEnabled; - - ISO8601d (); - ISO8601d (const std::string&, const std::string& format = ""); - ISO8601d (time_t); - ISO8601d (const int, const int, const int); - ISO8601d (const int, const int, const int, const int, const int, const int); - ~ISO8601d (); - bool parse (const std::string&, std::string::size_type&, const std::string& format = ""); - - time_t toEpoch () const; - std::string toEpochString () const; - std::string toISO () const; - std::string toISOLocalExtended () const; - double toJulian () const; - void toMDY (int&, int&, int&) const; - const std::string toString (const std::string& format = "m/d/Y") const; - - ISO8601d startOfDay () const; - ISO8601d startOfWeek () const; - ISO8601d startOfMonth () const; - ISO8601d startOfYear () const; - - static bool valid (const std::string&, const std::string& format = ""); - static bool valid (const int, const int, const int, const int, const int, const int); - static bool valid (const int, const int, const int); - static bool valid (const int, const int); - static bool leapYear (int); - static int daysInMonth (int, int); - static int daysInYear (int); - static std::string monthName (int); - static std::string monthNameShort (int); - static std::string dayName (int); - static std::string dayNameShort (int); - static int dayOfWeek (const std::string&); - static int dayOfWeek (int, int, int); - static int monthOfYear (const std::string&); - static int length (const std::string&); - - int month () const; - int week () const; - int day () const; - int year () const; - int weekOfYear (int) const; - int dayOfWeek () const; - int dayOfYear () const; - int hour () const; - int minute () const; - int second () const; - - bool operator== (const ISO8601d&) const; - bool operator!= (const ISO8601d&) const; - bool operator< (const ISO8601d&) const; - bool operator> (const ISO8601d&) const; - bool operator<= (const ISO8601d&) const; - bool operator>= (const ISO8601d&) const; - bool sameHour (const ISO8601d&) const; - bool sameDay (const ISO8601d&) const; - bool sameWeek (const ISO8601d&) const; - bool sameMonth (const ISO8601d&) const; - bool sameYear (const ISO8601d&) const; - ISO8601d operator+ (const int); - ISO8601d operator- (const int); - ISO8601d& operator+= (const int); - ISO8601d& operator-= (const int); - time_t operator- (const ISO8601d&); - void operator-- (); // Prefix - void operator-- (int); // Postfix - void operator++ (); // Prefix - void operator++ (int); // Postfix - -private: - void clear (); - bool parse_formatted (Nibbler&, const std::string&); - bool parse_named (Nibbler&); - bool parse_epoch (Nibbler&); - bool parse_date_time (Nibbler&); - bool parse_date_time_ext (Nibbler&); - bool parse_date_ext (Nibbler&); - bool parse_off_ext (Nibbler&); - bool parse_time_ext (Nibbler&); - bool parse_time_utc_ext (Nibbler&); - bool parse_time_off_ext (Nibbler&); - bool validate (); - void resolve (); - std::string dump () const; - -public: - int _year; - int _month; - int _week; - int _weekday; - int _julian; - int _day; - int _seconds; - int _offset; - bool _utc; - time_t _date; -}; - -// Period -class ISO8601p -{ -public: - static bool isoEnabled; - - ISO8601p (); - ISO8601p (time_t); - ISO8601p (const std::string&); - ~ISO8601p (); - ISO8601p (const ISO8601p&); // Unimplemented - ISO8601p& operator= (const ISO8601p&); - bool operator< (const ISO8601p&); - bool operator> (const ISO8601p&); - operator std::string () const; - operator time_t () const; - bool parse (const std::string&, std::string::size_type&); - const std::string format () const; - const std::string formatVague () const; - -private: - void clear (); - bool parse_designated (Nibbler&); - bool validate (); - void resolve (); - std::string dump () const; - -public: - int _year; - int _month; - int _day; - int _hours; - int _minutes; - int _seconds; - time_t _period; -}; - -#endif - -//////////////////////////////////////////////////////////////////////////////// diff --git a/src/JSON.cpp b/src/JSON.cpp deleted file mode 100644 index a18256362..000000000 --- a/src/JSON.cpp +++ /dev/null @@ -1,494 +0,0 @@ -//////////////////////////////////////////////////////////////////////////////// -// -// Copyright 2006 - 2016, 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 -#include -#include -#include -#include - -const char *json_encode[] = { - "\x00", "\x01", "\x02", "\x03", "\x04", "\x05", "\x06", "\x07", - "\\b", "\\t", "\\n", "\x0b", "\\f", "\\r", "\x0e", "\x0f", - "\x10", "\x11", "\x12", "\x13", "\x14", "\x15", "\x16", "\x17", - "\x18", "\x19", "\x1a", "\x1b", "\x1c", "\x1d", "\x1e", "\x1f", - "\x20", "\x21", "\\\"", "\x23", "\x24", "\x25", "\x26", "\x27", - "\x28", "\x29", "\x2a", "\x2b", "\x2c", "\x2d", "\x2e", "\\/", - "\x30", "\x31", "\x32", "\x33", "\x34", "\x35", "\x36", "\x37", - "\x38", "\x39", "\x3a", "\x3b", "\x3c", "\x3d", "\x3e", "\x3f", - "\x40", "\x41", "\x42", "\x43", "\x44", "\x45", "\x46", "\x47", - "\x48", "\x49", "\x4a", "\x4b", "\x4c", "\x4d", "\x4e", "\x4f", - "\x50", "\x51", "\x52", "\x53", "\x54", "\x55", "\x56", "\x57", - "\x58", "\x59", "\x5a", "\x5b", "\\\\", "\x5d", "\x5e", "\x5f", - "\x60", "\x61", "\x62", "\x63", "\x64", "\x65", "\x66", "\x67", - "\x68", "\x69", "\x6a", "\x6b", "\x6c", "\x6d", "\x6e", "\x6f", - "\x70", "\x71", "\x72", "\x73", "\x74", "\x75", "\x76", "\x77", - "\x78", "\x79", "\x7a", "\x7b", "\x7c", "\x7d", "\x7e", "\x7f", - "\x80", "\x81", "\x82", "\x83", "\x84", "\x85", "\x86", "\x87", - "\x88", "\x89", "\x8a", "\x8b", "\x8c", "\x8d", "\x8e", "\x8f", - "\x90", "\x91", "\x92", "\x93", "\x94", "\x95", "\x96", "\x97", - "\x98", "\x99", "\x9a", "\x9b", "\x9c", "\x9d", "\x9e", "\x9f", - "\xa0", "\xa1", "\xa2", "\xa3", "\xa4", "\xa5", "\xa6", "\xa7", - "\xa8", "\xa9", "\xaa", "\xab", "\xac", "\xad", "\xae", "\xaf", - "\xb0", "\xb1", "\xb2", "\xb3", "\xb4", "\xb5", "\xb6", "\xb7", - "\xb8", "\xb9", "\xba", "\xbb", "\xbc", "\xbd", "\xbe", "\xbf", - "\xc0", "\xc1", "\xc2", "\xc3", "\xc4", "\xc5", "\xc6", "\xc7", - "\xc8", "\xc9", "\xca", "\xcb", "\xcc", "\xcd", "\xce", "\xcf", - "\xd0", "\xd1", "\xd2", "\xd3", "\xd4", "\xd5", "\xd6", "\xd7", - "\xd8", "\xd9", "\xda", "\xdb", "\xdc", "\xdd", "\xde", "\xdf", - "\xe0", "\xe1", "\xe2", "\xe3", "\xe4", "\xe5", "\xe6", "\xe7", - "\xe8", "\xe9", "\xea", "\xeb", "\xec", "\xed", "\xee", "\xef", - "\xf0", "\xf1", "\xf2", "\xf3", "\xf4", "\xf5", "\xf6", "\xf7", - "\xf8", "\xf9", "\xfa", "\xfb", "\xfc", "\xfd", "\xfe", "\xff" -}; - -//////////////////////////////////////////////////////////////////////////////// -json::value* json::value::parse (Nibbler& nibbler) -{ - json::value* v; - if ((v = json::object::parse (nibbler)) || - (v = json::array::parse (nibbler)) || - (v = json::string::parse (nibbler)) || - (v = json::number::parse (nibbler)) || - (v = json::literal::parse (nibbler))) - return v; - - return NULL; -} - -//////////////////////////////////////////////////////////////////////////////// -json::jtype json::value::type () -{ - return json::j_value; -} - -//////////////////////////////////////////////////////////////////////////////// -std::string json::value::dump () const -{ - return ""; -} - -//////////////////////////////////////////////////////////////////////////////// -json::string::string (const std::string& other) -{ - _data = other; -} - -//////////////////////////////////////////////////////////////////////////////// -json::string* json::string::parse (Nibbler& nibbler) -{ - std::string value; - if (nibbler.getQuoted ('"', value)) - { - json::string* s = new json::string (); - s->_data = value; - return s; - } - - return NULL; -} - -//////////////////////////////////////////////////////////////////////////////// -json::jtype json::string::type () -{ - return json::j_string; -} - -//////////////////////////////////////////////////////////////////////////////// -std::string json::string::dump () const -{ - return std::string ("\"") + _data + "\""; -} - -//////////////////////////////////////////////////////////////////////////////// -json::number* json::number::parse (Nibbler& nibbler) -{ - double d; - if (nibbler.getNumber (d)) - { - json::number* s = new json::number (); - s->_dvalue = d; - return s; - } - - return NULL; -} - -//////////////////////////////////////////////////////////////////////////////// -json::jtype json::number::type () -{ - return json::j_number; -} - -//////////////////////////////////////////////////////////////////////////////// -std::string json::number::dump () const -{ - return format (_dvalue); -} - -//////////////////////////////////////////////////////////////////////////////// -json::number::operator double () const -{ - return _dvalue; -} - -//////////////////////////////////////////////////////////////////////////////// -json::literal* json::literal::parse (Nibbler& nibbler) -{ - if (nibbler.getLiteral ("null")) - { - json::literal* s = new json::literal (); - s->_lvalue = nullvalue; - return s; - } - else if (nibbler.getLiteral ("false")) - { - json::literal* s = new json::literal (); - s->_lvalue = falsevalue; - return s; - } - else if (nibbler.getLiteral ("true")) - { - json::literal* s = new json::literal (); - s->_lvalue = truevalue; - return s; - } - - return NULL; -} - -//////////////////////////////////////////////////////////////////////////////// -json::jtype json::literal::type () -{ - return json::j_literal; -} - -//////////////////////////////////////////////////////////////////////////////// -std::string json::literal::dump () const -{ - if (_lvalue == nullvalue) return "null"; - else if (_lvalue == falsevalue) return "false"; - else return "true"; -} - -//////////////////////////////////////////////////////////////////////////////// -json::array::~array () -{ - for (auto& i : _data) - delete i; -} - -//////////////////////////////////////////////////////////////////////////////// -json::array* json::array::parse (Nibbler& nibbler) -{ - Nibbler n (nibbler); - n.skipWS (); - if (n.skip ('[')) - { - n.skipWS (); - - json::array* arr = new json::array (); - - json::value* value; - if ((value = json::value::parse (n))) - { - arr->_data.push_back (value); - value = NULL; // Not a leak. Looks like a leak. - n.skipWS (); - while (n.skip (',')) - { - n.skipWS (); - - if ((value = json::value::parse (n))) - { - arr->_data.push_back (value); - n.skipWS (); - } - else - { - delete arr; - throw format (STRING_JSON_MISSING_VALUE, (int) n.cursor ()); - } - } - } - - if (n.skip (']')) - { - nibbler = n; - return arr; - } - else - throw format (STRING_JSON_MISSING_BRACKET, (int) n.cursor ()); - - delete arr; - } - - return NULL; -} - -//////////////////////////////////////////////////////////////////////////////// -json::jtype json::array::type () -{ - return json::j_array; -} - -//////////////////////////////////////////////////////////////////////////////// -std::string json::array::dump () const -{ - std::string output; - output += "["; - - for (auto i = _data.begin (); i != _data.end (); ++i) - { - if (i != _data.begin ()) - output += ","; - - output += (*i)->dump (); - } - - output += "]"; - return output; -} - -//////////////////////////////////////////////////////////////////////////////// -json::object::~object () -{ - for (auto& i : _data) - delete i.second; -} - -//////////////////////////////////////////////////////////////////////////////// -json::object* json::object::parse (Nibbler& nibbler) -{ - Nibbler n (nibbler); - n.skipWS (); - if (n.skip ('{')) - { - n.skipWS (); - - json::object* obj = new json::object (); - - std::string name; - json::value* value; - if (json::object::parse_pair (n, name, value)) - { - obj->_data.insert (std::pair (name, value)); - value = NULL; // Not a leak. Looks like a leak. - - n.skipWS (); - while (n.skip (',')) - { - n.skipWS (); - - if (json::object::parse_pair (n, name, value)) - { - obj->_data.insert (std::pair (name, value)); - n.skipWS (); - } - else - { - delete obj; - throw format (STRING_JSON_MISSING_VALUE, (int) n.cursor ()); - } - } - } - - if (n.skip ('}')) - { - nibbler = n; - return obj; - } - else - throw format (STRING_JSON_MISSING_BRACE, (int) n.cursor ()); - - delete obj; - } - - return NULL; -} - -//////////////////////////////////////////////////////////////////////////////// -bool json::object::parse_pair ( - Nibbler& nibbler, - std::string& name, - json::value*& val) -{ - Nibbler n (nibbler); - - if (n.getQuoted ('"', name)) - { - n.skipWS (); - if (n.skip (':')) - { - n.skipWS (); - if ((val = json::value::parse (n))) - { - nibbler = n; - return true; - } - else - throw format (STRING_JSON_MISSING_VALUE2, (int) n.cursor ()); - } - else - throw format (STRING_JSON_MISSING_COLON, (int) n.cursor ()); - } - - return false; -} - -//////////////////////////////////////////////////////////////////////////////// -json::jtype json::object::type () -{ - return json::j_object; -} - -//////////////////////////////////////////////////////////////////////////////// -std::string json::object::dump () const -{ - std::string output; - output += "{"; - - for (auto i = _data.begin (); i != _data.end (); ++i) - { - if (i != _data.begin ()) - output += ","; - - output += "\"" + i->first + "\":"; - output += i->second->dump (); - } - - output += "}"; - return output; -} - -//////////////////////////////////////////////////////////////////////////////// -json::value* json::parse (const std::string& input) -{ - json::value* root = NULL; - - Nibbler n (input); - n.skipWS (); - - if (n.next () == '{') root = json::object::parse (n); - else if (n.next () == '[') root = json::array::parse (n); - else - throw format (STRING_JSON_MISSING_OPEN, (int) n.cursor ()); - - // Check for end condition. - n.skipWS (); - if (!n.depleted ()) - { - delete root; - throw format (STRING_JSON_EXTRA_CHARACTERS, (int) n.cursor ()); - } - - return root; -} - -//////////////////////////////////////////////////////////////////////////////// -std::string json::encode (const std::string& input) -{ - std::string output; - output.reserve ((input.size () * 6) / 5); // 20% increase. - - auto last = input.begin (); - for (auto i = input.begin (); i != input.end (); ++i) - { - switch (*i) - { - // Simple translations. - case '"': - case '\\': - case '/': - case '\b': - case '\f': - case '\n': - case '\r': - case '\t': - output.append (last, i); - output += json_encode[(unsigned char)(*i)]; - last = i + 1; - - // Default NOP. - } - } - - output.append (last, input.end ()); - - return output; -} - -//////////////////////////////////////////////////////////////////////////////// -std::string json::decode (const std::string& input) -{ - std::string output; - output.reserve (input.size ()); // Same size. - - size_t pos = 0; - - while (pos < input.length ()) - { - if (input[pos] == '\\') - { - ++pos; - switch (input[pos]) - { - // Simple translations. - case '"': output += '"'; break; - case '\\': output += '\\'; break; - case '/': output += '/'; break; - case 'b': output += '\b'; break; - case 'f': output += '\f'; break; - case 'n': output += '\n'; break; - case 'r': output += '\r'; break; - case 't': output += '\t'; break; - - // Compose a UTF8 unicode character. - case 'u': - output += utf8_character (utf8_codepoint (input.substr (++pos))); - pos += 3; - break; - - // If it is an unrecognized sequence, do nothing. - default: - output += '\\'; - output += input[pos]; - break; - } - ++pos; - } - else - { - size_t next_backslash = input.find ('\\', pos); - output.append (input, pos, next_backslash - pos); - pos = next_backslash; - } - } - - return output; -} - -//////////////////////////////////////////////////////////////////////////////// diff --git a/src/JSON.h b/src/JSON.h deleted file mode 100644 index 3408b3a37..000000000 --- a/src/JSON.h +++ /dev/null @@ -1,135 +0,0 @@ -//////////////////////////////////////////////////////////////////////////////// -// -// Copyright 2006 - 2016, 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_JSON -#define INCLUDED_JSON - -#include -#include -#include -#include - -namespace json -{ - enum jtype - { - j_value, // 0 - j_object, // 1 - j_array, // 2 - j_string, // 3 - j_number, // 4 - j_literal // 5 - }; - - class value - { - public: - value () {} - virtual ~value () {} - static value* parse (Nibbler&); - virtual jtype type (); - virtual std::string dump () const; - }; - - class string : public value - { - public: - string () {} - string (const std::string&); - ~string () {} - static string* parse (Nibbler&); - jtype type (); - std::string dump () const; - - public: - std::string _data; - }; - - class number : public value - { - public: - number () : _dvalue (0.0) {} - ~number () {} - static number* parse (Nibbler&); - jtype type (); - std::string dump () const; - operator double () const; - - public: - double _dvalue; - }; - - class literal : public value - { - public: - literal () : _lvalue (none) {} - ~literal () {} - static literal* parse (Nibbler&); - jtype type (); - std::string dump () const; - - public: - enum literal_value {none, nullvalue, falsevalue, truevalue}; - literal_value _lvalue; - }; - - class array : public value - { - public: - array () {} - ~array (); - static array* parse (Nibbler&); - jtype type (); - std::string dump () const; - - public: - std::vector _data; - }; - - class object : public value - { - public: - object () {} - ~object (); - static object* parse (Nibbler&); - static bool parse_pair (Nibbler&, std::string&, value*&); - jtype type (); - std::string dump () const; - - public: - std::map _data; - }; - - // Parser entry point. - value* parse (const std::string&); - - // Encode/decode for JSON entities. - std::string encode (const std::string&); - std::string decode (const std::string&); -} - -#endif -//////////////////////////////////////////////////////////////////////////////// diff --git a/src/Lexer.cpp b/src/Lexer.cpp index 0d1d6e7b7..703681e68 100644 --- a/src/Lexer.cpp +++ b/src/Lexer.cpp @@ -1,6 +1,6 @@ //////////////////////////////////////////////////////////////////////////////// // -// Copyright 2013 - 2016, Paul Beckingham, Federico Hernandez. +// Copyright 2013 - 2020, 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 @@ -20,7 +20,7 @@ // 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 +// https://www.opensource.org/licenses/mit-license.php // //////////////////////////////////////////////////////////////////////////////// @@ -28,7 +28,9 @@ #include #include #include -#include +#include +#include +#include #include static const std::string uuid_pattern = "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx"; @@ -58,7 +60,7 @@ Lexer::~Lexer () bool Lexer::token (std::string& token, Lexer::Type& type) { // Eat white space. - while (isWhitespace (_text[_cursor])) + while (unicodeWhitespace (_text[_cursor])) utf8_next_char (_text, _cursor); // Terminate at EOS. @@ -141,79 +143,12 @@ const std::string Lexer::typeName (const Lexer::Type& type) return "unknown"; } -//////////////////////////////////////////////////////////////////////////////// -// Complete Unicode whitespace list. -// -// http://en.wikipedia.org/wiki/Whitespace_character -// Updated 2015-09-13 -// Static -// -// TODO This list should be derived from the Unicode database. -bool Lexer::isWhitespace (int c) -{ - return (c == 0x0020 || // space Common Separator, space - c == 0x0009 || // Common Other, control HT, Horizontal Tab - c == 0x000A || // Common Other, control LF, Line feed - c == 0x000B || // Common Other, control VT, Vertical Tab - c == 0x000C || // Common Other, control FF, Form feed - c == 0x000D || // Common Other, control CR, Carriage return - c == 0x0085 || // Common Other, control NEL, Next line - c == 0x00A0 || // no-break space Common Separator, space - c == 0x1680 || // ogham space mark Ogham Separator, space - c == 0x180E || // mongolian vowel separator Mongolian Separator, space - c == 0x2000 || // en quad Common Separator, space - c == 0x2001 || // em quad Common Separator, space - c == 0x2002 || // en space Common Separator, space - c == 0x2003 || // em space Common Separator, space - c == 0x2004 || // three-per-em space Common Separator, space - c == 0x2005 || // four-per-em space Common Separator, space - c == 0x2006 || // six-per-em space Common Separator, space - c == 0x2007 || // figure space Common Separator, space - c == 0x2008 || // punctuation space Common Separator, space - c == 0x2009 || // thin space Common Separator, space - c == 0x200A || // hair space Common Separator, space - c == 0x200B || // zero width space - c == 0x200C || // zero width non-joiner - c == 0x200D || // zero width joiner - c == 0x2028 || // line separator Common Separator, line - c == 0x2029 || // paragraph separator Common Separator, paragraph - c == 0x202F || // narrow no-break space Common Separator, space - c == 0x205F || // medium mathematical space Common Separator, space - c == 0x2060 || // word joiner - c == 0x3000); // ideographic space Common Separator, space -} - -//////////////////////////////////////////////////////////////////////////////// -bool Lexer::isAlpha (int c) -{ - return (c >= 'A' && c <= 'Z') || - (c >= 'a' && c <= 'z'); -} - -//////////////////////////////////////////////////////////////////////////////// -// Digits 0-9. -// -// TODO This list should be derived from the Unicode database. -bool Lexer::isDigit (int c) -{ - return c >= 0x30 && c <= 0x39; -} - -//////////////////////////////////////////////////////////////////////////////// -// Digits 0-9 a-f A-F. -bool Lexer::isHexDigit (int c) -{ - return (c >= '0' && c <= '9') || - (c >= 'a' && c <= 'f') || - (c >= 'A' && c <= 'F'); -} - //////////////////////////////////////////////////////////////////////////////// bool Lexer::isIdentifierStart (int c) { return c && // Include null character check. - ! isWhitespace (c) && - ! isDigit (c) && + ! unicodeWhitespace (c) && + ! unicodeLatinDigit (c) && ! isSingleCharOperator (c) && ! isPunctuation (c); } @@ -224,7 +159,7 @@ bool Lexer::isIdentifierNext (int c) return c && // Include null character check. c != ':' && // Used in isPair. c != '=' && // Used in isPair. - ! isWhitespace (c) && + ! unicodeWhitespace (c) && ! isSingleCharOperator (c); } @@ -271,15 +206,15 @@ bool Lexer::isTripleCharOperator (int c0, int c1, int c2, int c3) bool Lexer::isBoundary (int left, int right) { // EOS - if (right == '\0') return true; + if (right == '\0') return true; // XOR - if (isAlpha (left) != isAlpha (right)) return true; - if (isDigit (left) != isDigit (right)) return true; - if (isWhitespace (left) != isWhitespace (right)) return true; + if (unicodeLatinAlpha (left) != unicodeLatinAlpha (right)) return true; + if (unicodeLatinDigit (left) != unicodeLatinDigit (right)) return true; + if (unicodeWhitespace (left) != unicodeWhitespace (right)) return true; // OR - if (isPunctuation (left) || isPunctuation (right)) return true; + if (isPunctuation (left) || isPunctuation (right)) return true; return false; } @@ -288,7 +223,8 @@ bool Lexer::isBoundary (int left, int right) bool Lexer::isHardBoundary (int left, int right) { // EOS - if (right == '\0') return true; + if (right == '\0') + return true; // FILTER operators that don't need to be surrounded by whitespace. if (left == '(' || @@ -303,14 +239,14 @@ bool Lexer::isHardBoundary (int left, int right) //////////////////////////////////////////////////////////////////////////////// bool Lexer::isPunctuation (int c) { - return isprint (c) && - c != ' ' && - c != '@' && - c != '#' && - c != '$' && - c != '_' && - ! isDigit (c) && - ! isAlpha (c); + return isprint (c) && + c != ' ' && + c != '@' && + c != '#' && + c != '$' && + c != '_' && + ! unicodeLatinDigit (c) && + ! unicodeLatinAlpha (c); } //////////////////////////////////////////////////////////////////////////////// @@ -423,7 +359,7 @@ std::string Lexer::commify (const std::string& data) int i; for (int i = 0; i < (int) data.length (); ++i) { - if (Lexer::isDigit (data[i])) + if (unicodeLatinDigit (data[i])) end = i; if (data[i] == '.') @@ -441,11 +377,11 @@ std::string Lexer::commify (const std::string& data) int consecutiveDigits = 0; for (; i >= 0; --i) { - if (Lexer::isDigit (data[i])) + if (unicodeLatinDigit (data[i])) { result += data[i]; - if (++consecutiveDigits == 3 && i && Lexer::isDigit (data[i - 1])) + if (++consecutiveDigits == 3 && i && unicodeLatinDigit (data[i - 1])) { result += ','; consecutiveDigits = 0; @@ -465,11 +401,11 @@ std::string Lexer::commify (const std::string& data) int consecutiveDigits = 0; for (; i >= 0; --i) { - if (Lexer::isDigit (data[i])) + if (unicodeLatinDigit (data[i])) { result += data[i]; - if (++consecutiveDigits == 3 && i && Lexer::isDigit (data[i - 1])) + if (++consecutiveDigits == 3 && i && unicodeLatinDigit (data[i - 1])) { result += ','; consecutiveDigits = 0; @@ -553,12 +489,12 @@ bool Lexer::isString (std::string& token, Lexer::Type& type, const std::string& //////////////////////////////////////////////////////////////////////////////// // Lexer::Type::date -// +// bool Lexer::isDate (std::string& token, Lexer::Type& type) { // Try an ISO date parse. std::size_t iso_i = 0; - ISO8601d iso; + Datetime iso; if (iso.parse (_text.substr (_cursor), iso_i, Lexer::dateFormat)) { type = Lexer::Type::date; @@ -572,21 +508,21 @@ bool Lexer::isDate (std::string& token, Lexer::Type& type) //////////////////////////////////////////////////////////////////////////////// // Lexer::Type::duration -// | +// bool Lexer::isDuration (std::string& token, Lexer::Type& type) { std::size_t marker = _cursor; std::string extractedToken; Lexer::Type extractedType; - if (isOperator(extractedToken, extractedType)) + if (isOperator (extractedToken, extractedType)) { _cursor = marker; return false; } marker = 0; - ISO8601p iso; + Duration iso; if (iso.parse (_text.substr (_cursor), marker)) { type = Lexer::Type::duration; @@ -620,17 +556,17 @@ bool Lexer::isUUID (std::string& token, Lexer::Type& type, bool endBoundary) { if (uuid_pattern[i] == 'x') { - if (! isHexDigit (_text[marker + i])) + if (! unicodeHexDigit (_text[marker + i])) break; } else if (uuid_pattern[i] != _text[marker + i]) break; } - if (i >= uuid_min_length && - (! endBoundary || - ! _text[marker + i] || - isWhitespace (_text[marker + i]) || + if (i >= uuid_min_length && + (! endBoundary || + ! _text[marker + i] || + unicodeWhitespace (_text[marker + i]) || isSingleCharOperator (_text[marker + i]))) { token = _text.substr (_cursor, i); @@ -655,7 +591,7 @@ bool Lexer::isHexNumber (std::string& token, Lexer::Type& type) { marker += 2; - while (isHexDigit (_text[marker])) + while (unicodeHexDigit (_text[marker])) ++marker; if (marker - _cursor > 2) @@ -680,19 +616,19 @@ bool Lexer::isNumber (std::string& token, Lexer::Type& type) { std::size_t marker = _cursor; - if (isDigit (_text[marker])) + if (unicodeLatinDigit (_text[marker])) { ++marker; - while (isDigit (_text[marker])) + while (unicodeLatinDigit (_text[marker])) utf8_next_char (_text, marker); if (_text[marker] == '.') { ++marker; - if (isDigit (_text[marker])) + if (unicodeLatinDigit (_text[marker])) { ++marker; - while (isDigit (_text[marker])) + while (unicodeLatinDigit (_text[marker])) utf8_next_char (_text, marker); } } @@ -706,29 +642,29 @@ bool Lexer::isNumber (std::string& token, Lexer::Type& type) _text[marker] == '-') ++marker; - if (isDigit (_text[marker])) + if (unicodeLatinDigit (_text[marker])) { ++marker; - while (isDigit (_text[marker])) + while (unicodeLatinDigit (_text[marker])) utf8_next_char (_text, marker); if (_text[marker] == '.') { ++marker; - if (isDigit (_text[marker])) + if (unicodeLatinDigit (_text[marker])) { ++marker; - while (isDigit (_text[marker])) + while (unicodeLatinDigit (_text[marker])) utf8_next_char (_text, marker); } } } } - // Lookahread: ! | ! + // Lookahead: ! | ! // If there is an immediately consecutive character, that is not an operator, fail. if (_eos > marker && - ! isWhitespace (_text[marker]) && + ! unicodeWhitespace (_text[marker]) && ! isSingleCharOperator (_text[marker])) return false; @@ -748,10 +684,10 @@ bool Lexer::isInteger (std::string& token, Lexer::Type& type) { std::size_t marker = _cursor; - if (isDigit (_text[marker])) + if (unicodeLatinDigit (_text[marker])) { ++marker; - while (isDigit (_text[marker])) + while (unicodeLatinDigit (_text[marker])) utf8_next_char (_text, marker); token = _text.substr (_cursor, marker - _cursor); @@ -805,7 +741,7 @@ bool Lexer::isURL (std::string& token, Lexer::Type& type) marker += 3; while (marker < _eos && - ! isWhitespace (_text[marker])) + ! unicodeWhitespace (_text[marker])) utf8_next_char (_text, marker); token = _text.substr (_cursor, marker - _cursor); @@ -846,7 +782,7 @@ bool Lexer::isPair (std::string& token, Lexer::Type& type) if (readWord (_text, "'\"", _cursor, ignoredToken) || readWord (_text, _cursor, ignoredToken) || isEOS () || - isWhitespace (_text[_cursor])) + unicodeWhitespace (_text[_cursor])) { token = _text.substr (marker, _cursor - marker); type = Lexer::Type::pair; @@ -900,7 +836,7 @@ bool Lexer::isSet (std::string& token, Lexer::Type& type) // Success is multiple numbers, matching the pattern. if (count > 1 && (isEOS () || - isWhitespace (_text[_cursor]) || + unicodeWhitespace (_text[_cursor]) || isHardBoundary (_text[_cursor], _text[_cursor + 1]))) { token = _text.substr (marker, _cursor - marker); @@ -915,7 +851,7 @@ bool Lexer::isSet (std::string& token, Lexer::Type& type) //////////////////////////////////////////////////////////////////////////////// // Lexer::Type::tag -// ^ | '(' | ')' | +// ^ | '(' | ')' | // [ +|- ] [ ]* bool Lexer::isTag (std::string& token, Lexer::Type& type) { @@ -923,7 +859,7 @@ bool Lexer::isTag (std::string& token, Lexer::Type& type) // Lookbehind: Assert ^ or preceded by whitespace, (, or ). if (marker > 0 && - ! isWhitespace (_text[marker - 1]) && + ! unicodeWhitespace (_text[marker - 1]) && _text[marker - 1] != '(' && _text[marker - 1] != ')') return false; @@ -969,12 +905,12 @@ bool Lexer::isPath (std::string& token, Lexer::Type& type) break; if (_text[marker] && - ! isWhitespace (_text[marker]) && + ! unicodeWhitespace (_text[marker]) && _text[marker] != '/') { utf8_next_char (_text, marker); while (_text[marker] && - ! isWhitespace (_text[marker]) && + ! unicodeWhitespace (_text[marker]) && _text[marker] != '/') utf8_next_char (_text, marker); } @@ -996,7 +932,7 @@ bool Lexer::isPath (std::string& token, Lexer::Type& type) //////////////////////////////////////////////////////////////////////////////// // Lexer::Type::substitution -// / / / [g] | +// / / / [g] | bool Lexer::isSubstitution (std::string& token, Lexer::Type& type) { std::size_t marker = _cursor; @@ -1011,9 +947,9 @@ bool Lexer::isSubstitution (std::string& token, Lexer::Type& type) if (_text[_cursor] == 'g') ++_cursor; - // Lookahread: | + // Lookahread: | if (_text[_cursor] == '\0' || - isWhitespace (_text[_cursor])) + unicodeWhitespace (_text[_cursor])) { token = _text.substr (marker, _cursor - marker); type = Lexer::Type::substitution; @@ -1028,7 +964,7 @@ bool Lexer::isSubstitution (std::string& token, Lexer::Type& type) //////////////////////////////////////////////////////////////////////////////// // Lexer::Type::pattern -// / / | +// / / | bool Lexer::isPattern (std::string& token, Lexer::Type& type) { std::size_t marker = _cursor; @@ -1036,7 +972,7 @@ bool Lexer::isPattern (std::string& token, Lexer::Type& type) std::string word; if (readWord (_text, "/", _cursor, word) && (isEOS () || - isWhitespace (_text[_cursor]))) + unicodeWhitespace (_text[_cursor]))) { token = _text.substr (marker, _cursor - marker); type = Lexer::Type::pattern; @@ -1132,10 +1068,15 @@ bool Lexer::isOperator (std::string& token, Lexer::Type& type) // rc. // // System: -// context.program -// context.args -// context.width -// context.height +// tw.syncneeded +// tw.program +// tw.args +// tw.width +// tw.height +// context.program // 2017-02-25 Deprecated in 2.6.0 +// context.args // 2017-02-25 Deprecated in 2.6.0 +// context.width // 2017-02-25 Deprecated in 2.6.0 +// context.height // 2017-02-25 Deprecated in 2.6.0 // system.version // system.os // @@ -1159,6 +1100,7 @@ bool Lexer::isOperator (std::string& token, Lexer::Type& type) // .second // // Annotations (entry is a date): +// annotations.count // annotations..entry // annotations..description // @@ -1166,6 +1108,7 @@ bool Lexer::isDOM (std::string& token, Lexer::Type& type) { std::size_t marker = _cursor; + // rc. ... std::string partialToken; Lexer::Type partialType; if (isLiteral ("rc.", false, false) && @@ -1178,7 +1121,14 @@ bool Lexer::isDOM (std::string& token, Lexer::Type& type) else _cursor = marker; - if (isOneOf ({"context.program", + // Literals + if (isOneOf ({"tw.syncneeded", + "tw.program", + "tw.args", + "tw.width", + "tw.height", + "tw.version", + "context.program", "context.args", "context.width", "context.height", @@ -1220,7 +1170,7 @@ bool Lexer::isDOM (std::string& token, Lexer::Type& type) else _cursor = checkpoint; - // [prefix]attribute + // [prefix]attribute (bounded) if (isOneOf (attributes, false, true)) { token = _text.substr (marker, _cursor - marker); @@ -1228,7 +1178,7 @@ bool Lexer::isDOM (std::string& token, Lexer::Type& type) return true; } - // [prefix]attribute. + // [prefix]attribute. (unbounded) if (isOneOf (attributes, false, false)) { if (isLiteral (".", false, false)) @@ -1246,19 +1196,32 @@ bool Lexer::isDOM (std::string& token, Lexer::Type& type) type = Lexer::Type::dom; return true; } + + _cursor = checkpoint; } - else + + // Lookahead: ! + else if (! unicodeLatinAlpha (_text[marker])) { token = _text.substr (marker, _cursor - marker); type = Lexer::Type::dom; return true; } + + _cursor = checkpoint; } // [prefix]annotations. if (isLiteral ("annotations", true, false) && isLiteral (".", false, false)) { + if (isLiteral ("count", false, false)) + { + token = _text.substr (marker, _cursor - marker); + type = Lexer::Type::dom; + return true; + } + std::string extractedToken; Lexer::Type extractedType; if (isInteger (extractedToken, extractedType)) @@ -1290,6 +1253,8 @@ bool Lexer::isDOM (std::string& token, Lexer::Type& type) } } } + else + _cursor = checkpoint; } _cursor = marker; @@ -1327,7 +1292,7 @@ bool Lexer::isWord (std::string& token, Lexer::Type& type) std::size_t marker = _cursor; while (_text[marker] && - ! isWhitespace (_text[marker]) && + ! unicodeWhitespace (_text[marker]) && ! isSingleCharOperator (_text[marker])) utf8_next_char (_text, marker); @@ -1363,7 +1328,7 @@ bool Lexer::isLiteral ( // End boundary conditions must be met. if (endBoundary && _text[_cursor + common] && - ! Lexer::isWhitespace (_text[_cursor + common]) && + ! unicodeWhitespace (_text[_cursor + common]) && ! Lexer::isSingleCharOperator (_text[_cursor + common])) return false; @@ -1430,6 +1395,7 @@ bool Lexer::isAllDigits (const std::string& text) } //////////////////////////////////////////////////////////////////////////////// +// This is intentionally looking for a single token. bool Lexer::isDOM (const std::string& text) { Lexer lex (text); @@ -1478,10 +1444,10 @@ bool Lexer::readWord ( else if (eos - cursor >= 6 && ((text[cursor + 0] == 'U' && text[cursor + 1] == '+') || (text[cursor + 0] == '\\' && text[cursor + 1] == 'u')) && - isHexDigit (text[cursor + 2]) && - isHexDigit (text[cursor + 3]) && - isHexDigit (text[cursor + 4]) && - isHexDigit (text[cursor + 5])) + unicodeHexDigit (text[cursor + 2]) && + unicodeHexDigit (text[cursor + 3]) && + unicodeHexDigit (text[cursor + 4]) && + unicodeHexDigit (text[cursor + 5])) { word += utf8_character ( hexToInt ( @@ -1536,7 +1502,7 @@ bool Lexer::readWord ( // // Ends at: // Lexer::isEOS -// Lexer::isWhitespace +// unicodeWhitespace // Lexer::isHardBoundary bool Lexer::readWord ( const std::string& text, @@ -1551,7 +1517,7 @@ bool Lexer::readWord ( while ((c = text[cursor])) // Handles EOS. { // Unquoted word ends on white space. - if (Lexer::isWhitespace (c)) + if (unicodeWhitespace (c)) break; // Parentheses mostly. @@ -1562,10 +1528,10 @@ bool Lexer::readWord ( else if (eos - cursor >= 6 && ((text[cursor + 0] == 'U' && text[cursor + 1] == '+') || (text[cursor + 0] == '\\' && text[cursor + 1] == 'u')) && - isHexDigit (text[cursor + 2]) && - isHexDigit (text[cursor + 3]) && - isHexDigit (text[cursor + 4]) && - isHexDigit (text[cursor + 5])) + unicodeHexDigit (text[cursor + 2]) && + unicodeHexDigit (text[cursor + 3]) && + unicodeHexDigit (text[cursor + 4]) && + unicodeHexDigit (text[cursor + 5])) { word += utf8_character ( hexToInt ( diff --git a/src/Lexer.h b/src/Lexer.h index a201203f0..7c5cbfd02 100644 --- a/src/Lexer.h +++ b/src/Lexer.h @@ -1,6 +1,6 @@ //////////////////////////////////////////////////////////////////////////////// // -// Copyright 2013 - 2016, Paul Beckingham, Federico Hernandez. +// Copyright 2013 - 2020, 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 @@ -20,7 +20,7 @@ // 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 +// https://www.opensource.org/licenses/mit-license.php // //////////////////////////////////////////////////////////////////////////////// @@ -61,10 +61,6 @@ public: // 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); diff --git a/src/Msg.cpp b/src/Msg.cpp deleted file mode 100644 index 7f73858c4..000000000 --- a/src/Msg.cpp +++ /dev/null @@ -1,109 +0,0 @@ -//////////////////////////////////////////////////////////////////////////////// -// -// Copyright 2006 - 2016, 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 -#include -#include -#include - -//////////////////////////////////////////////////////////////////////////////// -void Msg::set (const std::string& name, const std::string& value) -{ - _header[name] = value; -} - -//////////////////////////////////////////////////////////////////////////////// -std::string Msg::get (const std::string& name) const -{ - auto i = _header.find (name); - if (i != _header.end ()) - return i->second; - - return ""; -} - -//////////////////////////////////////////////////////////////////////////////// -void Msg::setPayload (const std::string& payload) -{ - _payload = payload; -} - -//////////////////////////////////////////////////////////////////////////////// -std::string Msg::getPayload () const -{ - return _payload; -} - -//////////////////////////////////////////////////////////////////////////////// -std::vector Msg::all () const -{ - std::vector names; - for (auto& i : _header) - names.push_back (i.first); - - return names; -} - -//////////////////////////////////////////////////////////////////////////////// -std::string Msg::serialize () const -{ - std::string output; - for (auto& i : _header) - output += i.first + ": " + i.second + "\n"; - - output += "\n" + _payload + "\n"; - return output; -} - -//////////////////////////////////////////////////////////////////////////////// -bool Msg::parse (const std::string& input) -{ - _header.clear (); - _payload = ""; - - auto separator = input.find ("\n\n"); - if (separator == std::string::npos) - throw std::string ("ERROR: Malformed message"); - - // Parse header. - std::vector lines; - split (lines, input.substr (0, separator), '\n'); - for (auto& i : lines) - { - auto delimiter = i.find (':'); - if (delimiter == std::string::npos) - throw std::string ("ERROR: Malformed message header '") + i + "'"; - - _header[Lexer::trim (i.substr (0, delimiter))] = Lexer::trim (i.substr (delimiter + 1)); - } - - // Parse payload. - _payload = input.substr (separator + 2); - - return true; -} - -//////////////////////////////////////////////////////////////////////////////// diff --git a/src/Msg.h b/src/Msg.h deleted file mode 100644 index 72736b6d2..000000000 --- a/src/Msg.h +++ /dev/null @@ -1,53 +0,0 @@ -//////////////////////////////////////////////////////////////////////////////// -// -// Copyright 2006 - 2016, 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_MSG -#define INCLUDED_MSG - -#include -#include -#include - -class Msg -{ -public: - void set (const std::string&, const std::string&); - std::string get (const std::string&) const; - - void setPayload (const std::string&); - std::string getPayload () const; - - std::vector all () const; - std::string serialize () const; - bool parse (const std::string&); - -private: - std::map _header {}; - std::string _payload {""}; -}; - -#endif - diff --git a/src/Nibbler.cpp b/src/Nibbler.cpp deleted file mode 100644 index 4339f8c74..000000000 --- a/src/Nibbler.cpp +++ /dev/null @@ -1,626 +0,0 @@ -//////////////////////////////////////////////////////////////////////////////// -// -// Copyright 2006 - 2016, 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 -#include -#include -#include -#include -#include -#include - -static const char* _uuid_pattern = "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx"; -static const unsigned int _uuid_min_length = 8; - -//////////////////////////////////////////////////////////////////////////////// -Nibbler::Nibbler () -: _length (0) -, _cursor (0) -, _saved (0) -{ -} - -//////////////////////////////////////////////////////////////////////////////// -Nibbler::Nibbler (const std::string& input) -: _input (std::make_shared (input)) -, _length (input.length ()) -, _cursor (0) -{ -} - -//////////////////////////////////////////////////////////////////////////////// -Nibbler::Nibbler (const Nibbler& other) -: _input (other._input) -, _length (other._length) -, _cursor (other._cursor) -{ -} - -//////////////////////////////////////////////////////////////////////////////// -Nibbler& Nibbler::operator= (const Nibbler& other) -{ - if (this != &other) - { - _input = other._input; - _length = other._length; - _cursor = other._cursor; - } - - return *this; -} - -//////////////////////////////////////////////////////////////////////////////// -Nibbler::~Nibbler () -{ -} - -//////////////////////////////////////////////////////////////////////////////// -// Extract up until the next c (but not including) or EOS. -bool Nibbler::getUntil (char c, std::string& result) -{ - if (_cursor < _length) - { - auto i = _input->find (c, _cursor); - if (i != std::string::npos) - { - result = _input->substr (_cursor, i - _cursor); - _cursor = i; - } - else - { - result = _input->substr (_cursor); - _cursor = _length; - } - - return true; - } - - return false; -} - -//////////////////////////////////////////////////////////////////////////////// -bool Nibbler::getUntil (const std::string& terminator, std::string& result) -{ - if (_cursor < _length) - { - auto i = _input->find (terminator, _cursor); - if (i != std::string::npos) - { - result = _input->substr (_cursor, i - _cursor); - _cursor = i; - } - else - { - result = _input->substr (_cursor); - _cursor = _length; - } - - return true; - } - - return false; -} - -//////////////////////////////////////////////////////////////////////////////// -bool Nibbler::getUntilOneOf (const std::string& chars, std::string& result) -{ - if (_cursor < _length) - { - auto i = _input->find_first_of (chars, _cursor); - if (i != std::string::npos) - { - result = _input->substr (_cursor, i - _cursor); - _cursor = i; - } - else - { - result = _input->substr (_cursor); - _cursor = _length; - } - - return true; - } - - return false; -} - -//////////////////////////////////////////////////////////////////////////////// -bool Nibbler::getUntilWS (std::string& result) -{ - return this->getUntilOneOf (" \t\r\n\f", result); -} - -//////////////////////////////////////////////////////////////////////////////// -bool Nibbler::getUntilEOS (std::string& result) -{ - if (_cursor < _length) - { - result = _input->substr (_cursor); - _cursor = _length; - return true; - } - - return false; -} - -//////////////////////////////////////////////////////////////////////////////// -bool Nibbler::getN (const int quantity, std::string& result) -{ - if (_cursor + quantity <= _length) - { - result = _input->substr (_cursor, quantity); - _cursor += quantity; - return true; - } - - return false; -} - -//////////////////////////////////////////////////////////////////////////////// -// Gets quote content: "foobar" -> foobar (for c = '"') -// Handles escaped quotes: "foo\"bar" -> foo\"bar (for c = '"') -// Returns false if first character is not c, or if there is no closing c -bool Nibbler::getQuoted (char c, std::string& result) -{ - result = ""; - - if (_cursor >= _length || - (*_input)[_cursor] != c) - { - return false; - } - - std::string::size_type start = _cursor + 1; // Skip first quote char - std::string::size_type i = start; - - while (i < _length) - { - i = (*_input).find (c, i); - - if (i == std::string::npos) - return false; // Unclosed quote - - if (i == start) - { - // Empty quote - _cursor += 2; // Skip both quote chars - return true; - } - - if ((*_input)[i-1] == '\\') - { - // Check for escaped backslashes. Backtracking like this is not very - // efficient, but is only done in extreme corner cases. - - auto j = i-2; // Start one character further left - bool is_escaped_quote = true; - while (j >= start && (*_input)[j] == '\\') - { - // Toggle flag for each further backslash encountered. - is_escaped_quote = is_escaped_quote ? false : true; - --j; - } - - if (is_escaped_quote) - { - // Keep searching - ++i; - continue; - } - } - - // None of the above applied, we must have found the closing quote char. - result.assign ((*_input), start, i - start); - _cursor = i + 1; // Skip closing quote char - return true; - } - - // This should never be reached. We could throw here instead. - return false; -} - -//////////////////////////////////////////////////////////////////////////////// -bool Nibbler::getDigit (int& result) -{ - if (_cursor < _length && - Lexer::isDigit ((*_input)[_cursor])) - { - result = (*_input)[_cursor++] - '0'; - return true; - } - - return false; -} - -//////////////////////////////////////////////////////////////////////////////// -bool Nibbler::getDigit4 (int& result) -{ - auto i = _cursor; - if (i < _length && - _length - i >= 4) - { - 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; - return true; - } - } - - return false; -} - -//////////////////////////////////////////////////////////////////////////////// -bool Nibbler::getDigit3 (int& result) -{ - auto i = _cursor; - if (i < _length && - _length - i >= 3) - { - 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; - return true; - } - } - - return false; -} - -//////////////////////////////////////////////////////////////////////////////// -bool Nibbler::getDigit2 (int& result) -{ - auto i = _cursor; - if (i < _length && - _length - i >= 2) - { - if (Lexer::isDigit ((*_input)[i + 0]) && - Lexer::isDigit ((*_input)[i + 1])) - { - result = strtoimax (_input->substr (_cursor, 2).c_str (), NULL, 10); - _cursor += 2; - return true; - } - } - - return false; -} - -//////////////////////////////////////////////////////////////////////////////// -bool Nibbler::getInt (int& result) -{ - auto i = _cursor; - - if (i < _length) - { - if ((*_input)[i] == '-') - ++i; - else if ((*_input)[i] == '+') - ++i; - } - - // TODO Potential for use of find_first_not_of - while (i < _length && Lexer::isDigit ((*_input)[i])) - ++i; - - if (i > _cursor) - { - result = strtoimax (_input->substr (_cursor, i - _cursor).c_str (), NULL, 10); - _cursor = i; - return true; - } - - return false; -} - -//////////////////////////////////////////////////////////////////////////////// -bool Nibbler::getUnsignedInt (int& result) -{ - auto i = _cursor; - // TODO Potential for use of find_first_not_of - while (i < _length && Lexer::isDigit ((*_input)[i])) - ++i; - - if (i > _cursor) - { - result = strtoimax (_input->substr (_cursor, i - _cursor).c_str (), NULL, 10); - _cursor = i; - return true; - } - - return false; -} - -//////////////////////////////////////////////////////////////////////////////// -// number: -// int frac? exp? -// -// int: -// (-|+)? digit+ -// -// frac: -// . digit+ -// -// exp: -// e digit+ -// -// e: -// e|E (+|-)? -// -bool Nibbler::getNumber (std::string& result) -{ - auto i = _cursor; - - // [+-]? - if (i < _length && ((*_input)[i] == '-' || (*_input)[i] == '+')) - ++i; - - // digit+ - if (i < _length && Lexer::isDigit ((*_input)[i])) - { - ++i; - - while (i < _length && Lexer::isDigit ((*_input)[i])) - ++i; - - // ( . digit+ )? - if (i < _length && (*_input)[i] == '.') - { - ++i; - - while (i < _length && Lexer::isDigit ((*_input)[i])) - ++i; - } - - // ( [eE] [+-]? digit+ )? - if (i < _length && ((*_input)[i] == 'e' || (*_input)[i] == 'E')) - { - ++i; - - if (i < _length && ((*_input)[i] == '+' || (*_input)[i] == '-')) - ++i; - - if (i < _length && Lexer::isDigit ((*_input)[i])) - { - ++i; - - while (i < _length && Lexer::isDigit ((*_input)[i])) - ++i; - - result = _input->substr (_cursor, i - _cursor); - _cursor = i; - return true; - } - - return false; - } - - result = _input->substr (_cursor, i - _cursor); - _cursor = i; - return true; - } - - return false; -} - -//////////////////////////////////////////////////////////////////////////////// -bool Nibbler::getNumber (double &result) -{ - std::string s; - if (getNumber (s)) - { - result = strtof (s.c_str (), NULL); - return true; - } - - return false; -} - -//////////////////////////////////////////////////////////////////////////////// -bool Nibbler::getLiteral (const std::string& literal) -{ - if (_cursor < _length && - _input->find (literal, _cursor) == _cursor) - { - _cursor += literal.length (); - return true; - } - - return false; -} - -//////////////////////////////////////////////////////////////////////////////// -bool Nibbler::getPartialUUID (std::string& result) -{ - std::string::size_type i; - for (i = 0; i < 36 && i < (_length - _cursor); i++) - { - if (_uuid_pattern[i] == 'x' && !isxdigit ((*_input)[_cursor + i])) - break; - - else if (_uuid_pattern[i] == '-' && (*_input)[_cursor + i] != '-') - break; - } - - // If the partial match found is long enough, consider it a match. - if (i >= _uuid_min_length) - { - // Fail if there is another hex digit. - if (_cursor + i < _length && - isxdigit ((*_input)[_cursor + i])) - return false; - - result = _input->substr (_cursor, i); - _cursor += i; - - return true; - } - - return false; -} - -//////////////////////////////////////////////////////////////////////////////// -// Assumes that the options are sorted by decreasing length, so that if the -// options contain 'fourteen' and 'four', the stream is first matched against -// the longer entry. -bool Nibbler::getOneOf ( - const std::vector & options, - std::string& found) -{ - for (auto& option : options) - { - if (getLiteral (option)) - { - found = option; - return true; - } - } - - return false; -} - -//////////////////////////////////////////////////////////////////////////////// -bool Nibbler::skipN (const int quantity /* = 1 */) -{ - if (_cursor < _length && - _cursor <= _length - quantity) - { - _cursor += quantity; - return true; - } - - return false; -} - -//////////////////////////////////////////////////////////////////////////////// -bool Nibbler::skip (char c) -{ - if (_cursor < _length && - (*_input)[_cursor] == c) - { - ++_cursor; - return true; - } - - return false; -} - -//////////////////////////////////////////////////////////////////////////////// -bool Nibbler::skipWS () -{ - return this->skipAllOneOf (" \t\n\r\f"); -} - -//////////////////////////////////////////////////////////////////////////////// -bool Nibbler::skipAllOneOf (const std::string& chars) -{ - if (_cursor < _length) - { - auto i = _input->find_first_not_of (chars, _cursor); - if (i == _cursor) - return false; - - if (i == std::string::npos) - _cursor = _length; // Yes, off the end. - else - _cursor = i; - - return true; - } - - return false; -} - -//////////////////////////////////////////////////////////////////////////////// -// Peeks ahead - does not move cursor. -char Nibbler::next () -{ - if (_cursor < _length) - return (*_input)[_cursor]; - - return '\0'; -} - -//////////////////////////////////////////////////////////////////////////////// -std::string::size_type Nibbler::cursor () -{ - return _cursor; -} - -//////////////////////////////////////////////////////////////////////////////// -// Peeks ahead - does not move cursor. -std::string Nibbler::next (const int quantity) -{ - if ( _cursor < _length && - (unsigned) quantity <= _length && - _cursor <= _length - quantity) - return _input->substr (_cursor, quantity); - - return ""; -} - -//////////////////////////////////////////////////////////////////////////////// -std::string::size_type Nibbler::save () -{ - return _saved = _cursor; -} - -//////////////////////////////////////////////////////////////////////////////// -std::string::size_type Nibbler::restore () -{ - return _cursor = _saved; -} - -//////////////////////////////////////////////////////////////////////////////// -const std::string& Nibbler::str () const -{ - return *_input; -} - -//////////////////////////////////////////////////////////////////////////////// -bool Nibbler::depleted () -{ - if (_cursor >= _length) - return true; - - return false; -} - -//////////////////////////////////////////////////////////////////////////////// -std::string Nibbler::dump () -{ - return std::string ("Nibbler ‹") - + _input->substr (_cursor) - + "›"; -} - -//////////////////////////////////////////////////////////////////////////////// diff --git a/src/Nibbler.h b/src/Nibbler.h deleted file mode 100644 index e3cea065e..000000000 --- a/src/Nibbler.h +++ /dev/null @@ -1,89 +0,0 @@ -//////////////////////////////////////////////////////////////////////////////// -// -// Copyright 2006 - 2016, 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_NIBBLER -#define INCLUDED_NIBBLER - -#include -#include -#include -#include - -class Nibbler -{ -public: - Nibbler (); // Default constructor - Nibbler (const std::string&); // Constructor - Nibbler (const Nibbler&); // Copy constructor - Nibbler& operator= (const Nibbler&); // Assignment operator - ~Nibbler (); // Destructor - - bool getUntil (char, std::string&); - bool getUntil (const std::string&, std::string&); - bool getUntilOneOf (const std::string&, std::string&); - bool getUntilWS (std::string&); - bool getUntilEOS (std::string&); - - bool getN (const int, std::string&); - bool getQuoted (char, std::string&); - bool getDigit (int&); - bool getDigit4 (int&); - bool getDigit3 (int&); - bool getDigit2 (int&); - bool getInt (int&); - bool getUnsignedInt (int&); - bool getNumber (std::string&); - bool getNumber (double&); - bool getLiteral (const std::string&); - bool getPartialUUID (std::string&); - bool getOneOf (const std::vector &, std::string&); - - bool skipN (const int quantity = 1); - bool skip (char); - bool skipAllOneOf (const std::string&); - bool skipWS (); - - char next (); - std::string next (const int quantity); - - std::string::size_type cursor (); - std::string::size_type save (); - std::string::size_type restore (); - const std::string& str () const; - - bool depleted (); - - std::string dump (); - -private: - std::shared_ptr _input; - std::string::size_type _length; - std::string::size_type _cursor; - std::string::size_type _saved; -}; - -#endif -//////////////////////////////////////////////////////////////////////////////// diff --git a/src/RX.cpp b/src/RX.cpp deleted file mode 100644 index b68a063b7..000000000 --- a/src/RX.cpp +++ /dev/null @@ -1,159 +0,0 @@ -//////////////////////////////////////////////////////////////////////////////// -// -// Copyright 2006 - 2016, 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 -#include -#include -#include - -//////////////////////////////////////////////////////////////////////////////// -RX::RX () -{ -} - -//////////////////////////////////////////////////////////////////////////////// -RX::RX ( - const std::string& pattern, - bool case_sensitive /* = true */) -: _compiled (false) -, _pattern (pattern) -, _case_sensitive (case_sensitive) -{ - compile (); -} - -//////////////////////////////////////////////////////////////////////////////// -RX::RX (const RX& other) -{ - _compiled = false; - _pattern = other._pattern; - _case_sensitive = other._case_sensitive; -} - -//////////////////////////////////////////////////////////////////////////////// -RX::~RX () -{ - if (_compiled) - regfree (&_regex); -} - -//////////////////////////////////////////////////////////////////////////////// -RX& RX::operator= (const RX& other) -{ - _compiled = false; - _pattern = other._pattern; - _case_sensitive = other._case_sensitive; - - return *this; -} - -//////////////////////////////////////////////////////////////////////////////// -void RX::compile () -{ - if (! _compiled) - { - memset (&_regex, 0, sizeof (regex_t)); - - int result; - if ((result = regcomp (&_regex, _pattern.c_str (), -#if defined REG_ENHANCED - REG_ENHANCED | REG_EXTENDED | REG_NEWLINE | -#else - REG_EXTENDED | REG_NEWLINE | -#endif - (_case_sensitive ? 0 : REG_ICASE))) != 0) - { - char message[256]; - regerror (result, &_regex, message, 256); - throw std::string (message); - } - - _compiled = true; - } -} - -//////////////////////////////////////////////////////////////////////////////// -bool RX::match (const std::string& in) -{ - if (! _compiled) - compile (); - - return regexec (&_regex, in.c_str (), 0, nullptr, 0) == 0 ? true : false; -} - -//////////////////////////////////////////////////////////////////////////////// -bool RX::match ( - std::vector& matches, - const std::string& in) -{ - if (! _compiled) - compile (); - - regmatch_t rm[2]; - int offset = 0; - int length = in.length (); - while (regexec (&_regex, in.c_str () + offset, 2, &rm[0], 0) == 0 && - offset < length) - { - matches.push_back (in.substr (rm[0].rm_so + offset, rm[0].rm_eo - rm[0].rm_so)); - offset += rm[0].rm_eo; - - // Protection against zero-width patterns causing infinite loops. - if (rm[0].rm_so == rm[0].rm_eo) - ++offset; - } - - return matches.size () ? true : false; -} - -//////////////////////////////////////////////////////////////////////////////// -bool RX::match ( - std::vector & start, - std::vector & end, - const std::string& in) -{ - if (! _compiled) - compile (); - - regmatch_t rm[2]; - int offset = 0; - int length = in.length (); - while (regexec (&_regex, in.c_str () + offset, 2, &rm[0], 0) == 0 && - offset < length) - { - start.push_back (rm[0].rm_so + offset); - end.push_back (rm[0].rm_eo + offset); - offset += rm[0].rm_eo; - - // Protection against zero-width patterns causing infinite loops. - if (rm[0].rm_so == rm[0].rm_eo) - ++offset; - } - - return start.size () ? true : false; -} - -//////////////////////////////////////////////////////////////////////////////// diff --git a/src/RX.h b/src/RX.h deleted file mode 100644 index b98371113..000000000 --- a/src/RX.h +++ /dev/null @@ -1,58 +0,0 @@ -//////////////////////////////////////////////////////////////////////////////// -// -// Copyright 2006 - 2016, 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_RX -#define INCLUDED_RX - -#include -#include -#include - -class RX -{ -public: - RX (); - RX (const std::string&, bool caseSensitive = true); - RX (const RX&); - ~RX (); - RX& operator= (const RX&); - - bool match (const std::string&); - bool match (std::vector&, const std::string&); - bool match (std::vector &, std::vector &, const std::string&); - -private: - void compile (); - -private: - bool _compiled {false}; - std::string _pattern {}; - bool _case_sensitive {false}; - regex_t _regex; -}; - -#endif - diff --git a/src/TDB2.cpp b/src/TDB2.cpp index 22dff8a72..e984a03c8 100644 --- a/src/TDB2.cpp +++ b/src/TDB2.cpp @@ -1,6 +1,6 @@ //////////////////////////////////////////////////////////////////////////////// // -// Copyright 2006 - 2016, Paul Beckingham, Federico Hernandez. +// Copyright 2006 - 2020, 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 @@ -20,7 +20,7 @@ // 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 +// https://www.opensource.org/licenses/mit-license.php // //////////////////////////////////////////////////////////////////////////////// @@ -35,13 +35,14 @@ #include #include #include -#include -#include -#include -#include +#include +#include +#include +#include #include +#include -extern Context context; +#define STRING_TDB2_REVERTED "Modified task reverted." bool TDB2::debug_mode = false; @@ -60,8 +61,7 @@ TF2::TF2 () TF2::~TF2 () { if (_dirty && TDB2::debug_mode) - std::cout << format (STRING_TDB2_DIRTY_EXIT, std::string (_file)) - << "\n"; + std::cout << format ("Exiting with unwritten changes to {1}\n", std::string (_file)); } //////////////////////////////////////////////////////////////////////////////// @@ -169,7 +169,7 @@ void TF2::add_task (Task& task) _added_tasks.push_back (task); // For commit/synch // For faster lookup - if (context.cli2.getCommand () == "import") + if (Context::getContext ().cli2.getCommand () == "import") _tasks_map.insert (std::pair (task.get("uuid"), task)); Task::status status = task.getStatus (); @@ -178,7 +178,7 @@ void TF2::add_task (Task& task) status == Task::recurring || status == Task::waiting)) { - task.id = context.tdb2.next_id (); + task.id = Context::getContext ().tdb2.next_id (); } _I2U[task.id] = task.get ("uuid"); @@ -192,7 +192,7 @@ bool TF2::modify_task (const Task& task) { std::string uuid = task.get ("uuid"); - if (context.cli2.getCommand () == "import") + if (Context::getContext ().cli2.getCommand () == "import") { // Update map used for faster lookup auto i = _tasks_map.find (uuid); @@ -218,6 +218,21 @@ bool TF2::modify_task (const Task& task) return false; } +//////////////////////////////////////////////////////////////////////////////// +bool TF2::purge_task (const Task& task) +{ + // Bail out if task is not found in this file + std::string uuid = task.get ("uuid"); + if (!has (uuid)) + return false; + + // Mark the task to be purged + _purged_tasks.insert (uuid); + _dirty = true; + + return true; +} + //////////////////////////////////////////////////////////////////////////////// void TF2::add_line (const std::string& line) { @@ -248,12 +263,12 @@ void TF2::commit () if (_dirty) { // Special case: added but no modified means just append to the file. - if (!_modified_tasks.size () && + if (!_modified_tasks.size () && !_purged_tasks.size () && (_added_tasks.size () || _added_lines.size ())) { if (_file.open ()) { - if (context.config.getBoolean ("locking")) + if (Context::getContext ().config.getBoolean ("locking")) _file.lock (); // Write out all the added tasks. @@ -275,7 +290,7 @@ void TF2::commit () { if (_file.open ()) { - if (context.config.getBoolean ("locking")) + if (Context::getContext ().config.getBoolean ("locking")) _file.lock (); // Truncate the file and rewrite. @@ -284,7 +299,9 @@ void TF2::commit () // Only write out _tasks, because any deltas have already been applied. _file.append (std::string("")); // Seek to end of file for (auto& task : _tasks) - _file.write_raw (task.composeF4 () + "\n"); + // Skip over the tasks that are marked to be purged + if (_purged_tasks.find (task.get ("uuid")) == _purged_tasks.end ()) + _file.write_raw (task.composeF4 () + '\n'); // Write out all the added lines. _file.append (_added_lines); @@ -308,9 +325,9 @@ Task TF2::load_task (const std::string& line) { Task::status status = task.getStatus (); // Completed / deleted tasks in pending.data get an ID if GC is off. - if (! context.run_gc || + if (! Context::getContext ().run_gc || (status != Task::completed && status != Task::deleted)) - task.id = context.tdb2.next_id (); + task.id = Context::getContext ().tdb2.next_id (); } // Maintain mapping for ease of link/dependency resolution. @@ -330,41 +347,41 @@ Task TF2::load_task (const std::string& line) // or needs to be 'woken'. void TF2::load_gc (Task& task) { - ISO8601d now; + Datetime now; std::string status = task.get ("status"); if (status == "pending" || status == "recurring") { - context.tdb2.pending._tasks.push_back (task); + Context::getContext ().tdb2.pending._tasks.push_back (task); } else if (status == "waiting") { - ISO8601d wait (task.get_date ("wait")); + Datetime wait (task.get_date ("wait")); if (wait < now) { task.set ("status", "pending"); task.remove ("wait"); // Unwaiting pending tasks is the only case not caught by the size() // checks in TDB2::gc(), so we need to signal it here. - context.tdb2.pending._dirty = true; + Context::getContext ().tdb2.pending._dirty = true; - if (context.verbose ("unwait")) - context.footnote (format (STRING_TDB2_UNWAIT, task.get ("description"))); + if (Context::getContext ().verbose ("unwait")) + Context::getContext ().footnote (format ("Un-waiting task {1} '{2}'", task.id, task.get ("description"))); } - context.tdb2.pending._tasks.push_back (task); + Context::getContext ().tdb2.pending._tasks.push_back (task); } else { - context.tdb2.completed._tasks.push_back (task); + Context::getContext ().tdb2.completed._tasks.push_back (task); } } //////////////////////////////////////////////////////////////////////////////// void TF2::load_tasks (bool from_gc /* = false */) { - context.timer_load.start (); + Timer timer; if (! _loaded_lines) { @@ -392,7 +409,7 @@ void TF2::load_tasks (bool from_gc /* = false */) else _tasks.push_back (task); - if (context.cli2.getCommand () == "import") // For faster lookup only + if (Context::getContext ().cli2.getCommand () == "import") // For faster lookup only _tasks_map.insert (std::pair (task.get("uuid"), task)); } @@ -405,10 +422,10 @@ void TF2::load_tasks (bool from_gc /* = false */) catch (const std::string& e) { - throw e + format (STRING_TDB2_PARSE_ERROR, _file._data, line_number); + throw e + format (" in {1} at line {2}", _file._data, line_number); } - context.timer_load.stop (); + Context::getContext ().time_load_us += timer.total_us (); } //////////////////////////////////////////////////////////////////////////////// @@ -416,7 +433,7 @@ void TF2::load_lines () { if (_file.open ()) { - if (context.config.getBoolean ("locking")) + if (Context::getContext ().config.getBoolean ("locking")) _file.lock (); _file.read (_lines); @@ -492,6 +509,7 @@ void TF2::clear () _tasks.clear (); _added_tasks.clear (); _modified_tasks.clear (); + _purged_tasks.clear (); _lines.clear (); _added_lines.clear (); _I2U.clear (); @@ -509,10 +527,7 @@ void TF2::dependency_scan () { if (left.has ("depends")) { - std::vector deps; - left.getDependencies (deps); - - for (auto& dep : deps) + for (auto& dep : left.getDependencyUUIDs ()) { for (auto& right : _tasks) { @@ -553,8 +568,8 @@ const std::string TF2::dump () label = rightJustify (_file._data.substr (slash + 1), 14); // File mode. - std::string mode = std::string (_file.readable () ? "r" : "-") + - std::string (_file.writable () ? "w" : "-"); + std::string mode = std::string (_file.exists () && _file.readable () ? "r" : "-") + + std::string (_file.exists () && _file.writable () ? "w" : "-"); if (mode == "r-") mode = red.colorize (mode); else if (mode == "rw") mode = green.colorize (mode); else mode = yellow.colorize (mode); @@ -565,17 +580,19 @@ const std::string TF2::dump () std::string tasks = green.colorize (rightJustifyZero ((int) _tasks.size (), 4)); std::string tasks_added = red.colorize (rightJustifyZero ((int) _added_tasks.size (), 3)); std::string tasks_modified = yellow.colorize (rightJustifyZero ((int) _modified_tasks.size (), 3)); + std::string tasks_purged = red.colorize (rightJustifyZero ((int) _purged_tasks.size (), 3)); std::string lines = green.colorize (rightJustifyZero ((int) _lines.size (), 4)); std::string lines_added = red.colorize (rightJustifyZero ((int) _added_lines.size (), 3)); char buffer[256]; // Composed string is actually 246 bytes. Yikes. - snprintf (buffer, 256, "%14s %s %s T%s+%s~%s L%s+%s", + snprintf (buffer, 256, "%14s %s %s T%s+%s~%s-%s L%s+%s", label.c_str (), mode.c_str (), hygiene.c_str (), tasks.c_str (), tasks_added.c_str (), tasks_modified.c_str (), + tasks_purged.c_str (), lines.c_str (), lines_added.c_str ()); @@ -621,12 +638,12 @@ void TDB2::add (Task& task, bool add_to_backlog /* = true */) // If the tasks are loaded, then verify that this uuid is not already in // the file. if (!verifyUniqueUUID (uuid)) - throw format (STRING_TDB2_UUID_NOT_UNIQUE, uuid); + throw format ("Cannot add task because the uuid '{1}' is not unique.", uuid); // Only locally-added tasks trigger hooks. This means that tasks introduced // via 'sync' do not trigger hooks. if (add_to_backlog) - context.hooks.onAdd (task); + Context::getContext ().hooks.onAdd (task); update (task, add_to_backlog, true); } @@ -643,12 +660,19 @@ void TDB2::modify (Task& task, bool add_to_backlog /* = true */) { Task original; get (uuid, original); - context.hooks.onModify (original, task); + Context::getContext ().hooks.onModify (original, task); } update (task, add_to_backlog); } +//////////////////////////////////////////////////////////////////////////////// +void TDB2::purge (Task& task) +{ + // Delete the task from completed.data + completed.purge_task (task); +} + //////////////////////////////////////////////////////////////////////////////// void TDB2::update ( Task& task, @@ -681,9 +705,9 @@ void TDB2::update ( // old // new // --- - undo.add_line ("time " + ISO8601d ().toEpochString () + "\n"); - undo.add_line ("old " + original.composeF4 () + "\n"); - undo.add_line ("new " + task.composeF4 () + "\n"); + undo.add_line ("time " + Datetime ().toEpochString () + '\n'); + undo.add_line ("old " + original.composeF4 () + '\n'); + undo.add_line ("new " + task.composeF4 () + '\n'); undo.add_line ("---\n"); } else @@ -700,19 +724,21 @@ void TDB2::update ( // time