mirror of
https://salsa.debian.org/dskoll/remind.git
synced 2026-04-16 06:18:47 +02:00
Compare commits
100 Commits
05.04.00-B
...
05.05.00
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
86dcd9ce89 | ||
|
|
4915dc1e8d | ||
|
|
8c4cff22a5 | ||
|
|
50850134f6 | ||
|
|
a5de77cc91 | ||
|
|
87e4ed23bf | ||
|
|
0fe1d1591e | ||
|
|
dfb137085a | ||
|
|
143cdecb9e | ||
|
|
183ccf9d1c | ||
|
|
56ad4efb1a | ||
|
|
f4805a443b | ||
|
|
977aa3d6cf | ||
|
|
fe7ac980e5 | ||
|
|
aebab73dfa | ||
|
|
9bd0055d4d | ||
|
|
d944ceb32d | ||
|
|
3eadb3f767 | ||
|
|
be8a0621d1 | ||
|
|
235f947dd1 | ||
|
|
93dddec24a | ||
|
|
c13b721550 | ||
|
|
1c961dca83 | ||
|
|
700ac85e54 | ||
|
|
e20a14109a | ||
|
|
a3703173e2 | ||
|
|
7325375ccd | ||
|
|
4b898b2ba1 | ||
|
|
aa3760bc04 | ||
|
|
ea5e8c90ff | ||
|
|
609b68ab21 | ||
|
|
c3ab2a15cf | ||
|
|
418b050b1c | ||
|
|
4ab8897577 | ||
|
|
9613417a2e | ||
|
|
f808a2963d | ||
|
|
96a4dc3189 | ||
|
|
3c60285466 | ||
|
|
6fed350e1f | ||
|
|
9f220555af | ||
|
|
005ccef953 | ||
|
|
578c98c865 | ||
|
|
64bf3381c6 | ||
|
|
02ade6fc58 | ||
|
|
2954fca8d8 | ||
|
|
8356dacf2a | ||
|
|
4fd145cf4e | ||
|
|
1af2bdf8f1 | ||
|
|
9b98e65e01 | ||
|
|
0f83b98698 | ||
|
|
4fd62f9894 | ||
|
|
cc06592fe0 | ||
|
|
21d28ebfc3 | ||
|
|
b300422cdb | ||
|
|
37e09f4671 | ||
|
|
b6e53341c8 | ||
|
|
896fcf1d7f | ||
|
|
72155329f2 | ||
|
|
36c7db510a | ||
|
|
d4aa73747d | ||
|
|
3ed657b708 | ||
|
|
0441c0263b | ||
|
|
c40d4ee672 | ||
|
|
96f2d6537a | ||
|
|
dc777c95df | ||
|
|
3090d77346 | ||
|
|
157d2821f3 | ||
|
|
71d2da19a8 | ||
|
|
516b9c81b3 | ||
|
|
58d0e38f1a | ||
|
|
68d487ade9 | ||
|
|
9d42879170 | ||
|
|
db70aabc97 | ||
|
|
c8f55ef60b | ||
|
|
44b50fc6be | ||
|
|
a69a96529b | ||
|
|
f4e5cc63a6 | ||
|
|
136122b1db | ||
|
|
4cc63b1548 | ||
|
|
9390b4335b | ||
|
|
1fcf11a816 | ||
|
|
c4107e6a6f | ||
|
|
ab03232341 | ||
|
|
51a65841cd | ||
|
|
5035deaff1 | ||
|
|
09caa8988a | ||
|
|
9624b1045c | ||
|
|
102748397f | ||
|
|
f852f7e7e5 | ||
|
|
8d88192483 | ||
|
|
a6ca571fe5 | ||
|
|
2af783a58d | ||
|
|
af2daa7a87 | ||
|
|
c5bc459dd9 | ||
|
|
edf26eaa14 | ||
|
|
7e5dc26ee5 | ||
|
|
4c2b6031cd | ||
|
|
af8c1630c3 | ||
|
|
0ec43d570c | ||
|
|
1df8b12e71 |
3
Makefile
3
Makefile
@@ -42,6 +42,9 @@ install-stripped:
|
||||
test:
|
||||
@$(MAKE) -C src -s test
|
||||
|
||||
cppcheck:
|
||||
@$(MAKE) -C src cppcheck
|
||||
|
||||
distclean: clean
|
||||
-rm -f config.cache config.log config.status src/Makefile src/version.h src/config.h tests/test.out www/Makefile rem2pdf/Makefile.top rem2pdf/Makefile.old rem2pdf/Makefile rem2pdf/Makefile.PL rem2pdf/bin/rem2pdf rem2html/rem2html
|
||||
-rm -f man/rem.1 man/rem2ps.1 man/remind.1 man/tkremind.1 scripts/tkremind
|
||||
|
||||
33
README.md
33
README.md
@@ -55,6 +55,39 @@ edit custom.h on your behalf:
|
||||
|
||||
`wish ./build.tk`
|
||||
|
||||
## Usage
|
||||
|
||||
Remind is a large and complex program. You can read the full manual page
|
||||
with:
|
||||
|
||||
`man remind`
|
||||
|
||||
after installation. However, the man page is long and detailed and is
|
||||
more of a reference than an introduction. You can get an overview
|
||||
with a [slide deck](https://dianne.skoll.ca/projects/remind/download/remind-oclug.pdf)
|
||||
I made a while back. There's also a (long) [YouTube video](https://www.youtube.com/watch?v=0SNgvsDvx7M) that serves as an
|
||||
introduction to Remind.
|
||||
|
||||
## A Note about AI
|
||||
|
||||
1. No part of Remind was written using AI of any type.<br><br>
|
||||
I certify that all of the C, Perl and Tcl code in Remind was written
|
||||
by a human being. I certify that all code in `.rem` files other than
|
||||
ones under `include/holidays` was written by a human being. The code
|
||||
under `include/holidays` was derived from the Python "holidays" library
|
||||
and I have no direct knowledge of the provenance of that library,
|
||||
though I suspect it's entirely or almost entirely human-written.
|
||||
|
||||
2. No AI-generated patches or other sorts of contributions to Remind
|
||||
will be accepted.
|
||||
|
||||
3. Remind's source code may not be used to train an AI model,
|
||||
including an LLM model, unless all of the output of said model is
|
||||
released under the GNU General Public License, version 2. If you use
|
||||
any of Remind's source code to train your model, then anything that
|
||||
the model produces is a derived product of Remind and must be licensed
|
||||
under the same terms as Remind.
|
||||
|
||||
---
|
||||
|
||||
Contact info: dianne@skoll.ca
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
dnl Process this file with autoconf to produce a configure script.
|
||||
|
||||
AC_INIT(remind, 05.04.00, , , https://dianne.skoll.ca/projects/remind/)
|
||||
AC_INIT(remind, 05.05.00, , , https://dianne.skoll.ca/projects/remind/)
|
||||
AC_CONFIG_SRCDIR([src/queue.c])
|
||||
|
||||
cat <<'EOF'
|
||||
|
||||
@@ -110,15 +110,17 @@
|
||||
(defconst remind-keywords
|
||||
(sort
|
||||
(list "ADDOMIT" "AFTER" "AT" "BAN" "BANNER" "BEFORE" "CAL" "CLEAR"
|
||||
"CLEAR-OMIT-CONTEXT" "DEBUG" "DO" "DUMP" "DUMPVARS" "DURATION" "ELSE"
|
||||
"ENDIF" "ERRMSG" "EXIT" "EXPR" "FIRST" "FLUSH" "FOURTH" "FRENAME" "FROM" "FSET"
|
||||
"FUNSET" "IF" "IFTRIG" "IN" "INC" "INCLUDE" "INCLUDECMD" "INFO" "LAST"
|
||||
"LASTDAY" "LASTWORKDAY" "MAYBE" "MAYBE-UNCOMPUTABLE" "MSF" "MSG"
|
||||
"NOQUEUE" "OMIT" "OMITFUNC" "ONCE" "POP" "POP-OMIT-CONTEXT" "PRESERVE"
|
||||
"PRIORITY" "PS" "PSFILE" "PUSH" "PUSH-OMIT-CONTEXT" "REM" "RUN"
|
||||
"SATISFY" "SCAN" "SCANFROM" "SCHED" "SECOND" "SET" "SKIP" "SPECIAL"
|
||||
"SYSINCLUDE" "TAG" "THIRD" "THROUGH" "TRANSLATE" "TRANS" "UNSET"
|
||||
"UNTIL" "WARN")
|
||||
"CLEAR-OMIT-CONTEXT" "DEBUG" "DO" "DUMP" "DUMPVARS"
|
||||
"DURATION" "ELSE" "ENDIF" "ERRMSG" "EXIT" "EXPR" "FIRST"
|
||||
"FLUSH" "FOURTH" "FRENAME" "FROM" "FSET" "FUNSET" "IF"
|
||||
"IFTRIG" "IN" "INC" "INCLUDE" "INCLUDECMD" "INFO" "LAST"
|
||||
"LASTDAY" "LASTWORKDAY" "MAYBE" "MAYBE-UNCOMPUTABLE" "MSF"
|
||||
"MSG" "NOQUEUE" "OMIT" "OMITFUNC" "ONCE" "POP"
|
||||
"POP-OMIT-CONTEXT" "POP-FUNCS" "POP-VARS" "PRESERVE" "PRIORITY" "PS"
|
||||
"PSFILE" "PUSH" "PUSH-FUNCS" "PUSH-VARS" "PUSH-OMIT-CONTEXT" "REM"
|
||||
"RUN" "SATISFY" "SCAN" "SCANFROM" "SCHED" "SECOND" "SET"
|
||||
"SKIP" "SPECIAL" "SYSINCLUDE" "TAG" "THIRD" "THROUGH"
|
||||
"TRANSLATE" "TRANS" "UNSET" "UNTIL" "WARN")
|
||||
#'(lambda (a b) (> (length a) (length b)))))
|
||||
|
||||
|
||||
@@ -164,7 +166,7 @@
|
||||
(defconst remind-builtin-functions
|
||||
(sort
|
||||
(list "_" "abs" "access" "adawn" "adusk" "ampm" "ansicolor" "args" "asc"
|
||||
"baseyr" "catch" "catcherr" "char" "choose" "coerce" "columns" "current" "date"
|
||||
"baseyr" "catch" "catcherr" "char" "choose" "coerce" "columns" "const" "current" "date"
|
||||
"datepart" "datetime" "dawn" "day" "daysinmon" "defined" "dosubst"
|
||||
"dusk" "easterdate" "escape" "eval" "evaltrig" "filedate" "filedatetime"
|
||||
"filedir" "filename" "getenv" "hebdate" "hebday" "hebmon" "hebyear"
|
||||
|
||||
@@ -1,6 +1,51 @@
|
||||
CHANGES TO REMIND
|
||||
|
||||
* VERSION 5.4 Patch 0 - 2025-??-??
|
||||
* VERSION 5.5 Patch 0 - 2025-07-28
|
||||
|
||||
- NEW FEATURE: remind: Add the PUSH-VARS / POP-VARS commands and the
|
||||
analogous PUSH-FUNCS / POP-FUNCS commands. These let you localize
|
||||
changes to variables and functions and help with writing more modular
|
||||
reminder files.
|
||||
|
||||
- INTERNAL CHANGES: Clean up the code following recommendations from
|
||||
an updated "cppcheck" executable.
|
||||
|
||||
* VERSION 5.4 Patch 2 - 2025-07-16
|
||||
|
||||
- MINOR CHANGE: remind: Allow daysinmon() to take a DATE or DATETIME
|
||||
argument.
|
||||
|
||||
- MINOR CHANGE: remind: All functions that want an integer month number
|
||||
will now also accept a string naming the month.
|
||||
|
||||
= UPDATE: include/holidays/chinese-new-year.rem: Add dates for Chinese
|
||||
New Year for 2051 through 2100.
|
||||
|
||||
- BUG FIX: remind: Set trigdate() correctly for a fully-specified
|
||||
date, even if it's in the past, as the manual documented. Bug
|
||||
found by Tim Chase.
|
||||
|
||||
- DOCUMENTATION FIX: rem2html: Document the correct Perl module
|
||||
prerequisites.
|
||||
|
||||
- CODE FIXES: remind: Various minor improvements to the code with
|
||||
no user-visible changes.
|
||||
|
||||
* VERSION 5.4 Patch 1 - 2025-06-15
|
||||
|
||||
- MAJOR BUG FIX: remind: In some circumstances, a REM command could
|
||||
yield a trigger date after its UNTIL date, rather than recognizing it
|
||||
as having expired. This has been fixed. Bug found by Ian! D. Allen.
|
||||
|
||||
- BUG FIX: rem2pdf: Support the COLOUR special (as well as COLOR).
|
||||
|
||||
- MINOR IMPROVEMENT: Add include/utils/add-html-anchors.rem. You can
|
||||
INCLUDE this file to get HTML anchors added to every calendar day
|
||||
by rem2html.
|
||||
|
||||
- DOCUMENTATION: Add NOTE-ABOUT-AI.txt
|
||||
|
||||
* VERSION 5.4 Patch 0 - 2025-06-03
|
||||
|
||||
- MAJOR IMPROVEMENT: remind: Track which expressions and variables
|
||||
Remind can prove to its satisfaction are "constant" - that is, that
|
||||
@@ -11,16 +56,38 @@ CHANGES TO REMIND
|
||||
See the new remind(1) man page section "NON-CONSTANT EXPRESSIONS"
|
||||
|
||||
- MINOR NEW FEATURE: remind: add the "nonconst" built-in function (to
|
||||
force an expression to be interpreted as non-constant) and the
|
||||
"isconst" function to test if an expression is constant.
|
||||
force an expression to be interpreted as non-constant), the "const"
|
||||
function to force an expression to be interpreted as constant, and
|
||||
the "isconst" function to test if an expression is constant.
|
||||
|
||||
- MINOR NEW FEATURE: remind: Add eval() built-in function that takes a
|
||||
string argument and evaluates it as an expression.
|
||||
string argument and evaluates it as an expression. For safety, the
|
||||
"shell" function is disabled inside an eval().
|
||||
|
||||
- MINOR NEW FEATURE: remind: add the "u" debugging flag to warn you if
|
||||
you set a variable that is not subsequently used.
|
||||
|
||||
- MINOR NEW FEATURE: remind: Add the trigbase() function and
|
||||
corresponding $Tb system variable. See the remind(1) man page for
|
||||
details.
|
||||
|
||||
- MINOR IMPROVEMENT: remind: make value("var", default) evaluate the
|
||||
second argument lazily: If "var" is defined, then the second
|
||||
argument is never evaluated.
|
||||
|
||||
- MINOR IMPROVEMENT: remind: Add syntax for redefining a function without
|
||||
issuing a warning. The syntax:
|
||||
|
||||
FSET - func(x) expr
|
||||
|
||||
is equivalent to:
|
||||
|
||||
FUNSET func
|
||||
FSET func(x) expr
|
||||
|
||||
- MINOR IMPROVEMENT: include/holidays: Update a bunch of files to use
|
||||
isany(n, a, b, c) rather than (n == a || n == b || n == c)
|
||||
|
||||
- MINOR IMPROVEMENT: remind: Make $Tu a synonym for triguntil().
|
||||
|
||||
- MINOR IMPROVEMENT: remind: If coerce() fails, issue a more detailed
|
||||
@@ -50,7 +117,7 @@ CHANGES TO REMIND
|
||||
corresponding weekday number returned.
|
||||
|
||||
- MINOR IMPROVEMENT: remind: Make the expression parser optimize away
|
||||
"- INT_CONSTANT" and "! INT_CONSTANT".
|
||||
the unary "-" and "!" operators when followed by an integer constant.
|
||||
|
||||
- BUG FIX: tests: Don't use the obsolete "tail +2" syntax in test-rem.
|
||||
Fix courtesy of Dick Marinus.
|
||||
@@ -1492,10 +1559,10 @@ CHANGES TO REMIND
|
||||
- NEW FEATURE: Add "-u+username" variant to tell Remind to switch users to
|
||||
"username" without disabling RUN directives. Idea courtesy of Ian! D. Allen
|
||||
|
||||
- CHANGE: rem2html: rem2html has been moved out of the www/ directory into
|
||||
its own rem2html/ directory. If your system has the prerequisites
|
||||
(namely Perl, Getopt::Long and JSON::Any) then rem2html will be installed
|
||||
by "make install".
|
||||
- CHANGE: rem2html: rem2html has been moved out of the www/ directory
|
||||
into its own rem2html/ directory. If your system has the
|
||||
prerequisites (namely Perl, Getopt::Long and JSON::MaybeXS) then
|
||||
rem2html will be installed by "make install".
|
||||
|
||||
- CHANGE: Remove "cm2rem". It was about 20 years obsolete.
|
||||
|
||||
|
||||
@@ -28,7 +28,7 @@ if !defined("ansi_bold")
|
||||
set ansi_underline2 char(27) + "[21m"
|
||||
set ansi_overline char(27) + "[53m"
|
||||
endif
|
||||
preserve ansi_normal ansi_bold ansi_faint ansi_italic ansi_underline2 ansi_reverse ansi_strikeout ansi_underline2 ansi_overline
|
||||
preserve ansi_normal ansi_bold ansi_faint ansi_italic ansi_underline ansi_reverse ansi_strikeout ansi_underline2 ansi_overline
|
||||
endif
|
||||
|
||||
# Example: REM MSG I must [ansi_bold]emphasize[ansi_normal] \
|
||||
|
||||
@@ -38,10 +38,10 @@ You can use the following trick if you would like (for example) 7 days'
|
||||
advance warning of holidays:
|
||||
|
||||
# Save old definition (if any) of msgsuffix
|
||||
FRENAME msgsuffix saved_msgsuffix
|
||||
PUSH-FUNCS msgsuffix
|
||||
|
||||
# Save old value of $DefaultDelta
|
||||
SET old_delta $DefaultDelta
|
||||
PUSH-VARS $DefaultDelta
|
||||
|
||||
# We want 7 days' advance warning
|
||||
SET $DefaultDelta 7
|
||||
@@ -57,6 +57,9 @@ advance warning of holidays:
|
||||
SYSINCLUDE holidays/us.rem
|
||||
SYSINCLUDE holidays/us/ny.rem
|
||||
|
||||
# Restore old version of msgsuffix and $DefaultDelta
|
||||
FRENAME saved_msgsuffix msgsuffix
|
||||
SET $DefaultDelta old_delta
|
||||
# Restore old value $DefaultDelta
|
||||
POP-VARS
|
||||
|
||||
# Restore old version of msgsuffix
|
||||
POP-FUNCS
|
||||
|
||||
|
||||
@@ -6,28 +6,28 @@
|
||||
# See important caveats in the README file in this directory.
|
||||
|
||||
OMIT 1 January MSG Festat e Vitit të Ri
|
||||
REM 1 January OMIT SAT SUN AFTER ADDOMIT SCANFROM -28 SATISFY [wkdaynum(date($Ty, 1, 1))==0 || wkdaynum(date($Ty, 1, 1))==6] MSG Festat e Vitit të Ri (ditë pushimi e shtyrë)
|
||||
REM 1 January OMIT SAT SUN AFTER ADDOMIT SCANFROM -28 SATISFY [isany(wkdaynum(date($Ty, 1, 1)), 0, 6)] MSG Festat e Vitit të Ri (ditë pushimi e shtyrë)
|
||||
OMIT 2 January MSG Festat e Vitit të Ri
|
||||
REM 2 January OMIT SAT SUN AFTER ADDOMIT SCANFROM -28 SATISFY [wkdaynum(date($Ty, 1, 2))==0 || wkdaynum(date($Ty, 1, 2))==6] MSG Festat e Vitit të Ri (ditë pushimi e shtyrë)
|
||||
REM 2 January OMIT SAT SUN AFTER ADDOMIT SCANFROM -28 SATISFY [isany(wkdaynum(date($Ty, 1, 2)), 0, 6)] MSG Festat e Vitit të Ri (ditë pushimi e shtyrë)
|
||||
OMIT 14 March MSG Dita e Verës
|
||||
REM 14 March OMIT SAT SUN AFTER ADDOMIT SCANFROM -28 SATISFY [wkdaynum(date($Ty, 3, 14))==0 || wkdaynum(date($Ty, 3, 14))==6] MSG Dita e Verës (ditë pushimi e shtyrë)
|
||||
REM 14 March OMIT SAT SUN AFTER ADDOMIT SCANFROM -28 SATISFY [isany(wkdaynum(date($Ty, 3, 14)), 0, 6)] MSG Dita e Verës (ditë pushimi e shtyrë)
|
||||
OMIT 22 March MSG Dita e Nevruzit
|
||||
REM 22 March OMIT SAT SUN AFTER ADDOMIT SCANFROM -28 SATISFY [wkdaynum(date($Ty, 3, 22))==0 || wkdaynum(date($Ty, 3, 22))==6] MSG Dita e Nevruzit (ditë pushimi e shtyrë)
|
||||
REM 31 March OMIT SAT SUN AFTER ADDOMIT SCANFROM -28 SATISFY [wkdaynum(date($Ty, 3, 31))==0 || wkdaynum(date($Ty, 3, 31))==6] MSG E diela e Pashkëve Katolike (ditë pushimi e shtyrë)
|
||||
REM 22 March OMIT SAT SUN AFTER ADDOMIT SCANFROM -28 SATISFY [isany(wkdaynum(date($Ty, 3, 22)), 0, 6)] MSG Dita e Nevruzit (ditë pushimi e shtyrë)
|
||||
REM 31 March OMIT SAT SUN AFTER ADDOMIT SCANFROM -28 SATISFY [isany(wkdaynum(date($Ty, 3, 31)), 0, 6)] MSG E diela e Pashkëve Katolike (ditë pushimi e shtyrë)
|
||||
OMIT [easterdate($Uy)] MSG E diela e Pashkëve Katolike
|
||||
OMIT [easterdate($Uy)] MSG E diela e Pashkëve Ortodokse
|
||||
OMIT 1 May MSG Dita Ndërkombëtare e Punëtorëve
|
||||
REM 1 May OMIT SAT SUN AFTER ADDOMIT SCANFROM -28 SATISFY [wkdaynum(date($Ty, 5, 1))==0 || wkdaynum(date($Ty, 5, 1))==6] MSG Dita Ndërkombëtare e Punëtorëve (ditë pushimi e shtyrë)
|
||||
REM 5 May OMIT SAT SUN AFTER ADDOMIT SCANFROM -28 SATISFY [wkdaynum(date($Ty, 5, 5))==0 || wkdaynum(date($Ty, 5, 5))==6] MSG E diela e Pashkëve Ortodokse (ditë pushimi e shtyrë)
|
||||
REM 1 May OMIT SAT SUN AFTER ADDOMIT SCANFROM -28 SATISFY [isany(wkdaynum(date($Ty, 5, 1)), 0, 6)] MSG Dita Ndërkombëtare e Punëtorëve (ditë pushimi e shtyrë)
|
||||
REM 5 May OMIT SAT SUN AFTER ADDOMIT SCANFROM -28 SATISFY [isany(wkdaynum(date($Ty, 5, 5)), 0, 6)] MSG E diela e Pashkëve Ortodokse (ditë pushimi e shtyrë)
|
||||
OMIT 5 September MSG Dita e Shenjtërimit të Shenjt Terezës
|
||||
REM 5 September OMIT SAT SUN AFTER ADDOMIT SCANFROM -28 SATISFY [wkdaynum(date($Ty, 9, 5))==0 || wkdaynum(date($Ty, 9, 5))==6] MSG Dita e Shenjtërimit të Shenjt Terezës (ditë pushimi e shtyrë)
|
||||
REM 5 September OMIT SAT SUN AFTER ADDOMIT SCANFROM -28 SATISFY [isany(wkdaynum(date($Ty, 9, 5)), 0, 6)] MSG Dita e Shenjtërimit të Shenjt Terezës (ditë pushimi e shtyrë)
|
||||
OMIT 22 November MSG Dita e Alfabetit
|
||||
REM 22 November OMIT SAT SUN AFTER ADDOMIT SCANFROM -28 SATISFY [wkdaynum(date($Ty, 11, 22))==0 || wkdaynum(date($Ty, 11, 22))==6] MSG Dita e Alfabetit (ditë pushimi e shtyrë)
|
||||
REM 22 November OMIT SAT SUN AFTER ADDOMIT SCANFROM -28 SATISFY [isany(wkdaynum(date($Ty, 11, 22)), 0, 6)] MSG Dita e Alfabetit (ditë pushimi e shtyrë)
|
||||
OMIT 28 November MSG Dita Flamurit dhe e Pavarësisë
|
||||
REM 28 November OMIT SAT SUN AFTER ADDOMIT SCANFROM -28 SATISFY [wkdaynum(date($Ty, 11, 28))==0 || wkdaynum(date($Ty, 11, 28))==6] MSG Dita Flamurit dhe e Pavarësisë (ditë pushimi e shtyrë)
|
||||
REM 28 November OMIT SAT SUN AFTER ADDOMIT SCANFROM -28 SATISFY [isany(wkdaynum(date($Ty, 11, 28)), 0, 6)] MSG Dita Flamurit dhe e Pavarësisë (ditë pushimi e shtyrë)
|
||||
OMIT 29 November MSG Dita e Çlirimit
|
||||
REM 29 November OMIT SAT SUN AFTER ADDOMIT SCANFROM -28 SATISFY [wkdaynum(date($Ty, 11, 29))==0 || wkdaynum(date($Ty, 11, 29))==6] MSG Dita e Çlirimit (ditë pushimi e shtyrë)
|
||||
REM 29 November OMIT SAT SUN AFTER ADDOMIT SCANFROM -28 SATISFY [isany(wkdaynum(date($Ty, 11, 29)), 0, 6)] MSG Dita e Çlirimit (ditë pushimi e shtyrë)
|
||||
OMIT 8 December MSG Dita Kombëtare e Rinisë
|
||||
REM 8 December OMIT SAT SUN AFTER ADDOMIT SCANFROM -28 SATISFY [wkdaynum(date($Ty, 12, 8))==0 || wkdaynum(date($Ty, 12, 8))==6] MSG Dita Kombëtare e Rinisë (ditë pushimi e shtyrë)
|
||||
REM 8 December OMIT SAT SUN AFTER ADDOMIT SCANFROM -28 SATISFY [isany(wkdaynum(date($Ty, 12, 8)), 0, 6)] MSG Dita Kombëtare e Rinisë (ditë pushimi e shtyrë)
|
||||
OMIT 25 December MSG Krishtlindjet
|
||||
REM 25 December OMIT SAT SUN AFTER ADDOMIT SCANFROM -28 SATISFY [wkdaynum(date($Ty, 12, 25))==0 || wkdaynum(date($Ty, 12, 25))==6] MSG Krishtlindjet (ditë pushimi e shtyrë)
|
||||
REM 25 December OMIT SAT SUN AFTER ADDOMIT SCANFROM -28 SATISFY [isany(wkdaynum(date($Ty, 12, 25)), 0, 6)] MSG Krishtlindjet (ditë pushimi e shtyrë)
|
||||
|
||||
@@ -6,36 +6,36 @@
|
||||
# See important caveats in the README file in this directory.
|
||||
|
||||
OMIT 1 January MSG Yeni il bayramı
|
||||
REM 1 January OMIT SAT SUN AFTER ADDOMIT SCANFROM -28 SATISFY [wkdaynum(date($Ty, 1, 1))==0 || wkdaynum(date($Ty, 1, 1))==6] MSG Yeni il bayramı (müşahidə olunur)
|
||||
REM 1 January OMIT SAT SUN AFTER ADDOMIT SCANFROM -28 SATISFY [isany(wkdaynum(date($Ty, 1, 1)), 0, 6)] MSG Yeni il bayramı (müşahidə olunur)
|
||||
OMIT 2 January MSG Yeni il bayramı
|
||||
REM 2 January OMIT SAT SUN AFTER ADDOMIT SCANFROM -28 SATISFY [wkdaynum(date($Ty, 1, 2))==0 || wkdaynum(date($Ty, 1, 2))==6] MSG Yeni il bayramı (müşahidə olunur)
|
||||
REM 2 January OMIT SAT SUN AFTER ADDOMIT SCANFROM -28 SATISFY [isany(wkdaynum(date($Ty, 1, 2)), 0, 6)] MSG Yeni il bayramı (müşahidə olunur)
|
||||
OMIT 20 January MSG Ümumxalq hüzn günü
|
||||
OMIT 8 March MSG Qadınlar günü
|
||||
REM 8 March OMIT SAT SUN AFTER ADDOMIT SCANFROM -28 SATISFY [wkdaynum(date($Ty, 3, 8))==0 || wkdaynum(date($Ty, 3, 8))==6] MSG Qadınlar günü (müşahidə olunur)
|
||||
REM 8 March OMIT SAT SUN AFTER ADDOMIT SCANFROM -28 SATISFY [isany(wkdaynum(date($Ty, 3, 8)), 0, 6)] MSG Qadınlar günü (müşahidə olunur)
|
||||
OMIT 20 March MSG Novruz bayramı
|
||||
REM 20 March OMIT SAT SUN AFTER ADDOMIT SCANFROM -28 SATISFY [wkdaynum(date($Ty, 3, 20))==0 || wkdaynum(date($Ty, 3, 20))==6] MSG Novruz bayramı (müşahidə olunur)
|
||||
REM 20 March OMIT SAT SUN AFTER ADDOMIT SCANFROM -28 SATISFY [isany(wkdaynum(date($Ty, 3, 20)), 0, 6)] MSG Novruz bayramı (müşahidə olunur)
|
||||
OMIT 21 March MSG Novruz bayramı
|
||||
REM 21 March OMIT SAT SUN AFTER ADDOMIT SCANFROM -28 SATISFY [wkdaynum(date($Ty, 3, 21))==0 || wkdaynum(date($Ty, 3, 21))==6] MSG Novruz bayramı (müşahidə olunur)
|
||||
REM 21 March OMIT SAT SUN AFTER ADDOMIT SCANFROM -28 SATISFY [isany(wkdaynum(date($Ty, 3, 21)), 0, 6)] MSG Novruz bayramı (müşahidə olunur)
|
||||
OMIT 22 March MSG Novruz bayramı
|
||||
REM 22 March OMIT SAT SUN AFTER ADDOMIT SCANFROM -28 SATISFY [wkdaynum(date($Ty, 3, 22))==0 || wkdaynum(date($Ty, 3, 22))==6] MSG Novruz bayramı (müşahidə olunur)
|
||||
REM 22 March OMIT SAT SUN AFTER ADDOMIT SCANFROM -28 SATISFY [isany(wkdaynum(date($Ty, 3, 22)), 0, 6)] MSG Novruz bayramı (müşahidə olunur)
|
||||
OMIT 23 March MSG Novruz bayramı
|
||||
REM 23 March OMIT SAT SUN AFTER ADDOMIT SCANFROM -28 SATISFY [wkdaynum(date($Ty, 3, 23))==0 || wkdaynum(date($Ty, 3, 23))==6] MSG Novruz bayramı (müşahidə olunur)
|
||||
REM 23 March OMIT SAT SUN AFTER ADDOMIT SCANFROM -28 SATISFY [isany(wkdaynum(date($Ty, 3, 23)), 0, 6)] MSG Novruz bayramı (müşahidə olunur)
|
||||
OMIT 24 March MSG Novruz bayramı
|
||||
REM 24 March OMIT SAT SUN AFTER ADDOMIT SCANFROM -28 SATISFY [wkdaynum(date($Ty, 3, 24))==0 || wkdaynum(date($Ty, 3, 24))==6] MSG Novruz bayramı (müşahidə olunur)
|
||||
REM 24 March OMIT SAT SUN AFTER ADDOMIT SCANFROM -28 SATISFY [isany(wkdaynum(date($Ty, 3, 24)), 0, 6)] MSG Novruz bayramı (müşahidə olunur)
|
||||
OMIT 9 May MSG Faşizm üzərində qələbə günü
|
||||
REM 9 May OMIT SAT SUN AFTER ADDOMIT SCANFROM -28 SATISFY [wkdaynum(date($Ty, 5, 9))==0 || wkdaynum(date($Ty, 5, 9))==6] MSG Faşizm üzərində qələbə günü (müşahidə olunur)
|
||||
REM 9 May OMIT SAT SUN AFTER ADDOMIT SCANFROM -28 SATISFY [isany(wkdaynum(date($Ty, 5, 9)), 0, 6)] MSG Faşizm üzərində qələbə günü (müşahidə olunur)
|
||||
OMIT 28 May MSG Müstəqillik Günü
|
||||
REM 28 May OMIT SAT SUN AFTER ADDOMIT SCANFROM -28 SATISFY [wkdaynum(date($Ty, 5, 28))==0 || wkdaynum(date($Ty, 5, 28))==6] MSG Müstəqillik Günü (müşahidə olunur)
|
||||
REM 28 May OMIT SAT SUN AFTER ADDOMIT SCANFROM -28 SATISFY [isany(wkdaynum(date($Ty, 5, 28)), 0, 6)] MSG Müstəqillik Günü (müşahidə olunur)
|
||||
OMIT 15 June MSG Azərbaycan xalqının milli qurtuluş günü
|
||||
REM 15 June OMIT SAT SUN AFTER ADDOMIT SCANFROM -28 SATISFY [wkdaynum(date($Ty, 6, 15))==0 || wkdaynum(date($Ty, 6, 15))==6] MSG Azərbaycan xalqının milli qurtuluş günü (müşahidə olunur)
|
||||
REM 15 June OMIT SAT SUN AFTER ADDOMIT SCANFROM -28 SATISFY [isany(wkdaynum(date($Ty, 6, 15)), 0, 6)] MSG Azərbaycan xalqının milli qurtuluş günü (müşahidə olunur)
|
||||
OMIT 26 June MSG Azərbaycan Respublikasının Silahlı Qüvvələri günü
|
||||
REM 26 June OMIT SAT SUN AFTER ADDOMIT SCANFROM -28 SATISFY [wkdaynum(date($Ty, 6, 26))==0 || wkdaynum(date($Ty, 6, 26))==6] MSG Azərbaycan Respublikasının Silahlı Qüvvələri günü (müşahidə olunur)
|
||||
REM 26 June OMIT SAT SUN AFTER ADDOMIT SCANFROM -28 SATISFY [isany(wkdaynum(date($Ty, 6, 26)), 0, 6)] MSG Azərbaycan Respublikasının Silahlı Qüvvələri günü (müşahidə olunur)
|
||||
OMIT 8 November MSG Zəfər Günü
|
||||
REM 8 November OMIT SAT SUN AFTER ADDOMIT SCANFROM -28 SATISFY [wkdaynum(date($Ty, 11, 8))==0 || wkdaynum(date($Ty, 11, 8))==6] MSG Zəfər Günü (müşahidə olunur)
|
||||
REM 8 November OMIT SAT SUN AFTER ADDOMIT SCANFROM -28 SATISFY [isany(wkdaynum(date($Ty, 11, 8)), 0, 6)] MSG Zəfər Günü (müşahidə olunur)
|
||||
OMIT 9 November MSG Azərbaycan Respublikasının Dövlət bayrağı günü
|
||||
REM 9 November OMIT SAT SUN AFTER ADDOMIT SCANFROM -28 SATISFY [wkdaynum(date($Ty, 11, 9))==0 || wkdaynum(date($Ty, 11, 9))==6] MSG Azərbaycan Respublikasının Dövlət bayrağı günü (müşahidə olunur)
|
||||
REM 9 November OMIT SAT SUN AFTER ADDOMIT SCANFROM -28 SATISFY [isany(wkdaynum(date($Ty, 11, 9)), 0, 6)] MSG Azərbaycan Respublikasının Dövlət bayrağı günü (müşahidə olunur)
|
||||
OMIT 31 December MSG Dünya azərbaycanlılarının həmrəyliyi günü
|
||||
REM 31 December OMIT SAT SUN AFTER ADDOMIT SCANFROM -28 SATISFY [wkdaynum(date($Ty, 12, 31))==0 || wkdaynum(date($Ty, 12, 31))==6] MSG Dünya azərbaycanlılarının həmrəyliyi günü (müşahidə olunur)
|
||||
REM 31 December OMIT SAT SUN AFTER ADDOMIT SCANFROM -28 SATISFY [isany(wkdaynum(date($Ty, 12, 31)), 0, 6)] MSG Dünya azərbaycanlılarının həmrəyliyi günü (müşahidə olunur)
|
||||
|
||||
# Optional holidays
|
||||
REM 27 September MSG Anım Günü
|
||||
|
||||
@@ -6,29 +6,29 @@
|
||||
# See important caveats in the README file in this directory.
|
||||
|
||||
OMIT 1 January MSG Нова година
|
||||
REM 1 January OMIT SAT SUN AFTER ADDOMIT SCANFROM -28 SATISFY [wkdaynum(date($Ty, 1, 1))==0 || wkdaynum(date($Ty, 1, 1))==6] MSG Нова година (почивен ден)
|
||||
REM 1 January OMIT SAT SUN AFTER ADDOMIT SCANFROM -28 SATISFY [isany(wkdaynum(date($Ty, 1, 1)), 0, 6)] MSG Нова година (почивен ден)
|
||||
OMIT 3 March MSG Ден на Освобождението на България от османско иго
|
||||
REM 3 March OMIT SAT SUN AFTER ADDOMIT SCANFROM -28 SATISFY [wkdaynum(date($Ty, 3, 3))==0 || wkdaynum(date($Ty, 3, 3))==6] MSG Ден на Освобождението на България от османско иго (почивен ден)
|
||||
REM 3 March OMIT SAT SUN AFTER ADDOMIT SCANFROM -28 SATISFY [isany(wkdaynum(date($Ty, 3, 3)), 0, 6)] MSG Ден на Освобождението на България от османско иго (почивен ден)
|
||||
OMIT [orthodoxeaster($Uy)-2] MSG Велики петък
|
||||
OMIT [orthodoxeaster($Uy)-1] MSG Велика събота
|
||||
OMIT [orthodoxeaster($Uy)] MSG Великден
|
||||
OMIT [orthodoxeaster($Uy)+1] MSG Великден
|
||||
OMIT 1 May MSG Ден на труда и на международната работническа солидарност
|
||||
REM 1 May OMIT SAT SUN AFTER ADDOMIT SCANFROM -28 SATISFY [wkdaynum(date($Ty, 5, 1))==0 || wkdaynum(date($Ty, 5, 1))==6] MSG Ден на труда и на международната работническа солидарност (почивен ден)
|
||||
REM 1 May OMIT SAT SUN AFTER ADDOMIT SCANFROM -28 SATISFY [isany(wkdaynum(date($Ty, 5, 1)), 0, 6)] MSG Ден на труда и на международната работническа солидарност (почивен ден)
|
||||
OMIT 6 May MSG Гергьовден, Ден на храбростта и Българската армия
|
||||
REM 6 May OMIT SAT SUN AFTER ADDOMIT SCANFROM -28 SATISFY [wkdaynum(date($Ty, 5, 6))==0 || wkdaynum(date($Ty, 5, 6))==6] MSG Гергьовден, Ден на храбростта и Българската армия (почивен ден)
|
||||
REM 6 May OMIT SAT SUN AFTER ADDOMIT SCANFROM -28 SATISFY [isany(wkdaynum(date($Ty, 5, 6)), 0, 6)] MSG Гергьовден, Ден на храбростта и Българската армия (почивен ден)
|
||||
OMIT 24 May MSG Ден на светите братя Кирил и Методий, на българската азбука, просвета и култура и на славянската книжовност
|
||||
REM 24 May OMIT SAT SUN AFTER ADDOMIT SCANFROM -28 SATISFY [wkdaynum(date($Ty, 5, 24))==0 || wkdaynum(date($Ty, 5, 24))==6] MSG Ден на светите братя Кирил и Методий, на българската азбука, просвета и култура и на славянската книжовност (почивен ден)
|
||||
REM 24 May OMIT SAT SUN AFTER ADDOMIT SCANFROM -28 SATISFY [isany(wkdaynum(date($Ty, 5, 24)), 0, 6)] MSG Ден на светите братя Кирил и Методий, на българската азбука, просвета и култура и на славянската книжовност (почивен ден)
|
||||
OMIT 6 September MSG Ден на Съединението
|
||||
REM 6 September OMIT SAT SUN AFTER ADDOMIT SCANFROM -28 SATISFY [wkdaynum(date($Ty, 9, 6))==0 || wkdaynum(date($Ty, 9, 6))==6] MSG Ден на Съединението (почивен ден)
|
||||
REM 6 September OMIT SAT SUN AFTER ADDOMIT SCANFROM -28 SATISFY [isany(wkdaynum(date($Ty, 9, 6)), 0, 6)] MSG Ден на Съединението (почивен ден)
|
||||
OMIT 22 September MSG Ден на Независимостта на България
|
||||
REM 22 September OMIT SAT SUN AFTER ADDOMIT SCANFROM -28 SATISFY [wkdaynum(date($Ty, 9, 22))==0 || wkdaynum(date($Ty, 9, 22))==6] MSG Ден на Независимостта на България (почивен ден)
|
||||
REM 22 September OMIT SAT SUN AFTER ADDOMIT SCANFROM -28 SATISFY [isany(wkdaynum(date($Ty, 9, 22)), 0, 6)] MSG Ден на Независимостта на България (почивен ден)
|
||||
OMIT 24 December MSG Бъдни вечер
|
||||
REM 24 December OMIT SAT SUN AFTER ADDOMIT SCANFROM -28 SATISFY [wkdaynum(date($Ty, 12, 24))==0 || wkdaynum(date($Ty, 12, 24))==6] MSG Бъдни вечер (почивен ден)
|
||||
REM 24 December OMIT SAT SUN AFTER ADDOMIT SCANFROM -28 SATISFY [isany(wkdaynum(date($Ty, 12, 24)), 0, 6)] MSG Бъдни вечер (почивен ден)
|
||||
OMIT 25 December MSG Рождество Христово
|
||||
REM 25 December OMIT SAT SUN AFTER ADDOMIT SCANFROM -28 SATISFY [wkdaynum(date($Ty, 12, 25))==0 || wkdaynum(date($Ty, 12, 25))==6] MSG Рождество Христово (почивен ден)
|
||||
REM 25 December OMIT SAT SUN AFTER ADDOMIT SCANFROM -28 SATISFY [isany(wkdaynum(date($Ty, 12, 25)), 0, 6)] MSG Рождество Христово (почивен ден)
|
||||
OMIT 26 December MSG Рождество Христово
|
||||
REM 26 December OMIT SAT SUN AFTER ADDOMIT SCANFROM -28 SATISFY [wkdaynum(date($Ty, 12, 26))==0 || wkdaynum(date($Ty, 12, 26))==6] MSG Рождество Христово (почивен ден)
|
||||
REM 26 December OMIT SAT SUN AFTER ADDOMIT SCANFROM -28 SATISFY [isany(wkdaynum(date($Ty, 12, 26)), 0, 6)] MSG Рождество Христово (почивен ден)
|
||||
|
||||
# Optional holidays
|
||||
REM 1 November MSG Ден на народните будители
|
||||
|
||||
@@ -28,3 +28,53 @@ REM 26 Jan 2047 INFO "Url: https://en.wikipedia.org/wiki/Rabbit_(zodiac)" MSG %
|
||||
REM 14 Feb 2048 INFO "Url: https://en.wikipedia.org/wiki/Dragon_(zodiac)" MSG %(Chinese New Year) (%(Dragon))
|
||||
REM 2 Feb 2049 INFO "Url: https://en.wikipedia.org/wiki/Snake_(zodiac)" MSG %(Chinese New Year) (%(Snake))
|
||||
REM 23 Jan 2050 INFO "Url: https://en.wikipedia.org/wiki/Horse_(zodiac)" MSG %(Chinese New Year) (%(Horse))
|
||||
REM 11 Feb 2051 INFO "Url: https://en.wikipedia.org/wiki/Goat_(zodiac)" MSG %(Chinese New Year) (%(Goat))
|
||||
REM 1 Feb 2052 INFO "Url: https://en.wikipedia.org/wiki/Monkey_(zodiac)" MSG %(Chinese New Year) (%(Monkey))
|
||||
REM 19 Feb 2053 INFO "Url: https://en.wikipedia.org/wiki/Rooster_(zodiac)" MSG %(Chinese New Year) (%(Rooster))
|
||||
REM 8 Feb 2054 INFO "Url: https://en.wikipedia.org/wiki/Dog_(zodiac)" MSG %(Chinese New Year) (%(Dog))
|
||||
REM 28 Jan 2055 INFO "Url: https://en.wikipedia.org/wiki/Pig_(zodiac)" MSG %(Chinese New Year) (%(Pig))
|
||||
REM 15 Feb 2056 INFO "Url: https://en.wikipedia.org/wiki/Rat_(zodiac)" MSG %(Chinese New Year) (%(Rat))
|
||||
REM 4 Feb 2057 INFO "Url: https://en.wikipedia.org/wiki/Ox_(zodiac)" MSG %(Chinese New Year) (%(Ox))
|
||||
REM 24 Jan 2058 INFO "Url: https://en.wikipedia.org/wiki/Tiger_(zodiac)" MSG %(Chinese New Year) (%(Tiger))
|
||||
REM 12 Feb 2059 INFO "Url: https://en.wikipedia.org/wiki/Rabbit_(zodiac)" MSG %(Chinese New Year) (%(Rabbit))
|
||||
REM 2 Feb 2060 INFO "Url: https://en.wikipedia.org/wiki/Dragon_(zodiac)" MSG %(Chinese New Year) (%(Dragon))
|
||||
REM 21 Jan 2061 INFO "Url: https://en.wikipedia.org/wiki/Snake_(zodiac)" MSG %(Chinese New Year) (%(Snake))
|
||||
REM 9 Feb 2062 INFO "Url: https://en.wikipedia.org/wiki/Horse_(zodiac)" MSG %(Chinese New Year) (%(Horse))
|
||||
REM 29 Jan 2063 INFO "Url: https://en.wikipedia.org/wiki/Goat_(zodiac)" MSG %(Chinese New Year) (%(Goat))
|
||||
REM 17 Feb 2064 INFO "Url: https://en.wikipedia.org/wiki/Monkey_(zodiac)" MSG %(Chinese New Year) (%(Monkey))
|
||||
REM 5 Feb 2065 INFO "Url: https://en.wikipedia.org/wiki/Rooster_(zodiac)" MSG %(Chinese New Year) (%(Rooster))
|
||||
REM 26 Jan 2066 INFO "Url: https://en.wikipedia.org/wiki/Dog_(zodiac)" MSG %(Chinese New Year) (%(Dog))
|
||||
REM 14 Feb 2067 INFO "Url: https://en.wikipedia.org/wiki/Pig_(zodiac)" MSG %(Chinese New Year) (%(Pig))
|
||||
REM 3 Feb 2068 INFO "Url: https://en.wikipedia.org/wiki/Rat_(zodiac)" MSG %(Chinese New Year) (%(Rat))
|
||||
REM 23 Jan 2069 INFO "Url: https://en.wikipedia.org/wiki/Ox_(zodiac)" MSG %(Chinese New Year) (%(Ox))
|
||||
REM 11 Feb 2070 INFO "Url: https://en.wikipedia.org/wiki/Tiger_(zodiac)" MSG %(Chinese New Year) (%(Tiger))
|
||||
REM 31 Jan 2071 INFO "Url: https://en.wikipedia.org/wiki/Rabbit_(zodiac)" MSG %(Chinese New Year) (%(Rabbit))
|
||||
REM 19 Feb 2072 INFO "Url: https://en.wikipedia.org/wiki/Dragon_(zodiac)" MSG %(Chinese New Year) (%(Dragon))
|
||||
REM 7 Feb 2073 INFO "Url: https://en.wikipedia.org/wiki/Snake_(zodiac)" MSG %(Chinese New Year) (%(Snake))
|
||||
REM 27 Jan 2074 INFO "Url: https://en.wikipedia.org/wiki/Horse_(zodiac)" MSG %(Chinese New Year) (%(Horse))
|
||||
REM 15 Feb 2075 INFO "Url: https://en.wikipedia.org/wiki/Goat_(zodiac)" MSG %(Chinese New Year) (%(Goat))
|
||||
REM 5 Feb 2076 INFO "Url: https://en.wikipedia.org/wiki/Monkey_(zodiac)" MSG %(Chinese New Year) (%(Monkey))
|
||||
REM 24 Jan 2077 INFO "Url: https://en.wikipedia.org/wiki/Rooster_(zodiac)" MSG %(Chinese New Year) (%(Rooster))
|
||||
REM 12 Feb 2078 INFO "Url: https://en.wikipedia.org/wiki/Dog_(zodiac)" MSG %(Chinese New Year) (%(Dog))
|
||||
REM 2 Feb 2079 INFO "Url: https://en.wikipedia.org/wiki/Pig_(zodiac)" MSG %(Chinese New Year) (%(Pig))
|
||||
REM 22 Jan 2080 INFO "Url: https://en.wikipedia.org/wiki/Rat_(zodiac)" MSG %(Chinese New Year) (%(Rat))
|
||||
REM 9 Feb 2081 INFO "Url: https://en.wikipedia.org/wiki/Ox_(zodiac)" MSG %(Chinese New Year) (%(Ox))
|
||||
REM 29 Jan 2082 INFO "Url: https://en.wikipedia.org/wiki/Tiger_(zodiac)" MSG %(Chinese New Year) (%(Tiger))
|
||||
REM 17 Feb 2083 INFO "Url: https://en.wikipedia.org/wiki/Rabbit_(zodiac)" MSG %(Chinese New Year) (%(Rabbit))
|
||||
REM 6 Feb 2084 INFO "Url: https://en.wikipedia.org/wiki/Dragon_(zodiac)" MSG %(Chinese New Year) (%(Dragon))
|
||||
REM 26 Jan 2085 INFO "Url: https://en.wikipedia.org/wiki/Snake_(zodiac)" MSG %(Chinese New Year) (%(Snake))
|
||||
REM 14 Feb 2086 INFO "Url: https://en.wikipedia.org/wiki/Horse_(zodiac)" MSG %(Chinese New Year) (%(Horse))
|
||||
REM 3 Feb 2087 INFO "Url: https://en.wikipedia.org/wiki/Goat_(zodiac)" MSG %(Chinese New Year) (%(Goat))
|
||||
REM 24 Jan 2088 INFO "Url: https://en.wikipedia.org/wiki/Monkey_(zodiac)" MSG %(Chinese New Year) (%(Monkey))
|
||||
REM 10 Feb 2089 INFO "Url: https://en.wikipedia.org/wiki/Rooster_(zodiac)" MSG %(Chinese New Year) (%(Rooster))
|
||||
REM 30 Jan 2090 INFO "Url: https://en.wikipedia.org/wiki/Dog_(zodiac)" MSG %(Chinese New Year) (%(Dog))
|
||||
REM 18 Feb 2091 INFO "Url: https://en.wikipedia.org/wiki/Pig_(zodiac)" MSG %(Chinese New Year) (%(Pig))
|
||||
REM 7 Feb 2092 INFO "Url: https://en.wikipedia.org/wiki/Rat_(zodiac)" MSG %(Chinese New Year) (%(Rat))
|
||||
REM 27 Jan 2093 INFO "Url: https://en.wikipedia.org/wiki/Ox_(zodiac)" MSG %(Chinese New Year) (%(Ox))
|
||||
REM 15 Feb 2094 INFO "Url: https://en.wikipedia.org/wiki/Tiger_(zodiac)" MSG %(Chinese New Year) (%(Tiger))
|
||||
REM 5 Feb 2095 INFO "Url: https://en.wikipedia.org/wiki/Rabbit_(zodiac)" MSG %(Chinese New Year) (%(Rabbit))
|
||||
REM 25 Jan 2096 INFO "Url: https://en.wikipedia.org/wiki/Dragon_(zodiac)" MSG %(Chinese New Year) (%(Dragon))
|
||||
REM 12 Feb 2097 INFO "Url: https://en.wikipedia.org/wiki/Snake_(zodiac)" MSG %(Chinese New Year) (%(Snake))
|
||||
REM 1 Feb 2098 INFO "Url: https://en.wikipedia.org/wiki/Horse_(zodiac)" MSG %(Chinese New Year) (%(Horse))
|
||||
REM 21 Jan 2099 INFO "Url: https://en.wikipedia.org/wiki/Goat_(zodiac)" MSG %(Chinese New Year) (%(Goat))
|
||||
REM 9 Feb 2100 INFO "Url: https://en.wikipedia.org/wiki/Monkey_(zodiac)" MSG %(Chinese New Year) (%(Monkey))
|
||||
|
||||
@@ -26,7 +26,7 @@ REM 29 June ADDOMIT SCANFROM -28 SATISFY [$Tw != 2 && $Tw != 3 && $Tw != 4 && $T
|
||||
REM 2 July ADDOMIT SCANFROM -28 SATISFY [wkdaynum(date($Ty, 6, 29)) == 5] MSG San Pedro y San Pablo
|
||||
OMIT 16 July MSG Virgen del Carmen
|
||||
OMIT 15 August MSG Asunción de la Virgen
|
||||
REM 17 September ADDOMIT SCANFROM -28 SATISFY [$Tw == 1 || $Tw == 5] MSG Fiestas Patrias
|
||||
REM 17 September ADDOMIT SCANFROM -28 SATISFY [isany($Tw, 1, 5)] MSG Fiestas Patrias
|
||||
OMIT 18 September MSG Día de la Independencia
|
||||
OMIT 19 September MSG Día de las Glorias del Ejército
|
||||
REM 20 September ADDOMIT SCANFROM -28 SATISFY [$Tw == 5] MSG Fiestas Patrias
|
||||
|
||||
@@ -6,16 +6,16 @@
|
||||
# See important caveats in the README file in this directory.
|
||||
|
||||
OMIT 1 January MSG New Year's Day
|
||||
REM 1 January OMIT SAT SUN AFTER ADDOMIT SCANFROM -28 SATISFY [wkdaynum(date($Ty, 1, 1))==0 || wkdaynum(date($Ty, 1, 1))==6] MSG New Year's Day (observed)
|
||||
REM 1 January OMIT SAT SUN AFTER ADDOMIT SCANFROM -28 SATISFY [isany(wkdaynum(date($Ty, 1, 1)), 0, 6)] MSG New Year's Day (observed)
|
||||
OMIT 11 February MSG Youth Day
|
||||
REM 11 February OMIT SAT SUN AFTER ADDOMIT SCANFROM -28 SATISFY [wkdaynum(date($Ty, 2, 11))==0 || wkdaynum(date($Ty, 2, 11))==6] MSG Youth Day (observed)
|
||||
REM 11 February OMIT SAT SUN AFTER ADDOMIT SCANFROM -28 SATISFY [isany(wkdaynum(date($Ty, 2, 11)), 0, 6)] MSG Youth Day (observed)
|
||||
OMIT [easterdate($Uy)-2] MSG Good Friday
|
||||
OMIT 1 May MSG Labour Day
|
||||
REM 1 May OMIT SAT SUN AFTER ADDOMIT SCANFROM -28 SATISFY [wkdaynum(date($Ty, 5, 1))==0 || wkdaynum(date($Ty, 5, 1))==6] MSG Labour Day (observed)
|
||||
REM 1 May OMIT SAT SUN AFTER ADDOMIT SCANFROM -28 SATISFY [isany(wkdaynum(date($Ty, 5, 1)), 0, 6)] MSG Labour Day (observed)
|
||||
OMIT 20 May MSG National Day
|
||||
REM 20 May OMIT SAT SUN AFTER ADDOMIT SCANFROM -28 SATISFY [wkdaynum(date($Ty, 5, 20))==0 || wkdaynum(date($Ty, 5, 20))==6] MSG National Day (observed)
|
||||
REM 20 May OMIT SAT SUN AFTER ADDOMIT SCANFROM -28 SATISFY [isany(wkdaynum(date($Ty, 5, 20)), 0, 6)] MSG National Day (observed)
|
||||
OMIT [easterdate($Uy)+39] MSG Ascension Day
|
||||
OMIT 15 August MSG Assumption Day
|
||||
REM 15 August OMIT SAT SUN AFTER ADDOMIT SCANFROM -28 SATISFY [wkdaynum(date($Ty, 8, 15))==0 || wkdaynum(date($Ty, 8, 15))==6] MSG Assumption Day (observed)
|
||||
REM 15 August OMIT SAT SUN AFTER ADDOMIT SCANFROM -28 SATISFY [isany(wkdaynum(date($Ty, 8, 15)), 0, 6)] MSG Assumption Day (observed)
|
||||
OMIT 25 December MSG Christmas Day
|
||||
REM 25 December OMIT SAT SUN AFTER ADDOMIT SCANFROM -28 SATISFY [wkdaynum(date($Ty, 12, 25))==0 || wkdaynum(date($Ty, 12, 25))==6] MSG Christmas Day (observed)
|
||||
REM 25 December OMIT SAT SUN AFTER ADDOMIT SCANFROM -28 SATISFY [isany(wkdaynum(date($Ty, 12, 25)), 0, 6)] MSG Christmas Day (observed)
|
||||
|
||||
@@ -17,7 +17,7 @@ REM [orthodoxeaster($Uy)+1] MSG ΔΕΥΤΕΡΑ ΤΟΥ ΠΑΣΧΑ
|
||||
# minister decides moving that holiday. Here is a likely assumption of how this day might be moved.
|
||||
# Uncomment following lines to enable.
|
||||
|
||||
set PM date($Uy,5,1)
|
||||
# set PM date($Uy,5,1)
|
||||
# IF PM>=orthodoxeaster($Uy)-7 && PM<=orthodoxeaster($Uy)+1
|
||||
# IF PM<orthodoxeaster($Uy)-3
|
||||
# REM orthodoxeaster($Uy) -8 MSG πιθανόν ΕΡΓΑΤΙΚΗ Πρωτομαγιά
|
||||
|
||||
@@ -6,18 +6,18 @@
|
||||
# See important caveats in the README file in this directory.
|
||||
|
||||
OMIT 1 January MSG The first day of January
|
||||
REM 1 January OMIT SAT SUN AFTER ADDOMIT SCANFROM -28 SATISFY [wkdaynum(date($Ty, 1, 1))==0 || wkdaynum(date($Ty, 1, 1))==6] MSG The first day of January (observed)
|
||||
REM 4 April OMIT SAT SUN AFTER ADDOMIT SCANFROM -28 SATISFY [wkdaynum(date($Ty, 4, 4))==0 || wkdaynum(date($Ty, 4, 4))==6] MSG Ching Ming Festival (observed)
|
||||
REM 1 January OMIT SAT SUN AFTER ADDOMIT SCANFROM -28 SATISFY [isany(wkdaynum(date($Ty, 1, 1)), 0, 6)] MSG The first day of January (observed)
|
||||
REM 4 April OMIT SAT SUN AFTER ADDOMIT SCANFROM -28 SATISFY [isany(wkdaynum(date($Ty, 4, 4)), 0, 6)] MSG Ching Ming Festival (observed)
|
||||
OMIT 1 May MSG Labour Day
|
||||
REM 1 May OMIT SAT SUN AFTER ADDOMIT SCANFROM -28 SATISFY [wkdaynum(date($Ty, 5, 1))==0 || wkdaynum(date($Ty, 5, 1))==6] MSG Labour Day (observed)
|
||||
REM 1 May OMIT SAT SUN AFTER ADDOMIT SCANFROM -28 SATISFY [isany(wkdaynum(date($Ty, 5, 1)), 0, 6)] MSG Labour Day (observed)
|
||||
OMIT 1 July MSG Hong Kong Special Administrative Region Establishment Day
|
||||
REM 1 July OMIT SAT SUN AFTER ADDOMIT SCANFROM -28 SATISFY [wkdaynum(date($Ty, 7, 1))==0 || wkdaynum(date($Ty, 7, 1))==6] MSG Hong Kong Special Administrative Region Establishment Day (observed)
|
||||
REM 1 July OMIT SAT SUN AFTER ADDOMIT SCANFROM -28 SATISFY [isany(wkdaynum(date($Ty, 7, 1)), 0, 6)] MSG Hong Kong Special Administrative Region Establishment Day (observed)
|
||||
OMIT 1 October MSG National Day
|
||||
REM 1 October OMIT SAT SUN AFTER ADDOMIT SCANFROM -28 SATISFY [wkdaynum(date($Ty, 10, 1))==0 || wkdaynum(date($Ty, 10, 1))==6] MSG National Day (observed)
|
||||
REM 1 October OMIT SAT SUN AFTER ADDOMIT SCANFROM -28 SATISFY [isany(wkdaynum(date($Ty, 10, 1)), 0, 6)] MSG National Day (observed)
|
||||
OMIT 25 December MSG Christmas Day
|
||||
REM 25 December OMIT SAT SUN AFTER ADDOMIT SCANFROM -28 SATISFY [wkdaynum(date($Ty, 12, 25))==0 || wkdaynum(date($Ty, 12, 25))==6] MSG Christmas Day (observed)
|
||||
REM 25 December OMIT SAT SUN AFTER ADDOMIT SCANFROM -28 SATISFY [isany(wkdaynum(date($Ty, 12, 25)), 0, 6)] MSG Christmas Day (observed)
|
||||
OMIT 26 December MSG The first weekday after Christmas Day
|
||||
REM 26 December OMIT SAT SUN AFTER ADDOMIT SCANFROM -28 SATISFY [wkdaynum(date($Ty, 12, 26))==0 || wkdaynum(date($Ty, 12, 26))==6] MSG The first weekday after Christmas Day (observed)
|
||||
REM 26 December OMIT SAT SUN AFTER ADDOMIT SCANFROM -28 SATISFY [isany(wkdaynum(date($Ty, 12, 26)), 0, 6)] MSG The first weekday after Christmas Day (observed)
|
||||
|
||||
# Optional holidays
|
||||
REM [easterdate($Uy)-2] MSG Good Friday
|
||||
|
||||
@@ -6,7 +6,7 @@
|
||||
# See important caveats in the README file in this directory.
|
||||
|
||||
OMIT 1 January MSG New Year's Day
|
||||
REM 1 January OMIT SAT SUN AFTER ADDOMIT SCANFROM -28 SATISFY [wkdaynum(date($Ty, 1, 1))==0 || wkdaynum(date($Ty, 1, 1))==6] MSG New Year's Day (substitute day)
|
||||
REM 1 January OMIT SAT SUN AFTER ADDOMIT SCANFROM -28 SATISFY [isany(wkdaynum(date($Ty, 1, 1)), 0, 6)] MSG New Year's Day (substitute day)
|
||||
OMIT [easterdate($Uy)-2] MSG Good Friday
|
||||
OMIT [easterdate($Uy)+1] MSG Easter Monday
|
||||
REM First Monday in May ADDOMIT SCANFROM -28 MSG May Bank Holiday
|
||||
@@ -14,6 +14,6 @@ REM 9 May ADDOMIT SCANFROM -28 SATISFY [$Tw != 0] MSG Liberation Day
|
||||
REM Last Monday in May ADDOMIT SCANFROM -28 MSG Spring Bank Holiday
|
||||
REM Last Monday in August ADDOMIT SCANFROM -28 MSG Summer Bank Holiday
|
||||
OMIT 25 December MSG Christmas Day
|
||||
REM 25 December OMIT SAT SUN AFTER ADDOMIT SCANFROM -28 SATISFY [wkdaynum(date($Ty, 12, 25))==0 || wkdaynum(date($Ty, 12, 25))==6] MSG Christmas Day (substitute day)
|
||||
REM 25 December OMIT SAT SUN AFTER ADDOMIT SCANFROM -28 SATISFY [isany(wkdaynum(date($Ty, 12, 25)), 0, 6)] MSG Christmas Day (substitute day)
|
||||
OMIT 26 December MSG Boxing Day
|
||||
REM 26 December OMIT SAT SUN AFTER ADDOMIT SCANFROM -28 SATISFY [wkdaynum(date($Ty, 12, 26))==0 || wkdaynum(date($Ty, 12, 26))==6] MSG Boxing Day (substitute day)
|
||||
REM 26 December OMIT SAT SUN AFTER ADDOMIT SCANFROM -28 SATISFY [isany(wkdaynum(date($Ty, 12, 26)), 0, 6)] MSG Boxing Day (substitute day)
|
||||
|
||||
@@ -14,9 +14,6 @@ FSET _h2(x, y) HEBDATE(x, y, $U-7)
|
||||
FSET _PastSat(x, y) IIF(WKDAYNUM(_h2(x,y))!=6, _h2(x,y), _h2(x,y)+1)
|
||||
FSET _BackTwoFri(x, y) IIF(WKDAYNUM(_h2(x,y))!=5, _h2(x,y), _h2(x,y)-2)
|
||||
FSET _BackTwoSat(x, y) IIF(WKDAYNUM(_h2(x,y))!=6, _h2(x,y), _h2(x,y)-2)
|
||||
# Default values in case InIsrael and Reform are not set
|
||||
SET InIsrael VALUE("InIsrael", 0)
|
||||
SET Reform VALUE("Reform", 0)
|
||||
|
||||
REM [hebdate(1, "Tishrey")] INFO "Url: https://en.wikipedia.org/wiki/Rosh_Hashanah" MSG Rosh Hashana 1
|
||||
|
||||
|
||||
@@ -6,29 +6,29 @@
|
||||
# See important caveats in the README file in this directory.
|
||||
|
||||
OMIT 1 January MSG Жаңа жыл
|
||||
REM 1 January OMIT SAT SUN AFTER ADDOMIT SCANFROM -28 SATISFY [wkdaynum(date($Ty, 1, 1))==0 || wkdaynum(date($Ty, 1, 1))==6] MSG Жаңа жыл (қайта белгіленген демалыс)
|
||||
REM 1 January OMIT SAT SUN AFTER ADDOMIT SCANFROM -28 SATISFY [isany(wkdaynum(date($Ty, 1, 1)), 0, 6)] MSG Жаңа жыл (қайта белгіленген демалыс)
|
||||
OMIT 2 January MSG Жаңа жыл
|
||||
REM 2 January OMIT SAT SUN AFTER ADDOMIT SCANFROM -28 SATISFY [wkdaynum(date($Ty, 1, 2))==0 || wkdaynum(date($Ty, 1, 2))==6] MSG Жаңа жыл (қайта белгіленген демалыс)
|
||||
REM 2 January OMIT SAT SUN AFTER ADDOMIT SCANFROM -28 SATISFY [isany(wkdaynum(date($Ty, 1, 2)), 0, 6)] MSG Жаңа жыл (қайта белгіленген демалыс)
|
||||
OMIT 7 January MSG Православиелік Рождество
|
||||
OMIT 8 March MSG Халықаралық әйелдер күні
|
||||
REM 8 March OMIT SAT SUN AFTER ADDOMIT SCANFROM -28 SATISFY [wkdaynum(date($Ty, 3, 8))==0 || wkdaynum(date($Ty, 3, 8))==6] MSG Халықаралық әйелдер күні (қайта белгіленген демалыс)
|
||||
REM 8 March OMIT SAT SUN AFTER ADDOMIT SCANFROM -28 SATISFY [isany(wkdaynum(date($Ty, 3, 8)), 0, 6)] MSG Халықаралық әйелдер күні (қайта белгіленген демалыс)
|
||||
OMIT 21 March MSG Наурыз мейрамы
|
||||
REM 21 March OMIT SAT SUN AFTER ADDOMIT SCANFROM -28 SATISFY [wkdaynum(date($Ty, 3, 21))==0 || wkdaynum(date($Ty, 3, 21))==6] MSG Наурыз мейрамы (қайта белгіленген демалыс)
|
||||
REM 21 March OMIT SAT SUN AFTER ADDOMIT SCANFROM -28 SATISFY [isany(wkdaynum(date($Ty, 3, 21)), 0, 6)] MSG Наурыз мейрамы (қайта белгіленген демалыс)
|
||||
OMIT 22 March MSG Наурыз мейрамы
|
||||
REM 22 March OMIT SAT SUN AFTER ADDOMIT SCANFROM -28 SATISFY [wkdaynum(date($Ty, 3, 22))==0 || wkdaynum(date($Ty, 3, 22))==6] MSG Наурыз мейрамы (қайта белгіленген демалыс)
|
||||
REM 22 March OMIT SAT SUN AFTER ADDOMIT SCANFROM -28 SATISFY [isany(wkdaynum(date($Ty, 3, 22)), 0, 6)] MSG Наурыз мейрамы (қайта белгіленген демалыс)
|
||||
OMIT 23 March MSG Наурыз мейрамы
|
||||
REM 23 March OMIT SAT SUN AFTER ADDOMIT SCANFROM -28 SATISFY [wkdaynum(date($Ty, 3, 23))==0 || wkdaynum(date($Ty, 3, 23))==6] MSG Наурыз мейрамы (қайта белгіленген демалыс)
|
||||
REM 23 March OMIT SAT SUN AFTER ADDOMIT SCANFROM -28 SATISFY [isany(wkdaynum(date($Ty, 3, 23)), 0, 6)] MSG Наурыз мейрамы (қайта белгіленген демалыс)
|
||||
OMIT 1 May MSG Қазақстан халқының бірлігі мерекесі
|
||||
REM 1 May OMIT SAT SUN AFTER ADDOMIT SCANFROM -28 SATISFY [wkdaynum(date($Ty, 5, 1))==0 || wkdaynum(date($Ty, 5, 1))==6] MSG Қазақстан халқының бірлігі мерекесі (қайта белгіленген демалыс)
|
||||
REM 1 May OMIT SAT SUN AFTER ADDOMIT SCANFROM -28 SATISFY [isany(wkdaynum(date($Ty, 5, 1)), 0, 6)] MSG Қазақстан халқының бірлігі мерекесі (қайта белгіленген демалыс)
|
||||
OMIT 7 May MSG Отан Қорғаушы күні
|
||||
REM 7 May OMIT SAT SUN AFTER ADDOMIT SCANFROM -28 SATISFY [wkdaynum(date($Ty, 5, 7))==0 || wkdaynum(date($Ty, 5, 7))==6] MSG Отан Қорғаушы күні (қайта белгіленген демалыс)
|
||||
REM 7 May OMIT SAT SUN AFTER ADDOMIT SCANFROM -28 SATISFY [isany(wkdaynum(date($Ty, 5, 7)), 0, 6)] MSG Отан Қорғаушы күні (қайта белгіленген демалыс)
|
||||
OMIT 9 May MSG Жеңіс күні
|
||||
REM 9 May OMIT SAT SUN AFTER ADDOMIT SCANFROM -28 SATISFY [wkdaynum(date($Ty, 5, 9))==0 || wkdaynum(date($Ty, 5, 9))==6] MSG Жеңіс күні (қайта белгіленген демалыс)
|
||||
REM 9 May OMIT SAT SUN AFTER ADDOMIT SCANFROM -28 SATISFY [isany(wkdaynum(date($Ty, 5, 9)), 0, 6)] MSG Жеңіс күні (қайта белгіленген демалыс)
|
||||
OMIT 6 July MSG Астана күні
|
||||
REM 6 July OMIT SAT SUN AFTER ADDOMIT SCANFROM -28 SATISFY [wkdaynum(date($Ty, 7, 6))==0 || wkdaynum(date($Ty, 7, 6))==6] MSG Астана күні (қайта белгіленген демалыс)
|
||||
REM 6 July OMIT SAT SUN AFTER ADDOMIT SCANFROM -28 SATISFY [isany(wkdaynum(date($Ty, 7, 6)), 0, 6)] MSG Астана күні (қайта белгіленген демалыс)
|
||||
OMIT 30 August MSG Қазақстан Республикасының Конституциясы күні
|
||||
REM 30 August OMIT SAT SUN AFTER ADDOMIT SCANFROM -28 SATISFY [wkdaynum(date($Ty, 8, 30))==0 || wkdaynum(date($Ty, 8, 30))==6] MSG Қазақстан Республикасының Конституциясы күні (қайта белгіленген демалыс)
|
||||
REM 30 August OMIT SAT SUN AFTER ADDOMIT SCANFROM -28 SATISFY [isany(wkdaynum(date($Ty, 8, 30)), 0, 6)] MSG Қазақстан Республикасының Конституциясы күні (қайта белгіленген демалыс)
|
||||
OMIT 25 October MSG Республика күні
|
||||
REM 25 October OMIT SAT SUN AFTER ADDOMIT SCANFROM -28 SATISFY [wkdaynum(date($Ty, 10, 25))==0 || wkdaynum(date($Ty, 10, 25))==6] MSG Республика күні (қайта белгіленген демалыс)
|
||||
REM 25 October OMIT SAT SUN AFTER ADDOMIT SCANFROM -28 SATISFY [isany(wkdaynum(date($Ty, 10, 25)), 0, 6)] MSG Республика күні (қайта белгіленген демалыс)
|
||||
OMIT 16 December MSG Тəуелсіздік күні
|
||||
REM 16 December OMIT SAT SUN AFTER ADDOMIT SCANFROM -28 SATISFY [wkdaynum(date($Ty, 12, 16))==0 || wkdaynum(date($Ty, 12, 16))==6] MSG Тəуелсіздік күні (қайта белгіленген демалыс)
|
||||
REM 16 December OMIT SAT SUN AFTER ADDOMIT SCANFROM -28 SATISFY [isany(wkdaynum(date($Ty, 12, 16)), 0, 6)] MSG Тəуелсіздік күні (қайта белгіленген демалыс)
|
||||
|
||||
@@ -6,21 +6,21 @@
|
||||
# See important caveats in the README file in this directory.
|
||||
|
||||
OMIT 1 January MSG ວັນປີໃໝ່ສາກົນ
|
||||
REM 1 January OMIT SAT SUN AFTER ADDOMIT SCANFROM -28 SATISFY [wkdaynum(date($Ty, 1, 1))==0 || wkdaynum(date($Ty, 1, 1))==6] MSG ພັກຊົດເຊີຍວັນປີໃໝ່ສາກົນ
|
||||
REM 1 January OMIT SAT SUN AFTER ADDOMIT SCANFROM -28 SATISFY [isany(wkdaynum(date($Ty, 1, 1)), 0, 6)] MSG ພັກຊົດເຊີຍວັນປີໃໝ່ສາກົນ
|
||||
OMIT 8 March MSG ວັນແມ່ຍິງສາກົນ
|
||||
REM 8 March OMIT SAT SUN AFTER ADDOMIT SCANFROM -28 SATISFY [wkdaynum(date($Ty, 3, 8))==0 || wkdaynum(date($Ty, 3, 8))==6] MSG ພັກຊົດເຊີຍວັນແມ່ຍິງສາກົນ
|
||||
REM 8 March OMIT SAT SUN AFTER ADDOMIT SCANFROM -28 SATISFY [isany(wkdaynum(date($Ty, 3, 8)), 0, 6)] MSG ພັກຊົດເຊີຍວັນແມ່ຍິງສາກົນ
|
||||
OMIT 13 April MSG ບຸນປີໃໝ່ລາວ
|
||||
REM 13 April OMIT SAT SUN AFTER ADDOMIT SCANFROM -28 SATISFY [wkdaynum(date($Ty, 4, 13))==0 || wkdaynum(date($Ty, 4, 13))==6] MSG ພັກຊົດເຊີຍບຸນປີໃໝ່ລາວ
|
||||
REM 13 April OMIT SAT SUN AFTER ADDOMIT SCANFROM -28 SATISFY [isany(wkdaynum(date($Ty, 4, 13)), 0, 6)] MSG ພັກຊົດເຊີຍບຸນປີໃໝ່ລາວ
|
||||
OMIT 14 April MSG ບຸນປີໃໝ່ລາວ
|
||||
REM 14 April OMIT SAT SUN AFTER ADDOMIT SCANFROM -28 SATISFY [wkdaynum(date($Ty, 4, 14))==0 || wkdaynum(date($Ty, 4, 14))==6] MSG ພັກຊົດເຊີຍບຸນປີໃໝ່ລາວ
|
||||
REM 14 April OMIT SAT SUN AFTER ADDOMIT SCANFROM -28 SATISFY [isany(wkdaynum(date($Ty, 4, 14)), 0, 6)] MSG ພັກຊົດເຊີຍບຸນປີໃໝ່ລາວ
|
||||
OMIT 15 April MSG ບຸນປີໃໝ່ລາວ
|
||||
REM 15 April OMIT SAT SUN AFTER ADDOMIT SCANFROM -28 SATISFY [wkdaynum(date($Ty, 4, 15))==0 || wkdaynum(date($Ty, 4, 15))==6] MSG ພັກຊົດເຊີຍບຸນປີໃໝ່ລາວ
|
||||
REM 15 April OMIT SAT SUN AFTER ADDOMIT SCANFROM -28 SATISFY [isany(wkdaynum(date($Ty, 4, 15)), 0, 6)] MSG ພັກຊົດເຊີຍບຸນປີໃໝ່ລາວ
|
||||
OMIT 16 April MSG ບຸນປີໃໝ່ລາວ
|
||||
REM 16 April OMIT SAT SUN AFTER ADDOMIT SCANFROM -28 SATISFY [wkdaynum(date($Ty, 4, 16))==0 || wkdaynum(date($Ty, 4, 16))==6] MSG ພັກຊົດເຊີຍບຸນປີໃໝ່ລາວ
|
||||
REM 16 April OMIT SAT SUN AFTER ADDOMIT SCANFROM -28 SATISFY [isany(wkdaynum(date($Ty, 4, 16)), 0, 6)] MSG ພັກຊົດເຊີຍບຸນປີໃໝ່ລາວ
|
||||
OMIT 1 May MSG ວັນກຳມະກອນສາກົນ
|
||||
REM 1 May OMIT SAT SUN AFTER ADDOMIT SCANFROM -28 SATISFY [wkdaynum(date($Ty, 5, 1))==0 || wkdaynum(date($Ty, 5, 1))==6] MSG ພັກຊົດເຊີຍວັນກຳມະກອນສາກົນ
|
||||
REM 1 May OMIT SAT SUN AFTER ADDOMIT SCANFROM -28 SATISFY [isany(wkdaynum(date($Ty, 5, 1)), 0, 6)] MSG ພັກຊົດເຊີຍວັນກຳມະກອນສາກົນ
|
||||
OMIT 2 December MSG ວັນຊາດ
|
||||
REM 2 December OMIT SAT SUN AFTER ADDOMIT SCANFROM -28 SATISFY [wkdaynum(date($Ty, 12, 2))==0 || wkdaynum(date($Ty, 12, 2))==6] MSG ພັກຊົດເຊີຍວັນຊາດ
|
||||
REM 2 December OMIT SAT SUN AFTER ADDOMIT SCANFROM -28 SATISFY [isany(wkdaynum(date($Ty, 12, 2)), 0, 6)] MSG ພັກຊົດເຊີຍວັນຊາດ
|
||||
|
||||
# Optional holidays
|
||||
REM 20 January MSG ວັນສ້າງຕັ້ງກອງທັບປະຊາຊົນລາວ
|
||||
@@ -37,7 +37,7 @@ REM 15 August MSG ວັນລັດຖະທໍາມະນູນແຫ່ງ
|
||||
REM 23 August MSG ວັນຍຶດອຳນາດທົ່ວປະເທດ
|
||||
REM 7 October MSG ວັນຄູແຫ່ງຊາດ
|
||||
REM 7 October MSG ວັນສ້າງຕັ້ງທະນາຄານແຫ່ງ ສປປ ລາວ
|
||||
REM 7 October OMIT SAT SUN AFTER SCANFROM -28 SATISFY [wkdaynum(date($Ty, 10, 7))==0 || wkdaynum(date($Ty, 10, 7))==6] MSG ພັກຊົດເຊີຍວັນສ້າງຕັ້ງທະນາຄານແຫ່ງ ສປປ ລາວ
|
||||
REM 7 October OMIT SAT SUN AFTER SCANFROM -28 SATISFY [isany(wkdaynum(date($Ty, 10, 7)), 0, 6)] MSG ພັກຊົດເຊີຍວັນສ້າງຕັ້ງທະນາຄານແຫ່ງ ສປປ ລາວ
|
||||
REM 12 October MSG ວັນປະກາດເອກະລາດ
|
||||
REM 13 December MSG ວັນຄ້າຍວັນເກີດ ທ່ານ ປະທານ ໄກສອນ ພົມວິຫານ
|
||||
REM 27 December SCANFROM -28 SATISFY [$Tw >= 3 && $Tw <= 5] MSG ສາມວັນລັດຖະການສຸດທ້າຍຂອງທຸກໆປີ
|
||||
|
||||
@@ -13,11 +13,11 @@
|
||||
# [$SysInclude]/holidays/my/
|
||||
|
||||
OMIT 1 May MSG Hari Pekerja
|
||||
REM 1 May OMIT SAT SUN AFTER ADDOMIT SCANFROM -28 SATISFY [wkdaynum(date($Ty, 5, 1))==0 || wkdaynum(date($Ty, 5, 1))==6] MSG Cuti Hari Pekerja
|
||||
REM 1 May OMIT SAT SUN AFTER ADDOMIT SCANFROM -28 SATISFY [isany(wkdaynum(date($Ty, 5, 1)), 0, 6)] MSG Cuti Hari Pekerja
|
||||
REM First Monday in June ADDOMIT SCANFROM -28 MSG Hari Keputeraan Rasmi Seri Paduka Baginda Yang di-Pertuan Agong
|
||||
REM 3 June OMIT SAT SUN AFTER ADDOMIT SCANFROM -28 SATISFY [wkdaynum(date($Ty, 6, 3))==0 || wkdaynum(date($Ty, 6, 3))==6] MSG Cuti Hari Keputeraan Rasmi Seri Paduka Baginda Yang di-Pertuan Agong
|
||||
REM 3 June OMIT SAT SUN AFTER ADDOMIT SCANFROM -28 SATISFY [isany(wkdaynum(date($Ty, 6, 3)), 0, 6)] MSG Cuti Hari Keputeraan Rasmi Seri Paduka Baginda Yang di-Pertuan Agong
|
||||
OMIT 31 August MSG Hari Kebangsaan
|
||||
REM 31 August OMIT SAT SUN AFTER ADDOMIT SCANFROM -28 SATISFY [wkdaynum(date($Ty, 8, 31))==0 || wkdaynum(date($Ty, 8, 31))==6] MSG Cuti Hari Kebangsaan
|
||||
REM 31 August OMIT SAT SUN AFTER ADDOMIT SCANFROM -28 SATISFY [isany(wkdaynum(date($Ty, 8, 31)), 0, 6)] MSG Cuti Hari Kebangsaan
|
||||
OMIT 16 September MSG Hari Malaysia
|
||||
OMIT 25 December MSG Hari Krismas
|
||||
REM 25 December OMIT SAT SUN AFTER ADDOMIT SCANFROM -28 SATISFY [wkdaynum(date($Ty, 12, 25))==0 || wkdaynum(date($Ty, 12, 25))==6] MSG Cuti Hari Krismas
|
||||
REM 25 December OMIT SAT SUN AFTER ADDOMIT SCANFROM -28 SATISFY [isany(wkdaynum(date($Ty, 12, 25)), 0, 6)] MSG Cuti Hari Krismas
|
||||
|
||||
@@ -11,8 +11,8 @@
|
||||
# also SYSINCLUDE holidays/my.rem
|
||||
|
||||
OMIT 1 January MSG Tahun Baharu
|
||||
REM 1 January OMIT SAT SUN AFTER ADDOMIT SCANFROM -28 SATISFY [wkdaynum(date($Ty, 1, 1))==0 || wkdaynum(date($Ty, 1, 1))==6] MSG Cuti Tahun Baharu
|
||||
REM 1 January OMIT SAT SUN AFTER ADDOMIT SCANFROM -28 SATISFY [isany(wkdaynum(date($Ty, 1, 1)), 0, 6)] MSG Cuti Tahun Baharu
|
||||
OMIT 20 February MSG Hari Pengisytiharan Tarikh Kemerdekaan
|
||||
REM 20 February OMIT SAT SUN AFTER ADDOMIT SCANFROM -28 SATISFY [wkdaynum(date($Ty, 2, 20))==0 || wkdaynum(date($Ty, 2, 20))==6] MSG Cuti Hari Pengisytiharan Tarikh Kemerdekaan
|
||||
REM 20 February OMIT SAT SUN AFTER ADDOMIT SCANFROM -28 SATISFY [isany(wkdaynum(date($Ty, 2, 20)), 0, 6)] MSG Cuti Hari Pengisytiharan Tarikh Kemerdekaan
|
||||
OMIT 24 August MSG Hari Jadi Yang di-Pertua Negeri Melaka
|
||||
REM 24 August OMIT SAT SUN AFTER ADDOMIT SCANFROM -28 SATISFY [wkdaynum(date($Ty, 8, 24))==0 || wkdaynum(date($Ty, 8, 24))==6] MSG Cuti Hari Jadi Yang di-Pertua Negeri Melaka
|
||||
REM 24 August OMIT SAT SUN AFTER ADDOMIT SCANFROM -28 SATISFY [isany(wkdaynum(date($Ty, 8, 24)), 0, 6)] MSG Cuti Hari Jadi Yang di-Pertua Negeri Melaka
|
||||
|
||||
@@ -11,6 +11,6 @@
|
||||
# also SYSINCLUDE holidays/my.rem
|
||||
|
||||
OMIT 1 January MSG Tahun Baharu
|
||||
REM 1 January OMIT SAT SUN AFTER ADDOMIT SCANFROM -28 SATISFY [wkdaynum(date($Ty, 1, 1))==0 || wkdaynum(date($Ty, 1, 1))==6] MSG Cuti Tahun Baharu
|
||||
REM 1 January OMIT SAT SUN AFTER ADDOMIT SCANFROM -28 SATISFY [isany(wkdaynum(date($Ty, 1, 1)), 0, 6)] MSG Cuti Tahun Baharu
|
||||
OMIT 14 January MSG Hari Keputeraan Yang di-Pertuan Besar Negeri Sembilan
|
||||
REM 14 January OMIT SAT SUN AFTER ADDOMIT SCANFROM -28 SATISFY [wkdaynum(date($Ty, 1, 14))==0 || wkdaynum(date($Ty, 1, 14))==6] MSG Cuti Hari Keputeraan Yang di-Pertuan Besar Negeri Sembilan
|
||||
REM 14 January OMIT SAT SUN AFTER ADDOMIT SCANFROM -28 SATISFY [isany(wkdaynum(date($Ty, 1, 14)), 0, 6)] MSG Cuti Hari Keputeraan Yang di-Pertuan Besar Negeri Sembilan
|
||||
|
||||
@@ -11,7 +11,7 @@
|
||||
# also SYSINCLUDE holidays/my.rem
|
||||
|
||||
OMIT 1 January MSG Tahun Baharu
|
||||
REM 1 January OMIT SAT SUN AFTER ADDOMIT SCANFROM -28 SATISFY [wkdaynum(date($Ty, 1, 1))==0 || wkdaynum(date($Ty, 1, 1))==6] MSG Cuti Tahun Baharu
|
||||
REM 1 January OMIT SAT SUN AFTER ADDOMIT SCANFROM -28 SATISFY [isany(wkdaynum(date($Ty, 1, 1)), 0, 6)] MSG Cuti Tahun Baharu
|
||||
OMIT 22 May MSG Hari Hol Sultan Pahang
|
||||
OMIT 30 July MSG Hari Keputeraan Sultan Pahang
|
||||
REM 30 July OMIT SAT SUN AFTER ADDOMIT SCANFROM -28 SATISFY [wkdaynum(date($Ty, 7, 30))==0 || wkdaynum(date($Ty, 7, 30))==6] MSG Cuti Hari Keputeraan Sultan Pahang
|
||||
REM 30 July OMIT SAT SUN AFTER ADDOMIT SCANFROM -28 SATISFY [isany(wkdaynum(date($Ty, 7, 30)), 0, 6)] MSG Cuti Hari Keputeraan Sultan Pahang
|
||||
|
||||
@@ -11,7 +11,7 @@
|
||||
# also SYSINCLUDE holidays/my.rem
|
||||
|
||||
OMIT 1 January MSG Tahun Baharu
|
||||
REM 1 January OMIT SAT SUN AFTER ADDOMIT SCANFROM -28 SATISFY [wkdaynum(date($Ty, 1, 1))==0 || wkdaynum(date($Ty, 1, 1))==6] MSG Cuti Tahun Baharu
|
||||
REM 1 January OMIT SAT SUN AFTER ADDOMIT SCANFROM -28 SATISFY [isany(wkdaynum(date($Ty, 1, 1)), 0, 6)] MSG Cuti Tahun Baharu
|
||||
OMIT 7 July MSG Hari Ulang Tahun Perisytiharan Tapak Warisan Dunia
|
||||
REM Second Saturday in July ADDOMIT SCANFROM -28 MSG Hari Jadi Yang di-Pertua Negeri Pulau Pinang
|
||||
REM 13 July OMIT SAT SUN AFTER ADDOMIT SCANFROM -28 SATISFY [wkdaynum(date($Ty, 7, 13))==0 || wkdaynum(date($Ty, 7, 13))==6] MSG Cuti Hari Jadi Yang di-Pertua Negeri Pulau Pinang
|
||||
REM 13 July OMIT SAT SUN AFTER ADDOMIT SCANFROM -28 SATISFY [isany(wkdaynum(date($Ty, 7, 13)), 0, 6)] MSG Cuti Hari Jadi Yang di-Pertua Negeri Pulau Pinang
|
||||
|
||||
@@ -11,5 +11,5 @@
|
||||
# also SYSINCLUDE holidays/my.rem
|
||||
|
||||
OMIT 1 January MSG Tahun Baharu
|
||||
REM 1 January OMIT SAT SUN AFTER ADDOMIT SCANFROM -28 SATISFY [wkdaynum(date($Ty, 1, 1))==0 || wkdaynum(date($Ty, 1, 1))==6] MSG Cuti Tahun Baharu
|
||||
REM 1 January OMIT SAT SUN AFTER ADDOMIT SCANFROM -28 SATISFY [isany(wkdaynum(date($Ty, 1, 1)), 0, 6)] MSG Cuti Tahun Baharu
|
||||
REM First Friday in November ADDOMIT SCANFROM -28 MSG Hari Keputeraan Sultan Perak
|
||||
|
||||
@@ -11,4 +11,4 @@
|
||||
# also SYSINCLUDE holidays/my.rem
|
||||
|
||||
OMIT 17 May MSG Hari Ulang Tahun Keputeraan Raja Perlis
|
||||
REM 17 May OMIT SAT SUN AFTER ADDOMIT SCANFROM -28 SATISFY [wkdaynum(date($Ty, 5, 17))==0 || wkdaynum(date($Ty, 5, 17))==6] MSG Cuti Hari Ulang Tahun Keputeraan Raja Perlis
|
||||
REM 17 May OMIT SAT SUN AFTER ADDOMIT SCANFROM -28 SATISFY [isany(wkdaynum(date($Ty, 5, 17)), 0, 6)] MSG Cuti Hari Ulang Tahun Keputeraan Raja Perlis
|
||||
|
||||
@@ -11,6 +11,6 @@
|
||||
# also SYSINCLUDE holidays/my.rem
|
||||
|
||||
OMIT 1 January MSG Tahun Baharu
|
||||
REM 1 January OMIT SAT SUN AFTER ADDOMIT SCANFROM -28 SATISFY [wkdaynum(date($Ty, 1, 1))==0 || wkdaynum(date($Ty, 1, 1))==6] MSG Cuti Tahun Baharu
|
||||
REM 1 January OMIT SAT SUN AFTER ADDOMIT SCANFROM -28 SATISFY [isany(wkdaynum(date($Ty, 1, 1)), 0, 6)] MSG Cuti Tahun Baharu
|
||||
OMIT 11 December MSG Hari Keputeraan Sultan Selangor
|
||||
REM 11 December OMIT SAT SUN AFTER ADDOMIT SCANFROM -28 SATISFY [wkdaynum(date($Ty, 12, 11))==0 || wkdaynum(date($Ty, 12, 11))==6] MSG Cuti Hari Keputeraan Sultan Selangor
|
||||
REM 11 December OMIT SAT SUN AFTER ADDOMIT SCANFROM -28 SATISFY [isany(wkdaynum(date($Ty, 12, 11)), 0, 6)] MSG Cuti Hari Keputeraan Sultan Selangor
|
||||
|
||||
@@ -11,6 +11,6 @@
|
||||
# also SYSINCLUDE holidays/my.rem
|
||||
|
||||
OMIT 4 March MSG Hari Ulang Tahun Pertabalan Sultan Terengganu
|
||||
REM 4 March OMIT SAT SUN AFTER ADDOMIT SCANFROM -28 SATISFY [wkdaynum(date($Ty, 3, 4))==0 || wkdaynum(date($Ty, 3, 4))==6] MSG Cuti Hari Ulang Tahun Pertabalan Sultan Terengganu
|
||||
REM 4 March OMIT SAT SUN AFTER ADDOMIT SCANFROM -28 SATISFY [isany(wkdaynum(date($Ty, 3, 4)), 0, 6)] MSG Cuti Hari Ulang Tahun Pertabalan Sultan Terengganu
|
||||
OMIT 26 April MSG Hari Keputeraan Sultan Terengganu
|
||||
REM 26 April OMIT SAT SUN AFTER ADDOMIT SCANFROM -28 SATISFY [wkdaynum(date($Ty, 4, 26))==0 || wkdaynum(date($Ty, 4, 26))==6] MSG Cuti Hari Keputeraan Sultan Terengganu
|
||||
REM 26 April OMIT SAT SUN AFTER ADDOMIT SCANFROM -28 SATISFY [isany(wkdaynum(date($Ty, 4, 26)), 0, 6)] MSG Cuti Hari Keputeraan Sultan Terengganu
|
||||
|
||||
@@ -11,7 +11,7 @@
|
||||
# also SYSINCLUDE holidays/my.rem
|
||||
|
||||
OMIT 1 January MSG Tahun Baharu
|
||||
REM 1 January OMIT SAT SUN AFTER ADDOMIT SCANFROM -28 SATISFY [wkdaynum(date($Ty, 1, 1))==0 || wkdaynum(date($Ty, 1, 1))==6] MSG Cuti Tahun Baharu
|
||||
REM 1 January OMIT SAT SUN AFTER ADDOMIT SCANFROM -28 SATISFY [isany(wkdaynum(date($Ty, 1, 1)), 0, 6)] MSG Cuti Tahun Baharu
|
||||
OMIT [easterdate($Uy)-2] MSG Good Friday
|
||||
OMIT 30 May MSG Pesta Kaamatan
|
||||
OMIT 31 May MSG Pesta Kaamatan
|
||||
|
||||
@@ -11,12 +11,12 @@
|
||||
# also SYSINCLUDE holidays/my.rem
|
||||
|
||||
OMIT 1 January MSG Tahun Baharu
|
||||
REM 1 January OMIT SAT SUN AFTER ADDOMIT SCANFROM -28 SATISFY [wkdaynum(date($Ty, 1, 1))==0 || wkdaynum(date($Ty, 1, 1))==6] MSG Cuti Tahun Baharu
|
||||
REM 1 January OMIT SAT SUN AFTER ADDOMIT SCANFROM -28 SATISFY [isany(wkdaynum(date($Ty, 1, 1)), 0, 6)] MSG Cuti Tahun Baharu
|
||||
OMIT [easterdate($Uy)-2] MSG Good Friday
|
||||
OMIT 1 June MSG Perayaan Hari Gawai Dayak
|
||||
REM 1 June OMIT SAT SUN AFTER ADDOMIT SCANFROM -28 SATISFY [wkdaynum(date($Ty, 6, 1))==0 || wkdaynum(date($Ty, 6, 1))==6] MSG Cuti Perayaan Hari Gawai Dayak
|
||||
REM 1 June OMIT SAT SUN AFTER ADDOMIT SCANFROM -28 SATISFY [isany(wkdaynum(date($Ty, 6, 1)), 0, 6)] MSG Cuti Perayaan Hari Gawai Dayak
|
||||
OMIT 2 June MSG Perayaan Hari Gawai Dayak
|
||||
REM 2 June OMIT SAT SUN AFTER ADDOMIT SCANFROM -28 SATISFY [wkdaynum(date($Ty, 6, 2))==0 || wkdaynum(date($Ty, 6, 2))==6] MSG Cuti Perayaan Hari Gawai Dayak
|
||||
REM 2 June OMIT SAT SUN AFTER ADDOMIT SCANFROM -28 SATISFY [isany(wkdaynum(date($Ty, 6, 2)), 0, 6)] MSG Cuti Perayaan Hari Gawai Dayak
|
||||
OMIT 22 July MSG Hari Kemerdekaan Sarawak
|
||||
REM 22 July OMIT SAT SUN AFTER ADDOMIT SCANFROM -28 SATISFY [wkdaynum(date($Ty, 7, 22))==0 || wkdaynum(date($Ty, 7, 22))==6] MSG Cuti Hari Kemerdekaan Sarawak
|
||||
REM 22 July OMIT SAT SUN AFTER ADDOMIT SCANFROM -28 SATISFY [isany(wkdaynum(date($Ty, 7, 22)), 0, 6)] MSG Cuti Hari Kemerdekaan Sarawak
|
||||
REM Second Saturday in October ADDOMIT SCANFROM -28 MSG Hari Jadi Yang di-Pertua Negeri Sarawak
|
||||
|
||||
@@ -11,6 +11,6 @@
|
||||
# also SYSINCLUDE holidays/my.rem
|
||||
|
||||
OMIT 1 January MSG Tahun Baharu
|
||||
REM 1 January OMIT SAT SUN AFTER ADDOMIT SCANFROM -28 SATISFY [wkdaynum(date($Ty, 1, 1))==0 || wkdaynum(date($Ty, 1, 1))==6] MSG Cuti Tahun Baharu
|
||||
REM 1 January OMIT SAT SUN AFTER ADDOMIT SCANFROM -28 SATISFY [isany(wkdaynum(date($Ty, 1, 1)), 0, 6)] MSG Cuti Tahun Baharu
|
||||
OMIT 1 February MSG Hari Wilayah Persekutuan
|
||||
REM 1 February OMIT SAT SUN AFTER ADDOMIT SCANFROM -28 SATISFY [wkdaynum(date($Ty, 2, 1))==0 || wkdaynum(date($Ty, 2, 1))==6] MSG Cuti Hari Wilayah Persekutuan
|
||||
REM 1 February OMIT SAT SUN AFTER ADDOMIT SCANFROM -28 SATISFY [isany(wkdaynum(date($Ty, 2, 1)), 0, 6)] MSG Cuti Hari Wilayah Persekutuan
|
||||
|
||||
@@ -11,8 +11,8 @@
|
||||
# also SYSINCLUDE holidays/my.rem
|
||||
|
||||
OMIT 1 January MSG Tahun Baharu
|
||||
REM 1 January OMIT SAT SUN AFTER ADDOMIT SCANFROM -28 SATISFY [wkdaynum(date($Ty, 1, 1))==0 || wkdaynum(date($Ty, 1, 1))==6] MSG Cuti Tahun Baharu
|
||||
REM 1 January OMIT SAT SUN AFTER ADDOMIT SCANFROM -28 SATISFY [isany(wkdaynum(date($Ty, 1, 1)), 0, 6)] MSG Cuti Tahun Baharu
|
||||
OMIT 1 February MSG Hari Wilayah Persekutuan
|
||||
REM 1 February OMIT SAT SUN AFTER ADDOMIT SCANFROM -28 SATISFY [wkdaynum(date($Ty, 2, 1))==0 || wkdaynum(date($Ty, 2, 1))==6] MSG Cuti Hari Wilayah Persekutuan
|
||||
REM 1 February OMIT SAT SUN AFTER ADDOMIT SCANFROM -28 SATISFY [isany(wkdaynum(date($Ty, 2, 1)), 0, 6)] MSG Cuti Hari Wilayah Persekutuan
|
||||
OMIT 30 May MSG Pesta Kaamatan
|
||||
OMIT 31 May MSG Pesta Kaamatan
|
||||
|
||||
@@ -11,6 +11,6 @@
|
||||
# also SYSINCLUDE holidays/my.rem
|
||||
|
||||
OMIT 1 January MSG Tahun Baharu
|
||||
REM 1 January OMIT SAT SUN AFTER ADDOMIT SCANFROM -28 SATISFY [wkdaynum(date($Ty, 1, 1))==0 || wkdaynum(date($Ty, 1, 1))==6] MSG Cuti Tahun Baharu
|
||||
REM 1 January OMIT SAT SUN AFTER ADDOMIT SCANFROM -28 SATISFY [isany(wkdaynum(date($Ty, 1, 1)), 0, 6)] MSG Cuti Tahun Baharu
|
||||
OMIT 1 February MSG Hari Wilayah Persekutuan
|
||||
REM 1 February OMIT SAT SUN AFTER ADDOMIT SCANFROM -28 SATISFY [wkdaynum(date($Ty, 2, 1))==0 || wkdaynum(date($Ty, 2, 1))==6] MSG Cuti Hari Wilayah Persekutuan
|
||||
REM 1 February OMIT SAT SUN AFTER ADDOMIT SCANFROM -28 SATISFY [isany(wkdaynum(date($Ty, 2, 1)), 0, 6)] MSG Cuti Hari Wilayah Persekutuan
|
||||
|
||||
@@ -6,16 +6,16 @@
|
||||
# See important caveats in the README file in this directory.
|
||||
|
||||
OMIT 1 January MSG New Year's Day
|
||||
REM 1 January OMIT SAT SUN AFTER ADDOMIT SCANFROM -28 SATISFY [wkdaynum(date($Ty, 1, 1))==0 || wkdaynum(date($Ty, 1, 1))==6] MSG New Year's Day (observed)
|
||||
REM 1 January OMIT SAT SUN AFTER ADDOMIT SCANFROM -28 SATISFY [isany(wkdaynum(date($Ty, 1, 1)), 0, 6)] MSG New Year's Day (observed)
|
||||
OMIT [easterdate($Uy)-2] MSG Good Friday
|
||||
OMIT [easterdate($Uy)+1] MSG Easter Monday
|
||||
OMIT 1 May MSG Workers' Day
|
||||
REM 1 May OMIT SAT SUN AFTER ADDOMIT SCANFROM -28 SATISFY [wkdaynum(date($Ty, 5, 1))==0 || wkdaynum(date($Ty, 5, 1))==6] MSG Workers' Day (observed)
|
||||
REM 1 May OMIT SAT SUN AFTER ADDOMIT SCANFROM -28 SATISFY [isany(wkdaynum(date($Ty, 5, 1)), 0, 6)] MSG Workers' Day (observed)
|
||||
OMIT 12 June MSG Democracy Day
|
||||
REM 12 June OMIT SAT SUN AFTER ADDOMIT SCANFROM -28 SATISFY [wkdaynum(date($Ty, 6, 12))==0 || wkdaynum(date($Ty, 6, 12))==6] MSG Democracy Day (observed)
|
||||
REM 12 June OMIT SAT SUN AFTER ADDOMIT SCANFROM -28 SATISFY [isany(wkdaynum(date($Ty, 6, 12)), 0, 6)] MSG Democracy Day (observed)
|
||||
OMIT 1 October MSG Independence Day
|
||||
REM 1 October OMIT SAT SUN AFTER ADDOMIT SCANFROM -28 SATISFY [wkdaynum(date($Ty, 10, 1))==0 || wkdaynum(date($Ty, 10, 1))==6] MSG Independence Day (observed)
|
||||
REM 1 October OMIT SAT SUN AFTER ADDOMIT SCANFROM -28 SATISFY [isany(wkdaynum(date($Ty, 10, 1)), 0, 6)] MSG Independence Day (observed)
|
||||
OMIT 25 December MSG Christmas Day
|
||||
REM 25 December OMIT SAT SUN AFTER ADDOMIT SCANFROM -28 SATISFY [wkdaynum(date($Ty, 12, 25))==0 || wkdaynum(date($Ty, 12, 25))==6] MSG Christmas Day (observed)
|
||||
REM 25 December OMIT SAT SUN AFTER ADDOMIT SCANFROM -28 SATISFY [isany(wkdaynum(date($Ty, 12, 25)), 0, 6)] MSG Christmas Day (observed)
|
||||
OMIT 26 December MSG Boxing Day
|
||||
REM 26 December OMIT SAT SUN AFTER ADDOMIT SCANFROM -28 SATISFY [wkdaynum(date($Ty, 12, 26))==0 || wkdaynum(date($Ty, 12, 26))==6] MSG Boxing Day (observed)
|
||||
REM 26 December OMIT SAT SUN AFTER ADDOMIT SCANFROM -28 SATISFY [isany(wkdaynum(date($Ty, 12, 26)), 0, 6)] MSG Boxing Day (observed)
|
||||
|
||||
@@ -20,7 +20,6 @@ OMIT 26 December MSG Tweede Kerstdag
|
||||
|
||||
# Optional holidays
|
||||
REM [easterdate($Uy)-2] MSG Goede Vrijdag
|
||||
|
||||
# Bevrijdingsdag is a holiday every 5th year.
|
||||
# Hence the two reminders below
|
||||
REM 5 May SATISFY [$Ty % 5 != 0] MSG Bevrijdingsdag
|
||||
|
||||
@@ -6,11 +6,11 @@
|
||||
# See important caveats in the README file in this directory.
|
||||
|
||||
OMIT 1 January MSG New Year's Day
|
||||
REM 1 January OMIT SAT SUN AFTER ADDOMIT SCANFROM -28 SATISFY [wkdaynum(date($Ty, 1, 1))==0 || wkdaynum(date($Ty, 1, 1))==6] MSG New Year's Day (observed)
|
||||
REM 1 January OMIT SAT SUN AFTER ADDOMIT SCANFROM -28 SATISFY [isany(wkdaynum(date($Ty, 1, 1)), 0, 6)] MSG New Year's Day (observed)
|
||||
OMIT [easterdate($Uy)-2] MSG Good Friday
|
||||
OMIT 1 May MSG Labour Day
|
||||
REM 1 May OMIT SAT SUN AFTER ADDOMIT SCANFROM -28 SATISFY [wkdaynum(date($Ty, 5, 1))==0 || wkdaynum(date($Ty, 5, 1))==6] MSG Labour Day (observed)
|
||||
REM 1 May OMIT SAT SUN AFTER ADDOMIT SCANFROM -28 SATISFY [isany(wkdaynum(date($Ty, 5, 1)), 0, 6)] MSG Labour Day (observed)
|
||||
OMIT 9 August MSG National Day
|
||||
REM 9 August OMIT SAT SUN AFTER ADDOMIT SCANFROM -28 SATISFY [wkdaynum(date($Ty, 8, 9))==0 || wkdaynum(date($Ty, 8, 9))==6] MSG National Day (observed)
|
||||
REM 9 August OMIT SAT SUN AFTER ADDOMIT SCANFROM -28 SATISFY [isany(wkdaynum(date($Ty, 8, 9)), 0, 6)] MSG National Day (observed)
|
||||
OMIT 25 December MSG Christmas Day
|
||||
REM 25 December OMIT SAT SUN AFTER ADDOMIT SCANFROM -28 SATISFY [wkdaynum(date($Ty, 12, 25))==0 || wkdaynum(date($Ty, 12, 25))==6] MSG Christmas Day (observed)
|
||||
REM 25 December OMIT SAT SUN AFTER ADDOMIT SCANFROM -28 SATISFY [isany(wkdaynum(date($Ty, 12, 25)), 0, 6)] MSG Christmas Day (observed)
|
||||
|
||||
@@ -15,7 +15,7 @@ OMIT 6 April MSG วันจักรี
|
||||
REM 7 April ADDOMIT SCANFROM -28 SATISFY [wkdaynum(date($Ty, 4, 6)) == 0] MSG ชดเชยวันจักรี
|
||||
REM 8 April ADDOMIT SCANFROM -28 SATISFY [wkdaynum(date($Ty, 4, 6)) == 6] MSG ชดเชยวันจักรี
|
||||
OMIT 13 April MSG วันสงกรานต์
|
||||
REM 13 April OMIT SAT SUN AFTER ADDOMIT SCANFROM -28 SATISFY [wkdaynum(date($Ty, 4, 13))==0 || wkdaynum(date($Ty, 4, 13))==6] MSG ชดเชยวันสงกรานต์
|
||||
REM 13 April OMIT SAT SUN AFTER ADDOMIT SCANFROM -28 SATISFY [isany(wkdaynum(date($Ty, 4, 13)), 0, 6)] MSG ชดเชยวันสงกรานต์
|
||||
OMIT 14 April MSG วันสงกรานต์
|
||||
OMIT 15 April MSG วันสงกรานต์
|
||||
OMIT 1 May MSG วันแรงงานแห่งชาติ
|
||||
|
||||
@@ -6,21 +6,21 @@
|
||||
# See important caveats in the README file in this directory.
|
||||
|
||||
OMIT 1 January MSG 中華民國開國紀念日
|
||||
REM 1 January OMIT SAT SUN AFTER ADDOMIT SCANFROM -28 SATISFY [wkdaynum(date($Ty, 1, 1))==0 || wkdaynum(date($Ty, 1, 1))==6] MSG 中華民國開國紀念日(慶祝)
|
||||
REM 1 January OMIT SAT SUN BEFORE ADDOMIT SCANFROM -28 SATISFY [wkdaynum(date($Ty, 1, 1))==0 || wkdaynum(date($Ty, 1, 1))==6] MSG 中華民國開國紀念日(慶祝)
|
||||
REM 1 January OMIT SAT SUN AFTER ADDOMIT SCANFROM -28 SATISFY [isany(wkdaynum(date($Ty, 1, 1)), 0, 6)] MSG 中華民國開國紀念日(慶祝)
|
||||
REM 1 January OMIT SAT SUN BEFORE ADDOMIT SCANFROM -28 SATISFY [isany(wkdaynum(date($Ty, 1, 1)), 0, 6)] MSG 中華民國開國紀念日(慶祝)
|
||||
OMIT 28 February MSG 和平紀念日
|
||||
REM 28 February OMIT SAT SUN AFTER ADDOMIT SCANFROM -28 SATISFY [wkdaynum(date($Ty, 2, 28))==0 || wkdaynum(date($Ty, 2, 28))==6] MSG 和平紀念日(慶祝)
|
||||
REM 28 February OMIT SAT SUN BEFORE ADDOMIT SCANFROM -28 SATISFY [wkdaynum(date($Ty, 2, 28))==0 || wkdaynum(date($Ty, 2, 28))==6] MSG 和平紀念日(慶祝)
|
||||
REM 28 February OMIT SAT SUN AFTER ADDOMIT SCANFROM -28 SATISFY [isany(wkdaynum(date($Ty, 2, 28)), 0, 6)] MSG 和平紀念日(慶祝)
|
||||
REM 28 February OMIT SAT SUN BEFORE ADDOMIT SCANFROM -28 SATISFY [isany(wkdaynum(date($Ty, 2, 28)), 0, 6)] MSG 和平紀念日(慶祝)
|
||||
REM 2 April ADDOMIT SCANFROM -28 SATISFY [wkdaynum(date($Ty, 4, 4)) == 0] MSG 兒童節(慶祝)
|
||||
REM 3 April ADDOMIT SCANFROM -28 SATISFY [wkdaynum(date($Ty, 4, 4)) == 2] MSG 兒童節(慶祝)
|
||||
REM 3 April ADDOMIT SCANFROM -28 SATISFY [wkdaynum(date($Ty, 4, 4)) == 3] MSG 兒童節(慶祝)
|
||||
REM 3 April ADDOMIT SCANFROM -28 SATISFY [wkdaynum(date($Ty, 4, 4)) == 5] MSG 兒童節(慶祝)
|
||||
REM 3 April ADDOMIT SCANFROM -28 SATISFY [wkdaynum(date($Ty, 4, 4)) == 6] MSG 兒童節(慶祝)
|
||||
OMIT 4 April MSG 兒童節
|
||||
REM 4 April OMIT SAT SUN AFTER ADDOMIT SCANFROM -28 SATISFY [wkdaynum(date($Ty, 4, 4))==0 || wkdaynum(date($Ty, 4, 4))==6] MSG 清明節(慶祝)
|
||||
REM 4 April OMIT SAT SUN BEFORE ADDOMIT SCANFROM -28 SATISFY [wkdaynum(date($Ty, 4, 4))==0 || wkdaynum(date($Ty, 4, 4))==6] MSG 清明節(慶祝)
|
||||
REM 4 April OMIT SAT SUN AFTER ADDOMIT SCANFROM -28 SATISFY [isany(wkdaynum(date($Ty, 4, 4)), 0, 6)] MSG 清明節(慶祝)
|
||||
REM 4 April OMIT SAT SUN BEFORE ADDOMIT SCANFROM -28 SATISFY [isany(wkdaynum(date($Ty, 4, 4)), 0, 6)] MSG 清明節(慶祝)
|
||||
REM 5 April ADDOMIT SCANFROM -28 SATISFY [wkdaynum(date($Ty, 4, 4)) == 1] MSG 兒童節(慶祝)
|
||||
REM 5 April ADDOMIT SCANFROM -28 SATISFY [wkdaynum(date($Ty, 4, 4)) == 4] MSG 兒童節(慶祝)
|
||||
OMIT 10 October MSG 中華民國國慶日
|
||||
REM 10 October OMIT SAT SUN AFTER ADDOMIT SCANFROM -28 SATISFY [wkdaynum(date($Ty, 10, 10))==0 || wkdaynum(date($Ty, 10, 10))==6] MSG 中華民國國慶日(慶祝)
|
||||
REM 10 October OMIT SAT SUN BEFORE ADDOMIT SCANFROM -28 SATISFY [wkdaynum(date($Ty, 10, 10))==0 || wkdaynum(date($Ty, 10, 10))==6] MSG 中華民國國慶日(慶祝)
|
||||
REM 10 October OMIT SAT SUN AFTER ADDOMIT SCANFROM -28 SATISFY [isany(wkdaynum(date($Ty, 10, 10)), 0, 6)] MSG 中華民國國慶日(慶祝)
|
||||
REM 10 October OMIT SAT SUN BEFORE ADDOMIT SCANFROM -28 SATISFY [isany(wkdaynum(date($Ty, 10, 10)), 0, 6)] MSG 中華民國國慶日(慶祝)
|
||||
|
||||
@@ -13,6 +13,6 @@
|
||||
REM Fourth Monday in April ADDOMIT SCANFROM -28 MSG State Holiday
|
||||
REM Second Monday in October ADDOMIT SCANFROM -28 MSG Columbus Day
|
||||
REM Friday 23 November ADDOMIT SCANFROM -28 MSG State Holiday
|
||||
REM 23 December ADDOMIT SCANFROM -28 SATISFY [$TW == 4 || $Tw == 5] MSG Washington's Birthday
|
||||
REM 24 December ADDOMIT SCANFROM -28 SATISFY [$Tw == 1 || $Tw == 2 || $Tw == 4] MSG Washington's Birthday
|
||||
REM 26 December ADDOMIT SCANFROM -28 SATISFY [$Tw == 2 || $Tw == 5] MSG Washington's Birthday
|
||||
REM 23 December ADDOMIT SCANFROM -28 SATISFY [isany($Tw, 5, 4)] MSG Washington's Birthday
|
||||
REM 24 December ADDOMIT SCANFROM -28 SATISFY [isany($Tw, 1, 2, 4)] MSG Washington's Birthday
|
||||
REM 26 December ADDOMIT SCANFROM -28 SATISFY [isany($Tw, 2, 5)] MSG Washington's Birthday
|
||||
|
||||
@@ -14,6 +14,6 @@ OMIT [easterdate($Uy)-2] MSG Good Friday
|
||||
REM Tuesday 2 May ADDOMIT SCANFROM -28 MSG Primary Election Day
|
||||
REM Second Monday in October ADDOMIT SCANFROM -28 MSG Columbus Day
|
||||
REM Friday 23 November ADDOMIT SCANFROM -28 MSG Lincoln's Birthday
|
||||
REM 23 December ADDOMIT SCANFROM -28 SATISFY [$TW == 4 || $Tw == 5] MSG Washington's Birthday
|
||||
REM 24 December ADDOMIT SCANFROM -28 SATISFY [$Tw == 1 || $Tw == 2 || $Tw == 4] MSG Washington's Birthday
|
||||
REM 26 December ADDOMIT SCANFROM -28 SATISFY [$Tw == 2 || $Tw == 5] MSG Washington's Birthday
|
||||
REM 23 December ADDOMIT SCANFROM -28 SATISFY [isany($Tw, 5, 4)] MSG Washington's Birthday
|
||||
REM 24 December ADDOMIT SCANFROM -28 SATISFY [isany($Tw, 1, 2, 4)] MSG Washington's Birthday
|
||||
REM 26 December ADDOMIT SCANFROM -28 SATISFY [isany($Tw, 2, 5)] MSG Washington's Birthday
|
||||
|
||||
@@ -6,16 +6,16 @@
|
||||
# See important caveats in the README file in this directory.
|
||||
|
||||
OMIT 1 January MSG Yangi yil
|
||||
REM 1 January OMIT SAT SUN AFTER ADDOMIT SCANFROM -28 SATISFY [wkdaynum(date($Ty, 1, 1))==0 || wkdaynum(date($Ty, 1, 1))==6] MSG Yangi yil (ko‘chirilgan)
|
||||
REM 1 January OMIT SAT SUN AFTER ADDOMIT SCANFROM -28 SATISFY [isany(wkdaynum(date($Ty, 1, 1)), 0, 6)] MSG Yangi yil (ko‘chirilgan)
|
||||
OMIT 8 March MSG Xotin-qizlar kuni
|
||||
REM 8 March OMIT SAT SUN AFTER ADDOMIT SCANFROM -28 SATISFY [wkdaynum(date($Ty, 3, 8))==0 || wkdaynum(date($Ty, 3, 8))==6] MSG Xotin-qizlar kuni (ko‘chirilgan)
|
||||
REM 8 March OMIT SAT SUN AFTER ADDOMIT SCANFROM -28 SATISFY [isany(wkdaynum(date($Ty, 3, 8)), 0, 6)] MSG Xotin-qizlar kuni (ko‘chirilgan)
|
||||
OMIT 21 March MSG Navro‘z bayrami
|
||||
REM 21 March OMIT SAT SUN AFTER ADDOMIT SCANFROM -28 SATISFY [wkdaynum(date($Ty, 3, 21))==0 || wkdaynum(date($Ty, 3, 21))==6] MSG Navro‘z bayrami (ko‘chirilgan)
|
||||
REM 21 March OMIT SAT SUN AFTER ADDOMIT SCANFROM -28 SATISFY [isany(wkdaynum(date($Ty, 3, 21)), 0, 6)] MSG Navro‘z bayrami (ko‘chirilgan)
|
||||
OMIT 9 May MSG Xotira va qadrlash kuni
|
||||
REM 9 May OMIT SAT SUN AFTER ADDOMIT SCANFROM -28 SATISFY [wkdaynum(date($Ty, 5, 9))==0 || wkdaynum(date($Ty, 5, 9))==6] MSG Xotira va qadrlash kuni (ko‘chirilgan)
|
||||
REM 9 May OMIT SAT SUN AFTER ADDOMIT SCANFROM -28 SATISFY [isany(wkdaynum(date($Ty, 5, 9)), 0, 6)] MSG Xotira va qadrlash kuni (ko‘chirilgan)
|
||||
OMIT 1 September MSG Mustaqillik kuni
|
||||
REM 1 September OMIT SAT SUN AFTER ADDOMIT SCANFROM -28 SATISFY [wkdaynum(date($Ty, 9, 1))==0 || wkdaynum(date($Ty, 9, 1))==6] MSG Mustaqillik kuni (ko‘chirilgan)
|
||||
REM 1 September OMIT SAT SUN AFTER ADDOMIT SCANFROM -28 SATISFY [isany(wkdaynum(date($Ty, 9, 1)), 0, 6)] MSG Mustaqillik kuni (ko‘chirilgan)
|
||||
OMIT 1 October MSG O‘qituvchi va murabbiylar kuni
|
||||
REM 1 October OMIT SAT SUN AFTER ADDOMIT SCANFROM -28 SATISFY [wkdaynum(date($Ty, 10, 1))==0 || wkdaynum(date($Ty, 10, 1))==6] MSG O‘qituvchi va murabbiylar kuni (ko‘chirilgan)
|
||||
REM 1 October OMIT SAT SUN AFTER ADDOMIT SCANFROM -28 SATISFY [isany(wkdaynum(date($Ty, 10, 1)), 0, 6)] MSG O‘qituvchi va murabbiylar kuni (ko‘chirilgan)
|
||||
OMIT 8 December MSG O‘zbekiston Respublikasi Konstitutsiyasi kuni
|
||||
REM 8 December OMIT SAT SUN AFTER ADDOMIT SCANFROM -28 SATISFY [wkdaynum(date($Ty, 12, 8))==0 || wkdaynum(date($Ty, 12, 8))==6] MSG O‘zbekiston Respublikasi Konstitutsiyasi kuni (ko‘chirilgan)
|
||||
REM 8 December OMIT SAT SUN AFTER ADDOMIT SCANFROM -28 SATISFY [isany(wkdaynum(date($Ty, 12, 8)), 0, 6)] MSG O‘zbekiston Respublikasi Konstitutsiyasi kuni (ko‘chirilgan)
|
||||
|
||||
@@ -6,12 +6,12 @@
|
||||
# See important caveats in the README file in this directory.
|
||||
|
||||
OMIT 1 January MSG Tết Dương lịch
|
||||
REM 1 January OMIT SAT SUN AFTER ADDOMIT SCANFROM -28 SATISFY [wkdaynum(date($Ty, 1, 1))==0 || wkdaynum(date($Ty, 1, 1))==6] MSG Tết Dương lịch (nghỉ bù)
|
||||
REM 1 January OMIT SAT SUN AFTER ADDOMIT SCANFROM -28 SATISFY [isany(wkdaynum(date($Ty, 1, 1)), 0, 6)] MSG Tết Dương lịch (nghỉ bù)
|
||||
OMIT 30 April MSG Ngày Chiến thắng
|
||||
REM 30 April OMIT SAT SUN AFTER ADDOMIT SCANFROM -28 SATISFY [wkdaynum(date($Ty, 4, 30))==0 || wkdaynum(date($Ty, 4, 30))==6] MSG Ngày Chiến thắng (nghỉ bù)
|
||||
REM 30 April OMIT SAT SUN AFTER ADDOMIT SCANFROM -28 SATISFY [isany(wkdaynum(date($Ty, 4, 30)), 0, 6)] MSG Ngày Chiến thắng (nghỉ bù)
|
||||
OMIT 1 May MSG Ngày Quốc tế Lao động
|
||||
REM 1 May OMIT SAT SUN AFTER ADDOMIT SCANFROM -28 SATISFY [wkdaynum(date($Ty, 5, 1))==0 || wkdaynum(date($Ty, 5, 1))==6] MSG Ngày Quốc tế Lao động (nghỉ bù)
|
||||
REM 1 September ADDOMIT SCANFROM -28 SATISFY [$Tw == 1 || $Tw == 2 || $Tw == 4 || $Tw == 5] MSG Quốc khánh
|
||||
REM 1 May OMIT SAT SUN AFTER ADDOMIT SCANFROM -28 SATISFY [isany(wkdaynum(date($Ty, 5, 1)), 0, 6)] MSG Ngày Quốc tế Lao động (nghỉ bù)
|
||||
REM 1 September ADDOMIT SCANFROM -28 SATISFY [isany($Tw, 1, 2, 4, 5)] MSG Quốc khánh
|
||||
OMIT 2 September MSG Quốc khánh
|
||||
REM 2 September OMIT SAT SUN AFTER ADDOMIT SCANFROM -28 SATISFY [wkdaynum(date($Ty, 9, 2))==0 || wkdaynum(date($Ty, 9, 2))==6] MSG Quốc khánh (nghỉ bù)
|
||||
REM 3 September ADDOMIT SCANFROM -28 SATISFY [$Tw == 2 || $Tw == 5 || $Tw == 1] MSG Quốc khánh
|
||||
REM 2 September OMIT SAT SUN AFTER ADDOMIT SCANFROM -28 SATISFY [isany(wkdaynum(date($Ty, 9, 2)), 0, 6)] MSG Quốc khánh (nghỉ bù)
|
||||
REM 3 September ADDOMIT SCANFROM -28 SATISFY [isany($Tw, 2, 5, 1)] MSG Quốc khánh
|
||||
|
||||
@@ -2,6 +2,7 @@
|
||||
if !defined("__autolang__")
|
||||
SET __autolang__ 1
|
||||
PRESERVE __autolang__
|
||||
PUSH-VARS autolang
|
||||
SET autolang getenv("REMIND_LANG")
|
||||
|
||||
IF autolang == ""
|
||||
@@ -23,6 +24,6 @@ if !defined("__autolang__")
|
||||
ENDIF
|
||||
ENDIF
|
||||
ENDIF
|
||||
UNSET autolang
|
||||
POP-VARS
|
||||
ENDIF
|
||||
|
||||
|
||||
5
include/utils/add-html-anchors.rem
Normal file
5
include/utils/add-html-anchors.rem
Normal file
@@ -0,0 +1,5 @@
|
||||
# Add HTML anchors to each day box.
|
||||
# This adds anchors: <a id="YYYY-MM-DD" name="YYYY-MM-DD"></a>
|
||||
# to each calendar box in an HTML calendar.
|
||||
|
||||
REM SPECIAL HTML <a id="[$T]" name="[$T]"></a>
|
||||
208
man/remind.1.in
208
man/remind.1.in
@@ -300,7 +300,7 @@ standard error stream) to the standard output stream.
|
||||
.B \-d\fR\fIchars\fR
|
||||
The \fB-d\fR option enables certain debugging modes. The \fIchars\fR
|
||||
specify which modes to enable:
|
||||
.RS 2
|
||||
.RS
|
||||
.TP
|
||||
.B e
|
||||
Echo all input lines
|
||||
@@ -328,6 +328,26 @@ tree. This is unlikely to be useful unless you are working on
|
||||
.B h
|
||||
Dump hash-table statistics on exit.
|
||||
.TP
|
||||
.B u
|
||||
When \fBRemind\fR exits, print a list of variables that were SET, but
|
||||
not subsequently used.
|
||||
.RS
|
||||
.PP
|
||||
Note that the \fBu\fR debugging flag may produce spurious warnings. For
|
||||
example, this sequence of commands:
|
||||
.PP
|
||||
.nf
|
||||
DEBUG +u
|
||||
SET a 1
|
||||
IFTRIG Wed
|
||||
MSG a = [a]
|
||||
ENDIF
|
||||
.fi
|
||||
.PP
|
||||
will issue a warning about \fBa\fR being unused unless it is run on a
|
||||
Wednesday.
|
||||
.RE
|
||||
.TP
|
||||
.B n
|
||||
Print debugging information about why \fBRemind\fR considers an expression
|
||||
to be "non-constant"
|
||||
@@ -2559,7 +2579,7 @@ For example, to delete all the variables declared above, use:
|
||||
UNSET a b mydir time date
|
||||
.fi
|
||||
.PP
|
||||
.B SYSTEM VARIABLES
|
||||
.SH SYSTEM VARIABLES
|
||||
.PP
|
||||
In addition to the regular user variables, \fBRemind\fR has several
|
||||
"system variables" that are used to query or control the operating
|
||||
@@ -3038,7 +3058,7 @@ Equivalent to \fBday(trigdate())\fR.
|
||||
.B $Tm (read-only)
|
||||
Equivalent to \fBmonnum(trigdate())\fR.
|
||||
.TP
|
||||
.B $Tu (read-only)
|
||||
.B $Tu (read-only, DATE type)
|
||||
Equivalent to \fBtriguntil()\fR.
|
||||
.TP
|
||||
.B $Tw (read-only)
|
||||
@@ -3105,7 +3125,43 @@ Note: If any of the calendar modes are in effect, then the
|
||||
values of $Daemon, $DontFork, $DontTrigAts, $DontQueue, $HushMode,
|
||||
$IgnoreOnce, $InfDelta, and $NextMode are not meaningful.
|
||||
.PP
|
||||
.B BUILT-IN FUNCTIONS
|
||||
.SH SAVING AND RESTORING VARIABLES
|
||||
.PP
|
||||
Just as with the OMIT context, you can save and restore the values of
|
||||
global variables and all (modifiable) system variables. For example:
|
||||
.PP
|
||||
.nf
|
||||
SET a 1
|
||||
UNSET b
|
||||
|
||||
# Save variables
|
||||
PUSH-VARS $DefaultColor $AddBlankLines a b
|
||||
|
||||
SET $DefaultColor "255 0 0"
|
||||
SET $AddBlankLines 0
|
||||
SET a 3
|
||||
SET b 4
|
||||
REM MSG Hello
|
||||
|
||||
# Restore all the variables we pushed earlier
|
||||
POP-VARS
|
||||
|
||||
# Now the changes to $DefaultColor and $AddBlankLines
|
||||
# have been undone. Additionally, a is restored to 1
|
||||
# and b is unset
|
||||
.fi
|
||||
.PP
|
||||
As you see from the example, PUSH-VARS takes a list of global variable
|
||||
names and/or system variable names. You can save the values of any
|
||||
\fImodifiable\fR system variables and any global variable. You can
|
||||
even push global variables that are not set.
|
||||
.PP
|
||||
The POP-VARS command restores the values of all system variables and
|
||||
global variables that were pushed by the most recent PUSH-VARS
|
||||
command. If you push an undefined global variable, then that variable
|
||||
is unset by the POP-VARS command.
|
||||
.PP
|
||||
.SH BUILT-IN FUNCTIONS
|
||||
.PP
|
||||
\fBRemind\fR has a plethora of built-in functions. The syntax for a function
|
||||
call is the same as in C - the function name, followed a comma-separated list
|
||||
@@ -3400,15 +3456,22 @@ characters occupy two columns. \fBcolumns(str)\fR takes all of that
|
||||
into account. Note that if \fBRemind\fR was compiled without Unicode support,
|
||||
\fBcolumns(str)\fR returns a type mismatch error.
|
||||
.RE
|
||||
|
||||
.TP
|
||||
.B const(x_arg)
|
||||
Evaluates \fIarg\fR and returns it, but also ensures that the result
|
||||
is marked "constant". Use with caution; incorrect use could result
|
||||
in unwanted reminders being purged in Purge Mode. See also the section
|
||||
"NON-CONSTANT EXPRESSIONS"
|
||||
.TP
|
||||
.B current()
|
||||
Returns the current date and time as a DATETIME object. This may be the
|
||||
actual date and time, or may be the date and time supplied on the command line.
|
||||
.TP
|
||||
.B date(i_y, i_m, i_d)
|
||||
.B date(i_y, si_m, i_d)
|
||||
The \fBdate()\fR function returns a \fBDATE\fR object with the year,
|
||||
month and day components specified by \fIy\fR, \fIm\fR and \fId\fR.
|
||||
The month can be specified as an integer from 1 to 12, or a string
|
||||
that is the name of a month.
|
||||
.TP
|
||||
.B datepart(dq_datetime)
|
||||
Returns a \fBDATE\fR object representing the date portion of
|
||||
@@ -3425,11 +3488,13 @@ If you supply three arguments, the first
|
||||
must be a DATE and the second and third must be INTs. The second and
|
||||
third arguments are interpreted as hours and minutes and converted to a TIME.
|
||||
.PP
|
||||
If you supply four arguments, the first three must be INTs, interpreted
|
||||
as the year, month and day. The fourth argument must be a TIME.
|
||||
If you supply four arguments, they are interpreted as year, month, day
|
||||
and time. Year and day must be INTs. Month may be an INT from 0 to 12
|
||||
or a string naming a month. Time must be a TIME.
|
||||
.PP
|
||||
Finally, if you supply five arguments, they must all be INTs and are
|
||||
interpreted as year, month, day, hour and minute.
|
||||
interpreted as year, month, day, hour and minute. (Actually, month
|
||||
can also be a string that is the name of a month.)
|
||||
.RE
|
||||
.TP
|
||||
.B dawn([dq_date])
|
||||
@@ -3442,8 +3507,12 @@ This function takes a \fBDATE\fR or \fBDATETIME\fR as an argument, and
|
||||
returns an \fBINT\fR that is the day-of-month component of
|
||||
\fIdate\fR.
|
||||
.TP
|
||||
.B daysinmon(i_m, i_y)
|
||||
Returns the number of days in month \fIm\fR (1-12) of the year \fIy\fR.
|
||||
.B daysinmon(si_m, i_y)\fR or \fB daysinmon(dq_date)\fR
|
||||
Returns the number of days in month \fIm\fR (1-12) of the year
|
||||
\fIy\fR. The first argument can either be an integer from 1 to 12, or
|
||||
a string that is the name of a month. If given a single DATE or
|
||||
DATETIME argument, returns the number of days in the month containing
|
||||
the argument.
|
||||
.TP
|
||||
.B defined(s_var)
|
||||
Returns 1 if the variable named by \fIvar\fR is defined, or 0 if it is not.
|
||||
@@ -3534,6 +3603,10 @@ The result will be "F is 12" because the reference to \fIx\fR inside the
|
||||
\fBeval()\fR argument refers to the \fIglobal\fR variable \fIx\fR and
|
||||
not the function argument.
|
||||
.PP
|
||||
Note that for safety, \fBRUN\fR is disabled during the evaluation of
|
||||
\fBeval()\fR, which means you can't use the \fBshell()\fR function from
|
||||
within an \fBeval()\fR.
|
||||
.PP
|
||||
.RE
|
||||
.TP
|
||||
.B evaltrig(s_trigger [,dq_start])
|
||||
@@ -3745,10 +3818,20 @@ functions. It is available starting with version 03.00.07 of \fBRemind\fR.
|
||||
.B minute(tq_time)
|
||||
Returns the minute component of \fItime\fR.
|
||||
.TP
|
||||
.B mon(dqi_arg)
|
||||
.B mon(dqis_arg)
|
||||
If \fIarg\fR is of \fBDATE\fR or \fBDATETIME\fR type, returns a string
|
||||
that names the month component of the date. If \fIarg\fR is an
|
||||
\fBINT\fR from 1 to 12, returns a string that names the month.
|
||||
\fBINT\fR from 1 to 12, returns a string that names the month. If \fIarg\fR
|
||||
is a \fBSTRING\fR, returns the name of the month. This last case might
|
||||
sound silly, but for example:
|
||||
.RS
|
||||
.PP
|
||||
.nf
|
||||
mon("Mar")
|
||||
.fi
|
||||
.PP
|
||||
will return "March", the full name of the month.
|
||||
.RE
|
||||
.TP
|
||||
.B monnum(dq_date)\fR or \fBmonnum(s_str)\fR
|
||||
Returns an \fBINT\fR from 1 to 12, representing the month component of
|
||||
@@ -4566,7 +4649,9 @@ an error results.
|
||||
.PP
|
||||
However, if you supply a second argument, it is returned if the \fIvarname\fR
|
||||
is not defined. The expression value("XY", 0) will return 0 if XY is not
|
||||
defined, and the value of XY if it is defined.
|
||||
defined, and the value of XY if it is defined. Note that \fBvalue\fR
|
||||
evaluates the second argument lazily; it is \fInot\fR evaluated if
|
||||
\fIvarname\fR is defined.
|
||||
.RE
|
||||
.TP
|
||||
.B version()
|
||||
@@ -5023,29 +5108,69 @@ it is defined. However, if \fIfunc_a\fR exists, then it is renamed to
|
||||
was defined prior to the \fBFRENAME\fR command, then that old
|
||||
definition is lost.
|
||||
.PP
|
||||
\fBFRENAME\fR is useful if you want to save and restore the definition
|
||||
of a user-defined function. For example, you might want to define
|
||||
a \fBmsgprefix\fR function for a block of reminders, but not permanently
|
||||
overwrite any existing definition. You could do something like this:
|
||||
.PP
|
||||
.nf
|
||||
FRENAME msgprefix saved_msgprefix
|
||||
FSET msgprefix(x) "My new prefix: "
|
||||
INCLUDE block_of_reminders.rem
|
||||
FRENAME saved_msgprefix msgprefix
|
||||
.PP
|
||||
The file \fBblock_of_reminders.rem\fR would be executed with the
|
||||
\fBmsgprefix\fR function defined above. After the second FRENAME,
|
||||
\fBmsgprefix\fR would be restored to its previous definition if
|
||||
it had one, or simply unset if it was not previously defined.
|
||||
.PP
|
||||
If either argument to the \fBFRENAME\fR command is the name of a built-in
|
||||
function, the command fails with an error message and does nothing.
|
||||
.PP
|
||||
If you define a user-defined function and then later on redefine it,
|
||||
\fBRemind\fR will issue a warning. If you do not want this warning,
|
||||
then use \fBFUNSET\fR to remove the existing definition before you
|
||||
redefine the function.
|
||||
redefine the function. Alternatively, you can use a "-" token before
|
||||
the function name to suppress "redefined function" warnings, as in the
|
||||
following example:
|
||||
.PP
|
||||
.nf
|
||||
FSET - f(x) 2*x
|
||||
# You must have space before and after the "-"
|
||||
# This will NOT work:
|
||||
# FSET -f(x) 2*x
|
||||
.fi
|
||||
.PP
|
||||
to define a function and suppress any "redefined function" warning.
|
||||
.PP
|
||||
.SH SAVING AND RESTORING FUNCTIONS
|
||||
.PP
|
||||
Occasionally, it is useful to redefine a function for a specific block of
|
||||
reminders, but to restore its original definition at the end of that
|
||||
block. Just as with variables, functions can be pushed onto and popped
|
||||
off an internal stack. Here is an example:
|
||||
.PP
|
||||
.nf
|
||||
PUSH-FUNCS msgprefix
|
||||
FSET msgprefix(x) "My new prefix: "
|
||||
INCLUDE block_of_reminders.rem
|
||||
POP-FUNCS
|
||||
.fi
|
||||
.PP
|
||||
The file \fBblock_of_reminders.rem\fR would be executed with the
|
||||
\fBmsgprefix\fR function defined above. After the POP-FUNCS
|
||||
\fBmsgprefix\fR would be restored to its previous definition if
|
||||
it had one, or simply unset if it was not previously defined.
|
||||
.PP
|
||||
The command PUSH-FUNCS takes a space-separated list of function names.
|
||||
All of the named user-defined functions will be saved to an internal
|
||||
stack. You can even push names that are not defined as any function.
|
||||
.PP
|
||||
After a function name has been pushed, \fBRemind\fR will not issue a
|
||||
warning if you redefine it, because presumably the purpose of pushing
|
||||
it in the first place is to redefine it.
|
||||
.PP
|
||||
The command POP-FUNCS restores the definitions of all the user-defined
|
||||
functions in the corresponding PUSH-FUNCS command. If undefined functions
|
||||
were pushed onto the stack, then POP-FUNCS makes those functions undefined
|
||||
again. Here's one more example:
|
||||
.PP
|
||||
.nf
|
||||
FUNSET a
|
||||
FSET b(x) 2*x
|
||||
REM MSG [b(3)] # Outputs 6
|
||||
PUSH-FUNCS a b
|
||||
FSET a(x) 22*x
|
||||
FSET b(x) 3*x
|
||||
REM MSG [a(3)] [b(3)] # Outputs 66 9
|
||||
POP-FUNCS
|
||||
REM MSG [a(3)] # Undefined function "a"
|
||||
REM MSG [b(3)] # Outputs 6
|
||||
.fi
|
||||
.PP
|
||||
.SH PRECISE SCHEDULING
|
||||
.PP
|
||||
@@ -5335,7 +5460,7 @@ under program control. The format is:
|
||||
.PP
|
||||
\fBDEBUG\fR [+\fIflagson\fR] [\-\fIflagsoff\fR]
|
||||
.PP
|
||||
\fIFlagson\fR and \fIflagsoff\fR consist of strings of the characters "shextvlfqn"
|
||||
\fIFlagson\fR and \fIflagsoff\fR consist of strings of the characters "shextvlfqnu"
|
||||
that correspond to the debugging options discussed in the command-line
|
||||
options section. If preceded with a "+", the corresponding group of
|
||||
debugging options is switched on. Otherwise, they are switched off.
|
||||
@@ -5810,7 +5935,13 @@ Here are some examples that should make things clear:
|
||||
.PP
|
||||
Note that within the \fBIF\fR...\fBENDIF\fR scope, any assignments
|
||||
are non-constant because the code flow depends on today's date, which
|
||||
could change in subsequent \fBRemind\fR runs.
|
||||
could change in subsequent \fBRemind\fR runs. If you want to force
|
||||
a variable to be treated as constant, no matter what, then use the following
|
||||
just before you use the variable:
|
||||
.PP
|
||||
.nf
|
||||
SET var const(var)
|
||||
.fi
|
||||
.PP
|
||||
Variables initialized on the command-line with the \fB\-i\fR flag are
|
||||
\fIalways\fR considered to be non-constant.
|
||||
@@ -6725,12 +6856,13 @@ date of the scanning\fR that
|
||||
satisfies the trigger. In addition, there is one special case in which
|
||||
\fBtrigvalid()\fR returns 1 and \fBtrigdate()\fR returns a meaningful result:
|
||||
.PP
|
||||
If the \fBREM\fR or \fBIFTRIG\fR command did not contain an \fBUNTIL\fR
|
||||
clause, and contained all of the \fIday\fR, \fImonth\fR and \fIyear\fR
|
||||
components, then \fBRemind\fR will correctly compute a trigger date, even
|
||||
if it happens to be before the start of scanning.
|
||||
Note that this behaviour is not true for
|
||||
If the \fBREM\fR or \fBIFTRIG\fR command did not contain an
|
||||
\fBUNTIL\fR or \fBSATISFY\fR clause, and contained all of the
|
||||
\fIday\fR, \fImonth\fR and \fIyear\fR components, then \fBRemind\fR
|
||||
will correctly compute a trigger date, even if it happens to be before
|
||||
the start of scanning. Note that this behaviour is not true for
|
||||
versions of \fBRemind\fR prior to 03.00.01.
|
||||
|
||||
.SH FILES
|
||||
.PP
|
||||
The traditional location of your reminders file or directory is:
|
||||
|
||||
@@ -4,7 +4,7 @@ REM2HTML
|
||||
rem2html is a Perl script that transforms the output of `remind -pp
|
||||
...' to HTML. Type `perl rem2html --help' for usage information.
|
||||
|
||||
rem2html requires the Perl modules `JSON::Any' and `Getopt::Long'. It
|
||||
rem2html requires the Perl modules `JSON::MaybeXS' and `Getopt::Long'. It
|
||||
will not be installed unless you have those modules as well as Perl
|
||||
itself.
|
||||
|
||||
|
||||
@@ -265,6 +265,7 @@ while(1) {
|
||||
}
|
||||
my ($obj, $err) = Remind::PDF->create_from_stream(*STDIN,
|
||||
{color => 1,
|
||||
colour => 1,
|
||||
shade => 1,
|
||||
moon => 1,
|
||||
pango => 1,
|
||||
|
||||
@@ -102,7 +102,7 @@ depend:
|
||||
# distributions, etc.
|
||||
|
||||
cppcheck:
|
||||
cppcheck -j`nproc` -v --force --enable=all --suppress=ConfigurationNotChecked --suppress=unmatchedSuppression --suppress=variableScope --inline-suppr .
|
||||
cppcheck -j`nproc` -v --force --enable=all --suppress=missingIncludeSystem --suppress=ConfigurationNotChecked --suppress=unmatchedSuppression --suppress=variableScope --inline-suppr --check-level=exhaustive .
|
||||
|
||||
# Build a tar file based on all files checked into git.
|
||||
distro:
|
||||
|
||||
@@ -55,7 +55,7 @@ typedef struct cal_entry {
|
||||
DynamicBuffer tags;
|
||||
char passthru[PASSTHRU_LEN+1];
|
||||
int duration;
|
||||
char *filename;
|
||||
char const *filename;
|
||||
int lineno;
|
||||
int lineno_start;
|
||||
Trigger trig;
|
||||
@@ -279,6 +279,7 @@ static int DidAMonth;
|
||||
static int DidAWeek;
|
||||
static int DidADay;
|
||||
|
||||
static char const *CalendarTime(int tim, int duration);
|
||||
static void ColorizeEntry(CalEntry const *e, int clamp);
|
||||
static void SortCol (CalEntry **col);
|
||||
static void DoCalendarOneWeek (int nleft);
|
||||
@@ -288,7 +289,7 @@ static int WriteCalendarRow (void);
|
||||
static void WriteWeekHeaderLine (void);
|
||||
static void WritePostHeaderLine (void);
|
||||
static void PrintLeft (char const *s, int width, char pad);
|
||||
static void PrintCentered (char const *s, int width, char *pad);
|
||||
static void PrintCentered (char const *s, int width, char const *pad);
|
||||
static int WriteOneCalLine (int dse, int wd);
|
||||
static int WriteOneColLine (int col);
|
||||
static void GenerateCalEntries (int col);
|
||||
@@ -380,7 +381,7 @@ despace(char const *s)
|
||||
return buf;
|
||||
}
|
||||
|
||||
void PrintJSONChar(char c) {
|
||||
static void PrintJSONChar(char c) {
|
||||
switch(c) {
|
||||
case '\b': printf("\\b"); break;
|
||||
case '\f': printf("\\f"); break;
|
||||
@@ -422,7 +423,7 @@ void PrintJSONString(char const *s)
|
||||
}
|
||||
}
|
||||
|
||||
void PrintJSONStringLC(char const *s)
|
||||
static void PrintJSONStringLC(char const *s)
|
||||
{
|
||||
while (*s) {
|
||||
switch(*s) {
|
||||
@@ -466,7 +467,7 @@ void PrintJSONKeyPairString(char const *name, char const *val)
|
||||
printf("\",");
|
||||
}
|
||||
|
||||
void PrintJSONKeyPairDate(char const *name, int dse)
|
||||
static void PrintJSONKeyPairDate(char const *name, int dse)
|
||||
{
|
||||
int y, m, d;
|
||||
if (dse == NO_DATE) {
|
||||
@@ -480,7 +481,7 @@ void PrintJSONKeyPairDate(char const *name, int dse)
|
||||
|
||||
}
|
||||
|
||||
void PrintJSONKeyPairDateTime(char const *name, int dt)
|
||||
static void PrintJSONKeyPairDateTime(char const *name, int dt)
|
||||
{
|
||||
int y, m, d, h, i, k;
|
||||
if (dt == NO_TIME) {
|
||||
@@ -498,7 +499,7 @@ void PrintJSONKeyPairDateTime(char const *name, int dt)
|
||||
|
||||
}
|
||||
|
||||
void PrintJSONKeyPairTime(char const *name, int t)
|
||||
static void PrintJSONKeyPairTime(char const *name, int t)
|
||||
{
|
||||
int h, i;
|
||||
if (t == NO_TIME) {
|
||||
@@ -646,7 +647,7 @@ Colorize256(int r, int g, int b, int bg, int clamp)
|
||||
int best = -1;
|
||||
int best_dist = 0;
|
||||
int dist;
|
||||
struct xterm256_colors *cur;
|
||||
struct xterm256_colors const *cur;
|
||||
size_t i;
|
||||
|
||||
if (clamp) {
|
||||
@@ -757,7 +758,7 @@ InitMoonsAndShades(void)
|
||||
static void
|
||||
SetShadeEntry(int dse, char const *shade)
|
||||
{
|
||||
int y, m, d;
|
||||
int d;
|
||||
int r, g, b;
|
||||
/* Don't bother if we're not doing SHADE specials */
|
||||
if (!UseBGVTColors) {
|
||||
@@ -774,7 +775,7 @@ SetShadeEntry(int dse, char const *shade)
|
||||
if (r < 0 || g < 0 || b < 0 || r > 255 || g > 255 || b > 255) {
|
||||
return;
|
||||
}
|
||||
FromDSE(dse, &y, &m, &d);
|
||||
FromDSE(dse, NULL, NULL, &d);
|
||||
bgcolor[d][0] = r;
|
||||
bgcolor[d][1] = g;
|
||||
bgcolor[d][2] = b;
|
||||
@@ -784,7 +785,7 @@ static void
|
||||
SetMoonEntry(int dse, char const *moon)
|
||||
{
|
||||
int phase;
|
||||
int y, m, d;
|
||||
int d;
|
||||
char msg[28];
|
||||
|
||||
/* Don't bother unless it's utf-8 */
|
||||
@@ -803,7 +804,7 @@ SetMoonEntry(int dse, char const *moon)
|
||||
/* Bad phase */
|
||||
return;
|
||||
}
|
||||
FromDSE(dse, &y, &m, &d);
|
||||
FromDSE(dse, NULL, NULL, &d);
|
||||
if (msg[0]) {
|
||||
snprintf(moons[d], sizeof(moons[d]), "%s %s", moonphase_emojis[phase], msg);
|
||||
} else {
|
||||
@@ -1387,7 +1388,7 @@ static void PrintLeft(char const *s, int width, char pad)
|
||||
/* Center a piece of text */
|
||||
/* */
|
||||
/***************************************************************/
|
||||
static void PrintCentered(char const *s, int width, char *pad)
|
||||
static void PrintCentered(char const *s, int width, char const *pad)
|
||||
{
|
||||
#ifndef REM_USE_WCHAR
|
||||
int len = strlen(s);
|
||||
@@ -1476,13 +1477,13 @@ static void PrintCentered(char const *s, int width, char *pad)
|
||||
static int WriteOneCalLine(int start_dse, int wd)
|
||||
{
|
||||
int done = 1, i;
|
||||
int y, m, d;
|
||||
int d;
|
||||
|
||||
gon();
|
||||
DRAW(tb);
|
||||
goff();
|
||||
for (i=0; i<7; i++) {
|
||||
FromDSE(start_dse+i, &y, &m, &d);
|
||||
FromDSE(start_dse+i, NULL, NULL, &d);
|
||||
d -= wd;
|
||||
if (CalColumn[i]) {
|
||||
Backgroundize(ColToDay[i]);
|
||||
@@ -1539,7 +1540,6 @@ static int WriteOneColLine(int col)
|
||||
CalColumn[col] = e->next;
|
||||
free(e->text);
|
||||
free(e->raw_text);
|
||||
free(e->filename);
|
||||
if (e->wc_text) free(e->wc_text);
|
||||
FreeTrigInfoChain(e->infos);
|
||||
free(e);
|
||||
@@ -1626,7 +1626,6 @@ static int WriteOneColLine(int col)
|
||||
CalColumn[col] = e->next;
|
||||
free(e->text);
|
||||
free(e->raw_text);
|
||||
free(e->filename);
|
||||
if (e->wc_text) free(e->wc_text);
|
||||
FreeTrigInfoChain(e->infos);
|
||||
free(e);
|
||||
@@ -1645,7 +1644,6 @@ static int WriteOneColLine(int col)
|
||||
PrintLeft("", ColSpaces, ' ');
|
||||
CalColumn[col] = e->next;
|
||||
free(e->text);
|
||||
free(e->filename);
|
||||
#ifdef REM_USE_WCHAR
|
||||
if (e->wc_text) free(e->wc_text);
|
||||
#endif
|
||||
@@ -1708,7 +1706,6 @@ static int WriteOneColLine(int col)
|
||||
if (!*s && !e->next) {
|
||||
CalColumn[col] = e->next;
|
||||
free(e->text);
|
||||
free(e->filename);
|
||||
#ifdef REM_USE_WCHAR
|
||||
if (e->wc_text) free(e->wc_text);
|
||||
#endif
|
||||
@@ -1809,6 +1806,18 @@ static void GenerateCalEntries(int col)
|
||||
break;
|
||||
case T_Pop: r=PopOmitContext(&p); break;
|
||||
case T_Push: r=PushOmitContext(&p); break;
|
||||
case T_PushVars:
|
||||
r=PushVars(&p);
|
||||
break;
|
||||
case T_PopVars:
|
||||
r=PopVars(&p);
|
||||
break;
|
||||
case T_PushFuncs:
|
||||
r=PushUserFuncs(&p);
|
||||
break;
|
||||
case T_PopFuncs:
|
||||
r=PopUserFuncs(&p);
|
||||
break;
|
||||
case T_Preserve: r=DoPreserve(&p); break;
|
||||
case T_Expr: r = DoExpr(&p); break;
|
||||
case T_Translate: r = DoTranslate(&p); break;
|
||||
@@ -2317,17 +2326,7 @@ static int DoCalRem(ParsePtr p, int col)
|
||||
FreeTrig(&trig);
|
||||
e->duration = tim.duration;
|
||||
e->priority = trig.priority;
|
||||
e->filename = StrDup(FileName);
|
||||
if(!e->filename) {
|
||||
FreeTrigInfoChain(e->infos);
|
||||
if (e->text) free(e->text);
|
||||
if (e->raw_text) free(e->raw_text);
|
||||
#ifdef REM_USE_WCHAR
|
||||
if (e->wc_text) free(e->wc_text);
|
||||
#endif
|
||||
free(e);
|
||||
return E_NO_MEM;
|
||||
}
|
||||
e->filename = GetCurrentFilename();
|
||||
e->lineno = LineNo;
|
||||
e->lineno_start = LineNoStart;
|
||||
|
||||
@@ -2356,7 +2355,7 @@ static int DoCalRem(ParsePtr p, int col)
|
||||
return OK;
|
||||
}
|
||||
|
||||
static void WriteSimpleEntryProtocol1(CalEntry *e)
|
||||
static void WriteSimpleEntryProtocol1(CalEntry const *e)
|
||||
{
|
||||
if (e->passthru[0]) {
|
||||
printf(" %s", e->passthru);
|
||||
@@ -2673,7 +2672,6 @@ static void WriteSimpleEntries(int col, int dse)
|
||||
|
||||
free(e->text);
|
||||
free(e->raw_text);
|
||||
free(e->filename);
|
||||
FreeTrigInfoChain(e->infos);
|
||||
#ifdef REM_USE_WCHAR
|
||||
if (e->wc_text) free(e->wc_text);
|
||||
@@ -2797,7 +2795,7 @@ static void WriteCalDays(void)
|
||||
/* This takes into account duration */
|
||||
/* */
|
||||
/***************************************************************/
|
||||
char const *
|
||||
static char const *
|
||||
CalendarTime(int tim, int duration)
|
||||
{
|
||||
static char buf[128];
|
||||
|
||||
12
src/dedupe.c
12
src/dedupe.c
@@ -28,9 +28,9 @@ typedef struct dedupe_entry {
|
||||
|
||||
static hash_table DedupeTable;
|
||||
|
||||
static unsigned int DedupeHashFunc(void *x)
|
||||
static unsigned int DedupeHashFunc(void const *x)
|
||||
{
|
||||
DedupeEntry *e = (DedupeEntry *) x;
|
||||
DedupeEntry const *e = (DedupeEntry const *) x;
|
||||
unsigned int hashval = (unsigned int) e->trigger_date;
|
||||
if (e->trigger_time != NO_TIME) {
|
||||
hashval += (unsigned int) e->trigger_time;
|
||||
@@ -39,10 +39,10 @@ static unsigned int DedupeHashFunc(void *x)
|
||||
return hashval;
|
||||
}
|
||||
|
||||
static int CompareDedupes(void *x, void *y)
|
||||
static int CompareDedupes(void const *x, void const *y)
|
||||
{
|
||||
DedupeEntry *a = (DedupeEntry *) x;
|
||||
DedupeEntry *b = (DedupeEntry *) y;
|
||||
DedupeEntry const *a = (DedupeEntry const *) x;
|
||||
DedupeEntry const *b = (DedupeEntry const *) y;
|
||||
if (a->trigger_date != b->trigger_date) return a->trigger_date - b->trigger_date;
|
||||
if (a->trigger_time != b->trigger_time) return a->trigger_time - b->trigger_time;
|
||||
return strcmp(a->body, b->body);
|
||||
@@ -122,7 +122,7 @@ InsertDedupeEntry(int trigger_date, int trigger_time, char const *body)
|
||||
int
|
||||
ShouldDedupe(int trigger_date, int trigger_time, char const *body)
|
||||
{
|
||||
DedupeEntry *e = FindDedupeEntry(trigger_date, trigger_time, body);
|
||||
DedupeEntry const *e = FindDedupeEntry(trigger_date, trigger_time, body);
|
||||
|
||||
if (e) {
|
||||
return 1;
|
||||
|
||||
16
src/dorem.c
16
src/dorem.c
@@ -29,8 +29,8 @@ static int ParseLocalOmit (ParsePtr s, Trigger *t);
|
||||
static int ParseScanFrom (ParsePtr s, Trigger *t, int type);
|
||||
static int ParsePriority (ParsePtr s, Trigger *t);
|
||||
static int ParseUntil (ParsePtr s, Trigger *t, int type);
|
||||
static int ShouldTriggerBasedOnWarn (Trigger *t, int dse, int *err);
|
||||
static int ComputeTrigDuration(TimeTrig *t);
|
||||
static int ShouldTriggerBasedOnWarn (Trigger const *t, int dse, int *err);
|
||||
static int ComputeTrigDuration(TimeTrig const *t);
|
||||
|
||||
static int
|
||||
ensure_expr_references_first_local_arg(expr_node *node)
|
||||
@@ -179,7 +179,7 @@ static void ensure_satnode_mentions_trigdate(expr_node *node)
|
||||
|
||||
|
||||
static int
|
||||
ComputeTrigDuration(TimeTrig *t)
|
||||
ComputeTrigDuration(TimeTrig const *t)
|
||||
{
|
||||
if (t->ttime == NO_TIME ||
|
||||
t->duration == NO_TIME) {
|
||||
@@ -1115,7 +1115,7 @@ static int ParseScanFrom(ParsePtr s, Trigger *t, int type)
|
||||
/* Trigger the reminder if it's a RUN or MSG type. */
|
||||
/* */
|
||||
/***************************************************************/
|
||||
int TriggerReminder(ParsePtr p, Trigger *t, TimeTrig *tim, int dse, int is_queued, DynamicBuffer *output)
|
||||
int TriggerReminder(ParsePtr p, Trigger *t, TimeTrig const *tim, int dse, int is_queued, DynamicBuffer *output)
|
||||
{
|
||||
int r, y, m, d;
|
||||
int adjusted_for_newline = 0;
|
||||
@@ -1427,7 +1427,7 @@ int TriggerReminder(ParsePtr p, Trigger *t, TimeTrig *tim, int dse, int is_queue
|
||||
/* triggered. Sets *err non-zero in event of an error. */
|
||||
/* */
|
||||
/***************************************************************/
|
||||
int ShouldTriggerReminder(Trigger *t, TimeTrig *tim, int dse, int *err)
|
||||
int ShouldTriggerReminder(Trigger const *t, TimeTrig const *tim, int dse, int *err)
|
||||
{
|
||||
int r, omit;
|
||||
*err = 0;
|
||||
@@ -1554,6 +1554,8 @@ int DoSatRemind(Trigger *trig, TimeTrig *tt, ParsePtr p)
|
||||
}
|
||||
if (dse == -1) {
|
||||
free_expr_tree(sat_node);
|
||||
LastTrigValid = 0;
|
||||
LastTriggerDate = -1;
|
||||
return E_EXPIRED;
|
||||
}
|
||||
r = evaluate_expression(sat_node, NULL, &v, &nonconst);
|
||||
@@ -1572,7 +1574,7 @@ int DoSatRemind(Trigger *trig, TimeTrig *tt, ParsePtr p)
|
||||
int y, m, d;
|
||||
FromDSE(LastTriggerDate, &y, &m, &d);
|
||||
fprintf(ErrFp, "%s(%s): Trig(satisfied) = %s, %d %s, %d",
|
||||
FileName, line_range(LineNoStart, LineNo),
|
||||
GetCurrentFilename(), line_range(LineNoStart, LineNo),
|
||||
get_day_name(LastTriggerDate % 7),
|
||||
d,
|
||||
get_month_name(m),
|
||||
@@ -1702,7 +1704,7 @@ finished:
|
||||
/* function. */
|
||||
/* */
|
||||
/***************************************************************/
|
||||
static int ShouldTriggerBasedOnWarn(Trigger *t, int dse, int *err)
|
||||
static int ShouldTriggerBasedOnWarn(Trigger const *t, int dse, int *err)
|
||||
{
|
||||
char buffer[VAR_NAME_LEN+32];
|
||||
int i;
|
||||
|
||||
@@ -54,7 +54,7 @@ check_subst_args(UserFunc *f, int n)
|
||||
/* If mode==ADVANCE_MODE, ignore %" but don't add newline */
|
||||
/* */
|
||||
/***************************************************************/
|
||||
int DoSubst(ParsePtr p, DynamicBuffer *dbuf, Trigger *t, TimeTrig *tt, int dse, int mode)
|
||||
int DoSubst(ParsePtr p, DynamicBuffer *dbuf, Trigger *t, TimeTrig const *tt, int dse, int mode)
|
||||
{
|
||||
int diff = dse - DSEToday;
|
||||
int curtime = MinutesPastMidnight(0);
|
||||
|
||||
24
src/err.h
24
src/err.h
@@ -23,25 +23,25 @@
|
||||
#define E_MISS_END 1
|
||||
#define E_MISS_QUOTE 2
|
||||
#define E_OP_STK_OVER 3
|
||||
/* #define E_VA_STK_OVER 4 */
|
||||
#define E_CANT_PARSE_MONTH 4
|
||||
#define E_MISS_RIGHT_PAREN 5
|
||||
#define E_UNDEF_FUNC 6
|
||||
#define E_ILLEGAL_CHAR 7
|
||||
/* #define E_EXPECTING_BINOP 8 */
|
||||
#define E_CANT_PARSE_WKDAY 8
|
||||
#define E_NO_MEM 9
|
||||
#define E_BAD_NUMBER 10
|
||||
/* #define E_OP_STK_UNDER 11 */
|
||||
/* #define E_VA_STK_UNDER 12 */
|
||||
#define E_PUSHV_NO_POP 11
|
||||
#define E_POPV_NO_PUSH 12
|
||||
#define E_CANT_COERCE 13
|
||||
#define E_BAD_TYPE 14
|
||||
#define E_DATE_OVER 15
|
||||
/* #define E_STACK_ERR 16 */
|
||||
#define E_POPF_NO_PUSH 16
|
||||
#define E_DIV_ZERO 17
|
||||
#define E_NOSUCH_VAR 18
|
||||
#define E_EOLN 19
|
||||
#define E_EOF 20
|
||||
#define E_IO_ERR 21
|
||||
/* #define E_LINE_2_LONG 22 */
|
||||
#define E_PUSHF_NO_POP 22
|
||||
#define E_SWERR 23
|
||||
#define E_BAD_DATE 24
|
||||
#define E_2FEW_ARGS 25
|
||||
@@ -151,25 +151,25 @@ EXTERN char *ErrMsg[]
|
||||
/* E_MISS_END */ "Missing ']'",
|
||||
/* E_MISS_QUOTE */ "Missing quote",
|
||||
/* E_OP_STK_OVER */ "Expression too complex",
|
||||
/* E_VA_STK_OVER */ "",
|
||||
/* E_CANT_PARSE_MONTH */ "Invalid month name",
|
||||
/* E_MISS_RIGHT_PAREN */ "Missing ')'",
|
||||
/* E_UNDEF_FUNC */ "Undefined function",
|
||||
/* E_ILLEGAL_CHAR */ "Illegal character",
|
||||
/* E_EXPECTING_BINOP */ "Expecting binary operator",
|
||||
/* E_CANT_PARSE_WKDAY*/ "Invalid weekday name",
|
||||
/* E_NO_MEM */ "Out of memory",
|
||||
/* E_BAD_NUMBER */ "Ill-formed number",
|
||||
/* E_OP_STK_UNDER */ "",
|
||||
/* E_VA_STK_UNDER */ "",
|
||||
/* E_PUSHV_NO_POP */ "Warning: PUSH-VARS without matching POP-VARS",
|
||||
/* E_POPV_NO_PUSH */ "POP-VARS without matching PUSH-VARS",
|
||||
/* E_CANT_COERCE */ "Can't coerce",
|
||||
/* E_BAD_TYPE */ "Type mismatch",
|
||||
/* E_DATE_OVER */ "Date overflow",
|
||||
/* E_STACK_ERR */ "",
|
||||
/* E_POPF_NO_PUSH */ "POP-FUNCS without matching PUSH-FUNCS",
|
||||
/* E_DIV_ZERO */ "Division by zero",
|
||||
/* E_NOSUCH_VAR */ "Undefined variable",
|
||||
/* E_EOLN */ "Unexpected end of line",
|
||||
/* E_EOF */ "Unexpected end of file",
|
||||
/* E_IO_ERR */ "I/O error",
|
||||
/* E_LINE_2_LONG */ "",
|
||||
/* E_PUSHF_NO_POP */ "Warning: PUSH-FUNCS without matching POP-FUNCS",
|
||||
/* E_SWERR */ "Internal error",
|
||||
/* E_BAD_DATE */ "Bad date specification",
|
||||
/* E_2FEW_ARGS */ "Not enough arguments",
|
||||
|
||||
91
src/expr.c
91
src/expr.c
@@ -191,6 +191,7 @@ static int ExprNodesUsed = 0;
|
||||
/* Forward references */
|
||||
static expr_node * parse_expression_aux(char const **e, int *r, Var *locals, int level);
|
||||
static char const *get_operator_name(expr_node *node);
|
||||
static void print_expr_tree(expr_node *node, FILE *fp);
|
||||
|
||||
/* This is super-skanky... we keep track of the currently-executing
|
||||
user-defined function in a global var */
|
||||
@@ -425,7 +426,8 @@ get_var(expr_node *node, Value *ans, int *nonconst)
|
||||
Eprint("%s: `%s'", GetErr(E_NOSUCH_VAR), str);
|
||||
return E_NOSUCH_VAR;
|
||||
}
|
||||
if (v->nonconstant) {
|
||||
v->used_since_set = 1;
|
||||
if (!v->is_constant) {
|
||||
nonconst_debug(*nonconst, tr("Global variable `%s' makes expression non-constant"), str);
|
||||
*nonconst = 1;
|
||||
}
|
||||
@@ -442,7 +444,7 @@ get_var(expr_node *node, Value *ans, int *nonconst)
|
||||
/* */
|
||||
/***************************************************************/
|
||||
static int
|
||||
get_sysvar(expr_node *node, Value *ans)
|
||||
get_sysvar(expr_node const *node, Value *ans)
|
||||
{
|
||||
if (node->type == N_SHORT_SYSVAR) {
|
||||
return GetSysVar(node->u.name, ans);
|
||||
@@ -568,6 +570,13 @@ eval_builtin(expr_node *node, Value *locals, Value *ans, int *nonconst)
|
||||
/* All went well; copy the result destructively */
|
||||
(*ans) = info.retval;
|
||||
|
||||
/* Special case of const cunction */
|
||||
if (!strcmp(f->name, "const")) {
|
||||
if (*nonconst) {
|
||||
nonconst_debug(0, tr("Non-constant expression converted to constant by `const' built-in function"));
|
||||
}
|
||||
*nonconst = 0;
|
||||
}
|
||||
/* Don't allow retval to be destroyed! */
|
||||
info.retval.type = ERR_TYPE;
|
||||
}
|
||||
@@ -825,7 +834,7 @@ evaluate_expression(expr_node *node, Value *locals, Value *ans, int *nonconst)
|
||||
return r;
|
||||
}
|
||||
|
||||
static int CopyShortStr(Value *ans, expr_node *node)
|
||||
static int CopyShortStr(Value *ans, expr_node const *node)
|
||||
{
|
||||
size_t len = strlen(node->u.name);
|
||||
ans->v.str = malloc(len+1);
|
||||
@@ -1827,6 +1836,78 @@ expr_node * free_expr_tree(expr_node *node)
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/***************************************************************/
|
||||
/* */
|
||||
/* clone_expr_tree */
|
||||
/* */
|
||||
/* Clone an entire expr_tree. The clone shares no memory */
|
||||
/* with the original. Returns NULL and sets *r on failure. */
|
||||
/* */
|
||||
/***************************************************************/
|
||||
expr_node * clone_expr_tree(expr_node const *src, int *r)
|
||||
{
|
||||
int rc;
|
||||
expr_node *dest = alloc_expr_node(r);
|
||||
if (!dest) return NULL;
|
||||
|
||||
dest->type = src->type;
|
||||
dest->num_kids = src->num_kids;
|
||||
switch(dest->type) {
|
||||
case N_FREE:
|
||||
case N_ERROR:
|
||||
*r = E_SWERR;
|
||||
free_expr_tree(dest);
|
||||
return NULL;
|
||||
|
||||
case N_CONSTANT:
|
||||
case N_VARIABLE:
|
||||
case N_SYSVAR:
|
||||
case N_USER_FUNC:
|
||||
rc = CopyValue(&(dest->u.value), &(src->u.value));
|
||||
if (rc != OK) {
|
||||
*r = rc;
|
||||
free_expr_tree(dest);
|
||||
return NULL;
|
||||
}
|
||||
break;
|
||||
|
||||
case N_SHORT_STR:
|
||||
case N_SHORT_VAR:
|
||||
case N_SHORT_SYSVAR:
|
||||
case N_SHORT_USER_FUNC:
|
||||
strcpy(dest->u.name, src->u.name);
|
||||
break;
|
||||
|
||||
case N_LOCAL_VAR:
|
||||
dest->u.arg = src->u.arg;
|
||||
break;
|
||||
|
||||
case N_BUILTIN_FUNC:
|
||||
dest->u.builtin_func = src->u.builtin_func;
|
||||
break;
|
||||
|
||||
case N_OPERATOR:
|
||||
dest->u.operator_func = src->u.operator_func;
|
||||
break;
|
||||
}
|
||||
|
||||
if (src->child) {
|
||||
dest->child = clone_expr_tree(src->child, r);
|
||||
if (!dest->child) {
|
||||
free_expr_tree(dest);
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
if (src->sibling) {
|
||||
dest->sibling = clone_expr_tree(src->sibling, r);
|
||||
if (!dest->sibling) {
|
||||
free_expr_tree(dest);
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
return dest;
|
||||
}
|
||||
|
||||
/***************************************************************/
|
||||
/* */
|
||||
/* set_long_name - set a long name in an expr_node */
|
||||
@@ -2704,7 +2785,7 @@ static void print_kids(expr_node *node, FILE *fp)
|
||||
/* file. Used for debugging (the "-ds" flag.) */
|
||||
/* */
|
||||
/***************************************************************/
|
||||
void print_expr_tree(expr_node *node, FILE *fp)
|
||||
static void print_expr_tree(expr_node *node, FILE *fp)
|
||||
{
|
||||
if (!node) {
|
||||
return;
|
||||
@@ -2953,7 +3034,7 @@ int CopyValue(Value *dest, const Value *src)
|
||||
/* 4:00PM */
|
||||
/* */
|
||||
/***************************************************************/
|
||||
int ParseLiteralTime(char const **s, int *tim)
|
||||
static int ParseLiteralTime(char const **s, int *tim)
|
||||
{
|
||||
int h=0;
|
||||
int m=0;
|
||||
|
||||
104
src/files.c
104
src/files.c
@@ -20,6 +20,7 @@
|
||||
#include <errno.h>
|
||||
#include <ctype.h>
|
||||
#include <sys/stat.h>
|
||||
#include <stddef.h>
|
||||
|
||||
#ifdef TM_IN_SYS_TIME
|
||||
#include <sys/time.h>
|
||||
@@ -85,10 +86,21 @@ typedef struct {
|
||||
int ownedByMe;
|
||||
} IncludeStruct;
|
||||
|
||||
typedef struct fn_entry {
|
||||
struct hash_link link;
|
||||
char const *fname;
|
||||
} FilenameHashEntry;
|
||||
|
||||
/* A hash table to hold unique copies of all the filenames we process */
|
||||
static hash_table FilenameHashTable;
|
||||
|
||||
static CachedFile *CachedFiles = (CachedFile *) NULL;
|
||||
static CachedLine *CLine = (CachedLine *) NULL;
|
||||
static DirectoryFilenameChain *CachedDirectoryChains = NULL;
|
||||
|
||||
/* Current filename */
|
||||
static char const *FileName = NULL;
|
||||
|
||||
static FILE *fp;
|
||||
|
||||
static IncludeStruct IStack[INCLUDE_NEST];
|
||||
@@ -102,6 +114,64 @@ static int CheckSafetyAux (struct stat *statbuf);
|
||||
static int PopFile (void);
|
||||
static int IncludeCmd(char const *);
|
||||
|
||||
static unsigned int FnHashFunc(void const *x)
|
||||
{
|
||||
FilenameHashEntry const *e = (FilenameHashEntry const *) x;
|
||||
return HashVal_preservecase(e->fname);
|
||||
}
|
||||
|
||||
static int FnCompareFunc(void const *a, void const *b)
|
||||
{
|
||||
FilenameHashEntry const *e1 = (FilenameHashEntry const *) a;
|
||||
FilenameHashEntry const *e2 = (FilenameHashEntry const *) b;
|
||||
return strcmp(e1->fname, e2->fname);
|
||||
}
|
||||
|
||||
void InitFiles(void)
|
||||
{
|
||||
if (hash_table_init(&FilenameHashTable, offsetof(FilenameHashEntry, link),
|
||||
FnHashFunc, FnCompareFunc) < 0) {
|
||||
fprintf(ErrFp, "Unable to initialize filename hash table: Out of memory. Exiting.\n");
|
||||
exit(1);
|
||||
}
|
||||
}
|
||||
|
||||
void SetCurrentFilename(char const *fname)
|
||||
{
|
||||
FilenameHashEntry *e;
|
||||
FilenameHashEntry candidate;
|
||||
candidate.fname = fname;
|
||||
|
||||
e = (FilenameHashEntry *) hash_table_find(&FilenameHashTable, &candidate);
|
||||
if (!e) {
|
||||
e = NEW(FilenameHashEntry);
|
||||
if (!e) {
|
||||
fprintf(ErrFp, "Out of Memory!\n");
|
||||
exit(1);
|
||||
}
|
||||
e->fname = strdup(fname);
|
||||
if (!e->fname) {
|
||||
fprintf(ErrFp, "Out of Memory!\n");
|
||||
exit(1);
|
||||
}
|
||||
hash_table_insert(&FilenameHashTable, e);
|
||||
}
|
||||
FileName = e->fname;
|
||||
}
|
||||
|
||||
char const *GetCurrentFilename(void)
|
||||
{
|
||||
if (FileName) {
|
||||
if (!strcmp(FileName, "-")) {
|
||||
return "-stdin-";
|
||||
} else {
|
||||
return FileName;
|
||||
}
|
||||
} else {
|
||||
return "";
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
got_a_fresh_line(void)
|
||||
{
|
||||
@@ -109,7 +179,7 @@ got_a_fresh_line(void)
|
||||
WarnedAboutImplicit = 0;
|
||||
}
|
||||
|
||||
void set_cloexec(FILE *fp)
|
||||
static void set_cloexec(FILE *fp)
|
||||
{
|
||||
int flags;
|
||||
int fd;
|
||||
@@ -311,7 +381,7 @@ static int ReadLineFromFile(int use_pclose)
|
||||
/* ShouldCache is 1, cache the file */
|
||||
/* */
|
||||
/***************************************************************/
|
||||
int OpenFile(char const *fname)
|
||||
static int OpenFile(char const *fname)
|
||||
{
|
||||
CachedFile *h = CachedFiles;
|
||||
int r;
|
||||
@@ -332,7 +402,7 @@ int OpenFile(char const *fname)
|
||||
fprintf(ErrFp, "\n");
|
||||
}
|
||||
CLine = h->cache;
|
||||
STRSET(FileName, fname);
|
||||
SetCurrentFilename(fname);
|
||||
LineNo = 0;
|
||||
LineNoStart = 0;
|
||||
if (!h->ownedByMe) {
|
||||
@@ -387,7 +457,7 @@ int OpenFile(char const *fname)
|
||||
}
|
||||
}
|
||||
}
|
||||
STRSET(FileName, fname);
|
||||
SetCurrentFilename(fname);
|
||||
LineNo = 0;
|
||||
LineNoStart = 0;
|
||||
if (FileName) return OK; else return E_NO_MEM;
|
||||
@@ -569,7 +639,7 @@ static int PopFile(void)
|
||||
set_base_if_pointer(i->base_if_pointer);
|
||||
CLine = i->CLine;
|
||||
fp = NULL;
|
||||
STRSET(FileName, i->filename);
|
||||
SetCurrentFilename(i->filename);
|
||||
if (!i->ownedByMe) {
|
||||
RunDisabled |= RUN_NOTOWNER;
|
||||
} else {
|
||||
@@ -589,7 +659,6 @@ static int PopFile(void)
|
||||
if (fp != stdin)
|
||||
(void) fseek(fp, i->offset, 0); /* Trust that it works... */
|
||||
}
|
||||
free((char *) i->filename);
|
||||
return OK;
|
||||
}
|
||||
|
||||
@@ -894,15 +963,7 @@ static int IncludeCmd(char const *cmd)
|
||||
}
|
||||
fname = DBufValue(&buf);
|
||||
|
||||
if (FileName) {
|
||||
i->filename = StrDup(FileName);
|
||||
if (!i->filename) {
|
||||
DBufFree(&buf);
|
||||
return E_NO_MEM;
|
||||
}
|
||||
} else {
|
||||
i->filename = NULL;
|
||||
}
|
||||
i->filename = FileName;
|
||||
i->ownedByMe = 1;
|
||||
i->LineNo = LineNo;
|
||||
i->LineNoStart = LineNo;
|
||||
@@ -927,7 +988,7 @@ static int IncludeCmd(char const *cmd)
|
||||
fprintf(ErrFp, "\n");
|
||||
}
|
||||
CLine = h->cache;
|
||||
STRSET(FileName, fname);
|
||||
SetCurrentFilename(fname);
|
||||
DBufFree(&buf);
|
||||
LineNo = 0;
|
||||
LineNoStart = 0;
|
||||
@@ -979,7 +1040,7 @@ static int IncludeCmd(char const *cmd)
|
||||
CLine = CachedFiles->cache;
|
||||
LineNo = 0;
|
||||
LineNoStart = 0;
|
||||
STRSET(FileName, fname);
|
||||
SetCurrentFilename(fname);
|
||||
DBufFree(&buf);
|
||||
return OK;
|
||||
}
|
||||
@@ -1008,12 +1069,7 @@ int IncludeFile(char const *fname)
|
||||
if (IStackPtr >= INCLUDE_NEST) return E_NESTED_INCLUDE;
|
||||
i = &IStack[IStackPtr];
|
||||
|
||||
if (FileName) {
|
||||
i->filename = StrDup(FileName);
|
||||
if (!i->filename) return E_NO_MEM;
|
||||
} else {
|
||||
i->filename = NULL;
|
||||
}
|
||||
i->filename = FileName;
|
||||
i->LineNo = LineNo;
|
||||
i->LineNoStart = LineNoStart;
|
||||
i->base_if_pointer = get_base_if_pointer();
|
||||
@@ -1095,7 +1151,7 @@ int IncludeFile(char const *fname)
|
||||
int GetAccessDate(char const *file)
|
||||
{
|
||||
struct stat statbuf;
|
||||
struct tm *t1;
|
||||
struct tm const *t1;
|
||||
|
||||
if (stat(file, &statbuf)) return -1;
|
||||
t1 = localtime(&(statbuf.st_atime));
|
||||
|
||||
262
src/funcs.c
262
src/funcs.c
@@ -59,7 +59,9 @@
|
||||
#define Nargs (info->nargs)
|
||||
#define RetVal (info->retval)
|
||||
|
||||
#define DBG(x) do { if (DebugFlag & DB_PRTEXPR) { x; } } while(0)
|
||||
#define DBGX (DebugFlag & DB_PRTEXPR)
|
||||
|
||||
#define DBG(x) do { if (DBGX) { x; } } while(0)
|
||||
/* Debugging helpers for "choose()", "iif(), etc. */
|
||||
#define PUT(x) DBufPuts(&DebugBuf, x)
|
||||
#define OUT() do { fprintf(ErrFp, "%s\n", DBufValue(&DebugBuf)); DBufFree(&DebugBuf); } while(0)
|
||||
@@ -193,7 +195,7 @@ static int FTypeof (func_info *);
|
||||
static int FTzconvert (func_info *);
|
||||
static int FUTCToLocal (func_info *);
|
||||
static int FUpper (func_info *);
|
||||
static int FValue (func_info *);
|
||||
static int FValue (expr_node *, Value *, Value *, int *);
|
||||
static int FVersion (func_info *);
|
||||
static int FWeekno (func_info *);
|
||||
static int FWkday (func_info *);
|
||||
@@ -229,8 +231,10 @@ static int CacheHebYear, CacheHebMon, CacheHebDay;
|
||||
#define HASDATE(x) ((x).type & DATE_TYPE)
|
||||
#define HASTIME(x) ((x).type & TIME_TYPE)
|
||||
|
||||
#define GETMON(x) get_month(&(ARG(x)))
|
||||
|
||||
/* Macro for copying a value while destroying original copy */
|
||||
#define DCOPYVAL(x, y) ( (x) = (y), (y).type = ERR_TYPE )
|
||||
#define DCOPYVAL(x, y) ( (x) = (y), (y).type = ERR_TYPE, (y).v.val = 0 )
|
||||
|
||||
/* Get at RetVal.v.val easily */
|
||||
#define RETVAL info->retval.v.val
|
||||
@@ -258,13 +262,14 @@ BuiltinFunc Func[] = {
|
||||
{ "choose", 2, NO_MAX, 1, NULL, FChoose }, /*NEW-STYLE*/
|
||||
{ "coerce", 2, 2, 1, FCoerce, NULL },
|
||||
{ "columns", 0, 1, 0, FColumns, NULL },
|
||||
{ "const", 1, 1, 1, FNonconst, NULL },
|
||||
{ "current", 0, 0, 0, FCurrent, NULL },
|
||||
{ "date", 3, 3, 1, FDate, NULL },
|
||||
{ "datepart", 1, 1, 1, FDatepart, NULL },
|
||||
{ "datetime", 2, 5, 1, FDateTime, NULL },
|
||||
{ "dawn", 0, 1, 0, FDawn, NULL },
|
||||
{ "day", 1, 1, 1, FDay, NULL },
|
||||
{ "daysinmon", 2, 2, 1, FDaysinmon, NULL },
|
||||
{ "daysinmon", 1, 2, 1, FDaysinmon, NULL },
|
||||
{ "defined", 1, 1, 0, FDefined, NULL },
|
||||
{ "dosubst", 1, 3, 0, FDosubst, NULL },
|
||||
{ "dusk", 0, 1, 0, FDusk, NULL },
|
||||
@@ -364,7 +369,7 @@ BuiltinFunc Func[] = {
|
||||
{ "tzconvert", 2, 3, 0, FTzconvert, NULL },
|
||||
{ "upper", 1, 1, 1, FUpper, NULL },
|
||||
{ "utctolocal", 1, 1, 1, FUTCToLocal, NULL },
|
||||
{ "value", 1, 2, 0, FValue, NULL },
|
||||
{ "value", 1, 2, 1, NULL, FValue }, /* NEW-STYLE */
|
||||
{ "version", 0, 0, 1, FVersion, NULL },
|
||||
{ "weekno", 0, 3, 0, FWeekno, NULL },
|
||||
{ "wkday", 1, 1, 1, FWkday, NULL },
|
||||
@@ -375,6 +380,26 @@ BuiltinFunc Func[] = {
|
||||
/* Need a variable here - Func[] array not really visible to outside. */
|
||||
int NumFuncs = sizeof(Func) / sizeof(BuiltinFunc) ;
|
||||
|
||||
static int get_month(Value *v)
|
||||
{
|
||||
Token tok;
|
||||
|
||||
if (v->type == INT_TYPE) {
|
||||
if (v->v.val < 1) return -E_2LOW;
|
||||
if (v->v.val > 12) return -E_2HIGH;
|
||||
return v->v.val - 1;
|
||||
}
|
||||
if (v->type == STR_TYPE) {
|
||||
FindToken(v->v.str, &tok);
|
||||
if (tok.type != T_Month) {
|
||||
return -E_CANT_PARSE_MONTH;
|
||||
}
|
||||
return tok.val;
|
||||
}
|
||||
return -E_BAD_TYPE;
|
||||
}
|
||||
|
||||
|
||||
/***************************************************************/
|
||||
/* */
|
||||
/* RetStrVal */
|
||||
@@ -460,29 +485,27 @@ static int FBaseyr(func_info *info)
|
||||
static int FDate(func_info *info)
|
||||
{
|
||||
int y, m, d;
|
||||
int ytemp, mtemp, dtemp;
|
||||
|
||||
/* Any arg can be a date (in which case we use the corresponding
|
||||
component) or an integer */
|
||||
if (HASDATE(ARG(0))) {
|
||||
FromDSE(DATEPART(ARG(0)), &ytemp, &mtemp, &dtemp);
|
||||
y = ytemp;
|
||||
FromDSE(DATEPART(ARG(0)), &y, NULL, NULL);
|
||||
} else {
|
||||
ASSERT_TYPE(0, INT_TYPE);
|
||||
y = ARGV(0);
|
||||
}
|
||||
|
||||
if (HASDATE(ARG(1))) {
|
||||
FromDSE(DATEPART(ARG(1)), &ytemp, &mtemp, &dtemp);
|
||||
m = mtemp;
|
||||
FromDSE(DATEPART(ARG(1)), NULL, &m, NULL);
|
||||
} else {
|
||||
ASSERT_TYPE(1, INT_TYPE);
|
||||
m = ARGV(1) - 1;
|
||||
m = GETMON(1);
|
||||
if (m < 0) {
|
||||
return -m;
|
||||
}
|
||||
}
|
||||
|
||||
if (HASDATE(ARG(2))) {
|
||||
FromDSE(DATEPART(ARG(2)), &ytemp, &mtemp, &dtemp);
|
||||
d = dtemp;
|
||||
FromDSE(DATEPART(ARG(2)), NULL, NULL, &d);
|
||||
} else {
|
||||
ASSERT_TYPE(2, INT_TYPE);
|
||||
d = ARGV(2);
|
||||
@@ -527,11 +550,11 @@ static int FDateTime(func_info *info)
|
||||
return OK;
|
||||
case 4:
|
||||
if (ARG(0).type != INT_TYPE ||
|
||||
ARG(1).type != INT_TYPE ||
|
||||
ARG(2).type != INT_TYPE ||
|
||||
ARG(3).type != TIME_TYPE) return E_BAD_TYPE;
|
||||
y = ARGV(0);
|
||||
m = ARGV(1) - 1;
|
||||
m = GETMON(1);
|
||||
if (m < 0) return -m;
|
||||
d = ARGV(2);
|
||||
|
||||
if (!DateOK(y, m, d)) return E_BAD_DATE;
|
||||
@@ -539,13 +562,13 @@ static int FDateTime(func_info *info)
|
||||
return OK;
|
||||
case 5:
|
||||
if (ARG(0).type != INT_TYPE ||
|
||||
ARG(1).type != INT_TYPE ||
|
||||
ARG(2).type != INT_TYPE ||
|
||||
ARG(3).type != INT_TYPE ||
|
||||
ARG(4).type != INT_TYPE) return E_BAD_TYPE;
|
||||
|
||||
y = ARGV(0);
|
||||
m = ARGV(1) - 1;
|
||||
m = GETMON(1);
|
||||
if (m < 0) return -m;
|
||||
d = ARGV(2);
|
||||
if (!DateOK(y, m, d)) return E_BAD_DATE;
|
||||
|
||||
@@ -756,7 +779,7 @@ static int FMonnum(func_info *info)
|
||||
/* Convert a month name to a month number */
|
||||
FindToken(ARG(0).v.str, &tok);
|
||||
if (tok.type != T_Month) {
|
||||
return E_BAD_TYPE;
|
||||
return E_CANT_PARSE_MONTH;
|
||||
}
|
||||
RetVal.type = INT_TYPE;
|
||||
RETVAL = tok.val + 1;
|
||||
@@ -808,7 +831,7 @@ static int FWkdaynum(func_info *info)
|
||||
/* Convert a day name to a day number */
|
||||
FindToken(ARG(0).v.str, &tok);
|
||||
if (tok.type != T_WkDay) {
|
||||
return E_BAD_TYPE;
|
||||
return E_CANT_PARSE_WKDAY;
|
||||
}
|
||||
RetVal.type = INT_TYPE;
|
||||
RETVAL = (tok.val + 1) % 7;
|
||||
@@ -845,12 +868,11 @@ static int FMon(func_info *info)
|
||||
char const *s;
|
||||
int y, m, d, v;
|
||||
|
||||
if (!HASDATE(ARG(0)) && ARG(0).type != INT_TYPE) return E_BAD_TYPE;
|
||||
if (!HASDATE(ARG(0)) && ARG(0).type != INT_TYPE && ARG(0).type != STR_TYPE) return E_BAD_TYPE;
|
||||
|
||||
if (ARG(0).type == INT_TYPE) {
|
||||
m = ARGV(0) - 1;
|
||||
if (m < 0) return E_2LOW;
|
||||
if (m > 11) return E_2HIGH;
|
||||
if (ARG(0).type == INT_TYPE || ARG(0).type == STR_TYPE) {
|
||||
m = GETMON(0);
|
||||
if (m < 0) return -m;
|
||||
} else {
|
||||
v = DATEPART(ARG(0));
|
||||
if (v == CacheDse)
|
||||
@@ -1162,7 +1184,7 @@ static int FOrd(func_info *info)
|
||||
static int FPad(func_info *info)
|
||||
{
|
||||
int r;
|
||||
char *s;
|
||||
char const *s;
|
||||
DynamicBuffer dbuf;
|
||||
size_t len;
|
||||
size_t wantlen;
|
||||
@@ -1298,7 +1320,7 @@ static int FIsconst(expr_node *node, Value *locals, Value *ans, int *nonconst)
|
||||
ans->type = INT_TYPE;
|
||||
ans->v.val = (my_nonconst ? 0 : 1);
|
||||
DBG(PUT(PrintValue(&junk, NULL)));
|
||||
if (DebugFlag & DB_PRTEXPR) {
|
||||
if (DBGX) {
|
||||
PUT(") => ");
|
||||
PUT(PrintValue(ans, NULL));
|
||||
OUT();
|
||||
@@ -1365,7 +1387,7 @@ static int FIsAny(expr_node *node, Value *locals, Value *ans, int *nonconst)
|
||||
break;
|
||||
}
|
||||
DestroyValue(v);
|
||||
if (DebugFlag & DB_PRTEXPR) {
|
||||
if (DBGX) {
|
||||
while(cur->sibling) {
|
||||
cur = cur->sibling;
|
||||
PUT(", ?");
|
||||
@@ -1402,7 +1424,7 @@ static int FCatch(expr_node *node, Value *locals, Value *ans, int *nonconst)
|
||||
SuppressErrorOutputInCatch = old_suppress;
|
||||
|
||||
if (r == OK) {
|
||||
if (DebugFlag & DB_PRTEXPR) {
|
||||
if (DBGX) {
|
||||
PUT(PrintValue(ans, NULL));
|
||||
PUT(", ?) => ");
|
||||
PUT(PrintValue(ans, NULL));
|
||||
@@ -1413,14 +1435,14 @@ static int FCatch(expr_node *node, Value *locals, Value *ans, int *nonconst)
|
||||
|
||||
/* Save the catch error */
|
||||
LastCatchError = r;
|
||||
if (DebugFlag & DB_PRTEXPR) {
|
||||
if (DBGX) {
|
||||
PUT("*");
|
||||
PUT(GetErr(r));
|
||||
PUT("*, ");
|
||||
}
|
||||
r = evaluate_expr_node(cur->sibling, locals, ans, nonconst);
|
||||
if (r == OK) {
|
||||
if (DebugFlag & DB_PRTEXPR) {
|
||||
if (DBGX) {
|
||||
PUT(PrintValue(ans, NULL));
|
||||
PUT(") => ");
|
||||
PUT(PrintValue(ans, NULL));
|
||||
@@ -1428,7 +1450,7 @@ static int FCatch(expr_node *node, Value *locals, Value *ans, int *nonconst)
|
||||
}
|
||||
return r;
|
||||
}
|
||||
if (DebugFlag & DB_PRTEXPR) {
|
||||
if (DBGX) {
|
||||
PUT("*");
|
||||
PUT(GetErr(r));
|
||||
PUT("*) => ");
|
||||
@@ -1477,7 +1499,7 @@ static int FChoose(expr_node *node, Value *locals, Value *ans, int *nonconst)
|
||||
}
|
||||
DBG(PUT(PrintValue(&v, NULL)));
|
||||
if (v.type != INT_TYPE) {
|
||||
if (DebugFlag & DB_PRTEXPR) {
|
||||
if (DBGX) {
|
||||
cur = cur->sibling;
|
||||
while(cur) {
|
||||
PUT(", ?");
|
||||
@@ -1487,6 +1509,7 @@ static int FChoose(expr_node *node, Value *locals, Value *ans, int *nonconst)
|
||||
PUT(GetErr(E_BAD_TYPE));
|
||||
OUT();
|
||||
}
|
||||
DestroyValue(v);
|
||||
Eprint("choose(): %s", GetErr(E_BAD_TYPE));
|
||||
return E_BAD_TYPE;
|
||||
}
|
||||
@@ -1504,7 +1527,7 @@ static int FChoose(expr_node *node, Value *locals, Value *ans, int *nonconst)
|
||||
DBG(DBufFree(&DebugBuf));
|
||||
return r;
|
||||
}
|
||||
if (DebugFlag & DB_PRTEXPR) {
|
||||
if (DBGX) {
|
||||
PUT(", ");
|
||||
PUT(PrintValue(ans, NULL));
|
||||
cur = cur->sibling;
|
||||
@@ -1694,25 +1717,92 @@ static int FGetenv(func_info *info)
|
||||
/* it is returned if variable is undefined. */
|
||||
/* */
|
||||
/***************************************************************/
|
||||
static int FValue(func_info *info)
|
||||
static int FValue(expr_node *node, Value *locals, Value *ans, int *nonconst)
|
||||
{
|
||||
DynamicBuffer DebugBuf;
|
||||
expr_node *cur;
|
||||
int r;
|
||||
Value varname;
|
||||
Var *v;
|
||||
|
||||
ASSERT_TYPE(0, STR_TYPE);
|
||||
switch(Nargs) {
|
||||
case 1:
|
||||
return GetVarValue(ARGSTR(0), &RetVal);
|
||||
DBG(DBufInit(&DebugBuf));
|
||||
|
||||
case 2:
|
||||
v = FindVar(ARGSTR(0), 0);
|
||||
if (!v) {
|
||||
DCOPYVAL(RetVal, ARG(1));
|
||||
return OK;
|
||||
} else {
|
||||
return CopyValue(&RetVal, &v->v);
|
||||
cur = node->child;
|
||||
r = evaluate_expr_node(cur, locals, &varname, nonconst);
|
||||
if (r != OK) {
|
||||
DBG(DBufFree(&DebugBuf));
|
||||
return r;
|
||||
}
|
||||
|
||||
DBG(PUT("value("));
|
||||
DBG(PUT(PrintValue(&varname, NULL)));
|
||||
if (node->num_kids == 1) {
|
||||
DBG(PUT(") => "));
|
||||
} else {
|
||||
DBG(PUT(", "));
|
||||
}
|
||||
if (varname.type != STR_TYPE) {
|
||||
if (DBGX) {
|
||||
if (node->num_kids == 2) {
|
||||
PUT("?) => ");
|
||||
}
|
||||
PUT(GetErr(E_BAD_TYPE));
|
||||
OUT();
|
||||
}
|
||||
DestroyValue(varname);
|
||||
return E_BAD_TYPE;
|
||||
}
|
||||
|
||||
v = FindVar(varname.v.str, 0);
|
||||
if (!v) {
|
||||
r = E_NOSUCH_VAR;
|
||||
} else {
|
||||
r = OK;
|
||||
v->used_since_set = 1;
|
||||
CopyValue(ans, &v->v);
|
||||
if (!v->is_constant) {
|
||||
nonconst_debug(*nonconst, tr("Global variable `%s' makes expression non-constant"), varname.v.str);
|
||||
*nonconst = 1;
|
||||
}
|
||||
}
|
||||
return OK;
|
||||
if (r == OK || node->num_kids == 1) {
|
||||
DestroyValue(varname);
|
||||
if (DBGX) {
|
||||
if (node->num_kids == 2) {
|
||||
PUT("?) => ");
|
||||
}
|
||||
if (r != OK) {
|
||||
PUT(GetErr(r));
|
||||
} else {
|
||||
PUT(PrintValue(ans, NULL));
|
||||
}
|
||||
OUT();
|
||||
}
|
||||
return r;
|
||||
}
|
||||
|
||||
/* Variable does not exist. We have to mark the result of value()
|
||||
as non-constant because the nonexistence of a variable may depend
|
||||
on today's date (for example) */
|
||||
nonconst_debug(*nonconst, tr("Nonexistence of global variable `%s' makes value() non-constant"), varname.v.str);
|
||||
DestroyValue(varname);
|
||||
*nonconst = 1;
|
||||
r = evaluate_expr_node(cur->sibling, locals, ans, nonconst);
|
||||
if (DBGX) {
|
||||
if (node->num_kids == 2) {
|
||||
if (r != OK) {
|
||||
PUT(GetErr(r));
|
||||
PUT(") => ");
|
||||
PUT(GetErr(r));
|
||||
} else {
|
||||
PUT(PrintValue(ans, NULL));
|
||||
PUT(") => ");
|
||||
PUT(PrintValue(ans, NULL));
|
||||
}
|
||||
OUT();
|
||||
}
|
||||
}
|
||||
return r;
|
||||
}
|
||||
|
||||
/***************************************************************/
|
||||
@@ -1937,19 +2027,29 @@ static int FTrigdatetime(func_info *info)
|
||||
/* */
|
||||
/* FDaysinmon */
|
||||
/* */
|
||||
/* Returns the number of days in mon,yr */
|
||||
/* Returns the number of days in mon,yr OR month containing */
|
||||
/* given date. */
|
||||
/* */
|
||||
/***************************************************************/
|
||||
static int FDaysinmon(func_info *info)
|
||||
{
|
||||
if (ARG(0).type != INT_TYPE || ARG(1).type != INT_TYPE) return E_BAD_TYPE;
|
||||
int y, m;
|
||||
|
||||
if (ARGV(0) > 12 || ARGV(0) < 1 ||
|
||||
ARGV(1) < BASE || ARGV(1) > BASE+YR_RANGE)
|
||||
return E_DOMAIN_ERR;
|
||||
if (Nargs == 1) {
|
||||
if (!HASDATE(ARG(0))) return E_BAD_TYPE;
|
||||
FromDSE(DATEPART(ARG(0)), &y, &m, NULL);
|
||||
} else {
|
||||
if (ARG(1).type != INT_TYPE) return E_BAD_TYPE;
|
||||
|
||||
m = GETMON(0);
|
||||
if (m < 0) return -m;
|
||||
y = ARGV(1);
|
||||
if (y < BASE) return E_2LOW;
|
||||
if (y > BASE + YR_RANGE) return E_2HIGH;
|
||||
}
|
||||
|
||||
RetVal.type = INT_TYPE;
|
||||
RETVAL = DaysInMonth(ARGV(0)-1, ARGV(1));
|
||||
RETVAL = DaysInMonth(m, y);
|
||||
return OK;
|
||||
}
|
||||
|
||||
@@ -1962,13 +2062,13 @@ static int FDaysinmon(func_info *info)
|
||||
/***************************************************************/
|
||||
static int FIsleap(func_info *info)
|
||||
{
|
||||
int y, m, d;
|
||||
int y;
|
||||
|
||||
if (ARG(0).type != INT_TYPE && !HASDATE(ARG(0))) return E_BAD_TYPE;
|
||||
|
||||
/* If it's a date, extract the year */
|
||||
if (HASDATE(ARG(0)))
|
||||
FromDSE(DATEPART(ARG(0)), &y, &m, &d);
|
||||
FromDSE(DATEPART(ARG(0)), &y, NULL, NULL);
|
||||
else
|
||||
y = ARGV(0);
|
||||
|
||||
@@ -2214,7 +2314,7 @@ static int FIif(expr_node *node, Value *locals, Value *ans, int *nonconst)
|
||||
cur = node->child;
|
||||
|
||||
if (!(node->num_kids % 2)) {
|
||||
if (DebugFlag & DB_PRTEXPR) {
|
||||
if (DBGX) {
|
||||
r = 0;
|
||||
while(cur) {
|
||||
if (r) PUT(", ");
|
||||
@@ -2237,7 +2337,7 @@ static int FIif(expr_node *node, Value *locals, Value *ans, int *nonconst)
|
||||
DBG(DBufFree(&DebugBuf));
|
||||
return r;
|
||||
}
|
||||
if (DebugFlag & DB_PRTEXPR) {
|
||||
if (DBGX) {
|
||||
if (done) PUT(", ");
|
||||
done = 1;
|
||||
PUT(PrintValue(&v, NULL));
|
||||
@@ -2245,7 +2345,7 @@ static int FIif(expr_node *node, Value *locals, Value *ans, int *nonconst)
|
||||
|
||||
if (truthy(&v)) {
|
||||
r = evaluate_expr_node(cur->sibling, locals, ans, nonconst);
|
||||
if (r == OK && (DebugFlag & DB_PRTEXPR)) {
|
||||
if (r == OK && DBGX) {
|
||||
PUT(", ");
|
||||
PUT(PrintValue(ans, NULL));
|
||||
cur = cur->sibling->sibling;
|
||||
@@ -2266,7 +2366,7 @@ static int FIif(expr_node *node, Value *locals, Value *ans, int *nonconst)
|
||||
|
||||
/* Return the last arg */
|
||||
r = evaluate_expr_node(cur, locals, ans, nonconst);
|
||||
if (DebugFlag & DB_PRTEXPR) {
|
||||
if (DBGX) {
|
||||
if (done) PUT(", ");
|
||||
PUT(PrintValue(ans, NULL));
|
||||
PUT(") => ");
|
||||
@@ -2285,7 +2385,7 @@ static int FIif(expr_node *node, Value *locals, Value *ans, int *nonconst)
|
||||
/***************************************************************/
|
||||
static int FFilename(func_info *info)
|
||||
{
|
||||
return RetStrVal(FileName, info);
|
||||
return RetStrVal(GetCurrentFilename(), info);
|
||||
}
|
||||
|
||||
/***************************************************************/
|
||||
@@ -2303,7 +2403,7 @@ static int FFiledir(func_info *info)
|
||||
|
||||
DBufInit(&buf);
|
||||
|
||||
if (DBufPuts(&buf, FileName) != OK) return E_NO_MEM;
|
||||
if (DBufPuts(&buf, GetCurrentFilename()) != OK) return E_NO_MEM;
|
||||
if (DBufLen(&buf) == 0) {
|
||||
DBufFree(&buf);
|
||||
return RetStrVal(".", info);
|
||||
@@ -2363,12 +2463,12 @@ static int FAccess(func_info *info)
|
||||
static int FTypeof(func_info *info)
|
||||
{
|
||||
switch(ARG(0).type) {
|
||||
case INT_TYPE: return RetStrVal("INT", info);
|
||||
case DATE_TYPE: return RetStrVal("DATE", info);
|
||||
case TIME_TYPE: return RetStrVal("TIME", info);
|
||||
case STR_TYPE: return RetStrVal("STRING", info);
|
||||
case INT_TYPE: return RetStrVal("INT", info);
|
||||
case DATE_TYPE: return RetStrVal("DATE", info);
|
||||
case TIME_TYPE: return RetStrVal("TIME", info);
|
||||
case STR_TYPE: return RetStrVal("STRING", info);
|
||||
case DATETIME_TYPE: return RetStrVal("DATETIME", info);
|
||||
default: return RetStrVal("ERR", info);
|
||||
default: return RetStrVal("ERR", info);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2754,7 +2854,7 @@ static int FEasterdate(func_info *info)
|
||||
int base;
|
||||
if (Nargs == 0) {
|
||||
base = DSEToday;
|
||||
FromDSE(DSEToday, &y, &m, &d);
|
||||
FromDSE(DSEToday, &y, NULL, NULL);
|
||||
} else {
|
||||
if (ARG(0).type == INT_TYPE) {
|
||||
base = -1;
|
||||
@@ -2763,7 +2863,7 @@ static int FEasterdate(func_info *info)
|
||||
else if (y > BASE+YR_RANGE) return E_2HIGH;
|
||||
} else if (HASDATE(ARG(0))) {
|
||||
base = DATEPART(ARG(0));
|
||||
FromDSE(DATEPART(ARG(0)), &y, &m, &d); /* We just want the year */
|
||||
FromDSE(DATEPART(ARG(0)), &y, NULL, NULL); /* We just want the year */
|
||||
} else return E_BAD_TYPE;
|
||||
}
|
||||
|
||||
@@ -2807,7 +2907,7 @@ static int FOrthodoxeaster(func_info *info)
|
||||
int base = -1;
|
||||
if (Nargs == 0) {
|
||||
base = DSEToday;
|
||||
FromDSE(DSEToday, &y, &m, &d);
|
||||
FromDSE(DSEToday, &y, NULL, NULL);
|
||||
} else {
|
||||
if (ARG(0).type == INT_TYPE) {
|
||||
y = ARGV(0);
|
||||
@@ -2815,7 +2915,7 @@ static int FOrthodoxeaster(func_info *info)
|
||||
else if (y > BASE+YR_RANGE) return E_2HIGH;
|
||||
} else if (HASDATE(ARG(0))) {
|
||||
base = DATEPART(ARG(0));
|
||||
FromDSE(DATEPART(ARG(0)), &y, &m, &d); /* We just want the year */
|
||||
FromDSE(DATEPART(ARG(0)), &y, NULL, NULL); /* We just want the year */
|
||||
} else return E_BAD_TYPE;
|
||||
}
|
||||
|
||||
@@ -2890,7 +2990,8 @@ static int FTimeStuff(int wantmins, func_info *info)
|
||||
static int FTimezone(func_info *info)
|
||||
{
|
||||
int yr, mon, day, hr, min, dse, now;
|
||||
struct tm local, *withzone;
|
||||
struct tm local;
|
||||
struct tm const * withzone;
|
||||
time_t t;
|
||||
char buf[64];
|
||||
|
||||
@@ -3279,7 +3380,7 @@ static int FADusk(func_info *info)
|
||||
static int FFiledate(func_info *info)
|
||||
{
|
||||
struct stat statbuf;
|
||||
struct tm *t1;
|
||||
struct tm const *t1;
|
||||
|
||||
RetVal.type = DATE_TYPE;
|
||||
|
||||
@@ -3310,7 +3411,7 @@ static int FFiledate(func_info *info)
|
||||
static int FFiledatetime(func_info *info)
|
||||
{
|
||||
struct stat statbuf;
|
||||
struct tm *t1;
|
||||
struct tm const *t1;
|
||||
|
||||
RetVal.type = DATETIME_TYPE;
|
||||
|
||||
@@ -3721,7 +3822,7 @@ static int tz_convert(int year, int month, int day,
|
||||
{
|
||||
int r;
|
||||
time_t t;
|
||||
struct tm *res;
|
||||
struct tm const *res;
|
||||
char const *old_tz;
|
||||
|
||||
/* init tm struct */
|
||||
@@ -3843,7 +3944,7 @@ FSlide(func_info *info)
|
||||
for (i=localargs; i<Nargs; i++) {
|
||||
if (ARG(i).type != STR_TYPE) return E_BAD_TYPE;
|
||||
FindToken(ARG(i).v.str, &tok);
|
||||
if (tok.type != T_WkDay) return E_UNKNOWN_TOKEN;
|
||||
if (tok.type != T_WkDay) return E_CANT_PARSE_WKDAY;
|
||||
localomit |= (1 << tok.val);
|
||||
}
|
||||
|
||||
@@ -3901,7 +4002,7 @@ FNonomitted(func_info *info)
|
||||
for (i=localargs; i<Nargs; i++) {
|
||||
if (ARG(i).type != STR_TYPE) return E_BAD_TYPE;
|
||||
FindToken(ARG(i).v.str, &tok);
|
||||
if (tok.type != T_WkDay) return E_UNKNOWN_TOKEN;
|
||||
if (tok.type != T_WkDay) return E_CANT_PARSE_WKDAY;
|
||||
localomit |= (1 << tok.val);
|
||||
}
|
||||
|
||||
@@ -3992,6 +4093,7 @@ FEval(func_info *info)
|
||||
{
|
||||
expr_node *n;
|
||||
int r;
|
||||
int run_was_enabled = 0;
|
||||
|
||||
ASSERT_TYPE(0, STR_TYPE);
|
||||
char const *e = ARGSTR(0);
|
||||
@@ -4002,7 +4104,15 @@ FEval(func_info *info)
|
||||
return r;
|
||||
}
|
||||
|
||||
/* Disable shell() command in eval */
|
||||
if (! (RunDisabled & RUN_IN_EVAL)) {
|
||||
run_was_enabled = 1;
|
||||
RunDisabled |= RUN_IN_EVAL;
|
||||
}
|
||||
r = evaluate_expr_node(n, NULL, &(info->retval), &(info->nonconst));
|
||||
if (run_was_enabled) {
|
||||
RunDisabled &= ~RUN_IN_EVAL;
|
||||
}
|
||||
free_expr_tree(n);
|
||||
return r;
|
||||
}
|
||||
|
||||
@@ -113,7 +113,6 @@ EXTERN INIT( int SynthesizeTags, 0);
|
||||
EXTERN INIT( int ScFormat, SC_AMPM);
|
||||
EXTERN INIT( int MaxSatIter, 1000);
|
||||
EXTERN INIT( int MaxStringLen, MAX_STR_LEN);
|
||||
EXTERN INIT( char *FileName, NULL);
|
||||
EXTERN INIT( int UseStdin, 0);
|
||||
EXTERN INIT( int PurgeMode, 0);
|
||||
EXTERN INIT( int PurgeIncludeDepth, 0);
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
/***************************************************************/
|
||||
/* */
|
||||
/* HASHTAB_STATS.C */
|
||||
/* HASHTAB.C */
|
||||
/* */
|
||||
/* Implementation of hash table. */
|
||||
/* */
|
||||
@@ -99,8 +99,8 @@ static size_t bucket_choices[] = {
|
||||
int
|
||||
hash_table_init(hash_table *t,
|
||||
size_t link_offset,
|
||||
unsigned int (*hashfunc)(void *x),
|
||||
int (*compare)(void *a, void *b))
|
||||
unsigned int (*hashfunc)(void const *x),
|
||||
int (*compare)(void const *a, void const *b))
|
||||
{
|
||||
t->bucket_choice_index = 0;
|
||||
t->num_entries = 0;
|
||||
@@ -141,7 +141,7 @@ hash_table_free(hash_table *t)
|
||||
* \return The number of items in the hash table
|
||||
*/
|
||||
size_t
|
||||
hash_table_num_entries(hash_table *t)
|
||||
hash_table_num_entries(hash_table const *t)
|
||||
{
|
||||
return t->num_entries;
|
||||
}
|
||||
@@ -154,7 +154,7 @@ hash_table_num_entries(hash_table *t)
|
||||
* \return The number of buckets in the hash table
|
||||
*/
|
||||
size_t
|
||||
hash_table_num_buckets(hash_table *t)
|
||||
hash_table_num_buckets(hash_table const *t)
|
||||
{
|
||||
if (t->bucket_choice_index >= NUM_BUCKET_CHOICES) {
|
||||
return 0;
|
||||
@@ -321,7 +321,7 @@ hash_table_find(hash_table *t, void *candidate)
|
||||
*
|
||||
* \return 0 on success, -1 on failure
|
||||
*/
|
||||
int
|
||||
static int
|
||||
hash_table_delete_helper(hash_table *t, void *item, int resize_ok)
|
||||
{
|
||||
if (!item) {
|
||||
|
||||
@@ -34,8 +34,8 @@ typedef struct {
|
||||
size_t num_entries; /**< Number of entries in the hash table */
|
||||
size_t hash_link_offset; /**< Offset of the struct hash_link in the container */
|
||||
void **buckets; /**< Array of buckets */
|
||||
unsigned int (*hashfunc)(void *x); /**< Pointer to the hashing function */
|
||||
int (*compare)(void *a, void *b); /**< Pointer to the comparison function */
|
||||
unsigned int (*hashfunc)(void const *x); /**< Pointer to the hashing function */
|
||||
int (*compare)(void const *a, void const *b); /**< Pointer to the comparison function */
|
||||
} hash_table;
|
||||
|
||||
/**
|
||||
@@ -56,11 +56,11 @@ struct hash_table_stats {
|
||||
|
||||
int hash_table_init(hash_table *t,
|
||||
size_t link_offset,
|
||||
unsigned int (*hashfunc)(void *x),
|
||||
int (*compare)(void *a, void *b));
|
||||
unsigned int (*hashfunc)(void const *x),
|
||||
int (*compare)(void const *a, void const *b));
|
||||
void hash_table_free(hash_table *t);
|
||||
size_t hash_table_num_entries(hash_table *t);
|
||||
size_t hash_table_num_buckets(hash_table *t);
|
||||
size_t hash_table_num_entries(hash_table const *t);
|
||||
size_t hash_table_num_buckets(hash_table const *t);
|
||||
size_t hash_table_chain_len(hash_table *t, size_t i);
|
||||
int hash_table_insert(hash_table *t, void *item);
|
||||
void *hash_table_find(hash_table *t, void *candidate);
|
||||
@@ -68,7 +68,6 @@ int hash_table_delete(hash_table *t, void *item);
|
||||
int hash_table_delete_no_resize(hash_table *t, void *item);
|
||||
void *hash_table_next(hash_table *t, void *cur);
|
||||
void hash_table_dump_stats(hash_table *t, FILE *fp);
|
||||
void hash_table_get_stats(hash_table *t, struct hash_table_stats *stat);
|
||||
|
||||
/**
|
||||
* \brief Iterate over all items in a hash table
|
||||
|
||||
@@ -22,6 +22,8 @@
|
||||
#include <stdio.h>
|
||||
#include <math.h>
|
||||
|
||||
static void hash_table_get_stats(hash_table *t, struct hash_table_stats *stat);
|
||||
|
||||
/**
|
||||
* \brief Dump hash table statistics to a stdio FILE
|
||||
*
|
||||
@@ -53,7 +55,7 @@ hash_table_dump_stats(hash_table *t, FILE *fp)
|
||||
* \param t A pointer to a hash_table object
|
||||
* \param stat A pointer to a hash_table_stats object that will be filled in
|
||||
*/
|
||||
void
|
||||
static void
|
||||
hash_table_get_stats(hash_table *t, struct hash_table_stats *stat)
|
||||
{
|
||||
size_t n = hash_table_num_buckets(t);
|
||||
|
||||
10
src/hbcal.c
10
src/hbcal.c
@@ -70,6 +70,8 @@ static char MaxMonLen[] = {
|
||||
|
||||
static char HebIsLeap[] = {0,0,1,0,0,1,0,1,0,0,1,0,0,1,0,0,1,0,1};
|
||||
|
||||
static long DaysToHebYear(int y);
|
||||
|
||||
/***************************************************************/
|
||||
/* */
|
||||
/* RoshHashana */
|
||||
@@ -78,7 +80,7 @@ static char HebIsLeap[] = {0,0,1,0,0,1,0,1,0,0,1,0,0,1,0,0,1,0,1};
|
||||
/* Hebrew year. (ie, 5751, not 1990) */
|
||||
/* */
|
||||
/***************************************************************/
|
||||
int RoshHashana(int i)
|
||||
static int RoshHashana(int i)
|
||||
{
|
||||
long j;
|
||||
j = DaysToHebYear(i-3744) - CORRECTION;
|
||||
@@ -93,7 +95,7 @@ int RoshHashana(int i)
|
||||
/* from new moon before Tishrey 1 5701. */
|
||||
/* */
|
||||
/***************************************************************/
|
||||
long DaysToHebYear(int y)
|
||||
static long DaysToHebYear(int y)
|
||||
{
|
||||
long m, nm, dw, s, l;
|
||||
|
||||
@@ -126,7 +128,7 @@ long DaysToHebYear(int y)
|
||||
/* */
|
||||
/* */
|
||||
/***************************************************************/
|
||||
int DaysInHebYear(int y)
|
||||
static int DaysInHebYear(int y)
|
||||
{
|
||||
long thisyear, nextyear;
|
||||
|
||||
@@ -143,7 +145,7 @@ int DaysInHebYear(int y)
|
||||
/* given the LENGTH of the Hebrew year. */
|
||||
/* */
|
||||
/***************************************************************/
|
||||
char const *DaysInHebMonths(int ylen)
|
||||
static char const *DaysInHebMonths(int ylen)
|
||||
{
|
||||
static char monlen[14] =
|
||||
{30, 29, 30, 29, 30, 0, 29, 30, 29, 30, 29, 30, 29, 29};
|
||||
|
||||
11
src/init.c
11
src/init.c
@@ -186,6 +186,7 @@ void InitRemind(int argc, char const *argv[])
|
||||
InitUserFunctions();
|
||||
|
||||
InitTranslationTable();
|
||||
InitFiles();
|
||||
|
||||
/* If stdout is a terminal, initialize $FormWidth to terminal width-8,
|
||||
but clamp to [20, 500] */
|
||||
@@ -644,6 +645,7 @@ void InitRemind(int argc, char const *argv[])
|
||||
case 'f': case 'F': DebugFlag |= DB_TRACE_FILES; break;
|
||||
case 'q': case 'Q': DebugFlag |= DB_TRANSLATE; break;
|
||||
case 'n': case 'N': DebugFlag |= DB_NONCONST; break;
|
||||
case 'u': case 'U': DebugFlag |= DB_UNUSED_VARS; break;
|
||||
default:
|
||||
fprintf(ErrFp, GetErr(M_BAD_DB_FLAG), *(arg-1));
|
||||
fprintf(ErrFp, "\n");
|
||||
@@ -836,7 +838,7 @@ void Usage(void)
|
||||
fprintf(ErrFp, " -q Don't queue timed reminders\n");
|
||||
fprintf(ErrFp, " -f Trigger timed reminders by staying in foreground\n");
|
||||
fprintf(ErrFp, " -z[n] Enter daemon mode, waking every n (1) minutes.\n");
|
||||
fprintf(ErrFp, " -d... Debug: e=echo x=expr-eval t=trig v=dumpvars l=showline f=tracefiles\n");
|
||||
fprintf(ErrFp, " -d... Debug: See man page for details\n");
|
||||
fprintf(ErrFp, " -e Divert messages normally sent to stderr to stdout\n");
|
||||
fprintf(ErrFp, " -b[n] Time format for cal: 0=am/pm, 1=24hr, 2=none\n");
|
||||
fprintf(ErrFp, " -x[n] Iteration limit for SATISFY clause (def=1000)\n");
|
||||
@@ -1015,11 +1017,6 @@ static void InitializeVar(char const *str)
|
||||
return;
|
||||
}
|
||||
|
||||
if (!*varname) {
|
||||
fprintf(ErrFp, GetErr(M_I_OPTION), GetErr(E_MISS_VAR));
|
||||
fprintf(ErrFp, "\n");
|
||||
return;
|
||||
}
|
||||
expr = str+1;
|
||||
if (!*expr) {
|
||||
fprintf(ErrFp, GetErr(M_I_OPTION), GetErr(E_MISS_EXPR));
|
||||
@@ -1061,7 +1058,7 @@ static void InitializeVar(char const *str)
|
||||
static void
|
||||
AddTrustedUser(char const *username)
|
||||
{
|
||||
struct passwd *pwent;
|
||||
struct passwd const *pwent;
|
||||
if (NumTrustedUsers >= MAX_TRUSTED_USERS) {
|
||||
fprintf(ErrFp, "Too many trusted users (%d max)\n",
|
||||
MAX_TRUSTED_USERS);
|
||||
|
||||
27
src/json.c
27
src/json.c
@@ -47,19 +47,8 @@
|
||||
#include <stdint.h>
|
||||
#endif
|
||||
|
||||
#ifndef JSON_INT_T_OVERRIDDEN
|
||||
#if defined(_MSC_VER)
|
||||
/* https://docs.microsoft.com/en-us/cpp/cpp/data-type-ranges */
|
||||
#define JSON_INT_MAX 9223372036854775807LL
|
||||
#elif defined(__STDC_VERSION__) && __STDC_VERSION__ >= 199901L
|
||||
/* C99 */
|
||||
#define JSON_INT_MAX INT_FAST64_MAX
|
||||
#else
|
||||
/* C89 */
|
||||
#include <limits.h>
|
||||
#define JSON_INT_MAX LONG_MAX
|
||||
#endif
|
||||
#endif
|
||||
#include <limits.h>
|
||||
#define JSON_INT_MAX LONG_MAX
|
||||
|
||||
#ifndef JSON_INT_MAX
|
||||
#define JSON_INT_MAX (json_int_t)(((unsigned json_int_t)(-1)) / (unsigned json_int_t)2);
|
||||
@@ -69,6 +58,8 @@ typedef unsigned int json_uchar;
|
||||
|
||||
const struct _json_value json_value_none;
|
||||
|
||||
static void json_value_free_ex (json_settings * settings, json_value * value);
|
||||
|
||||
static unsigned char hex_value (json_char c)
|
||||
{
|
||||
if (isdigit((unsigned char)c))
|
||||
@@ -252,10 +243,10 @@ static const long
|
||||
flag_block_comment = 1 << 14,
|
||||
flag_num_got_decimal = 1 << 15;
|
||||
|
||||
json_value * json_parse_ex (json_settings * settings,
|
||||
const json_char * json,
|
||||
size_t length,
|
||||
char * error_buf)
|
||||
static json_value * json_parse_ex (json_settings const * settings,
|
||||
const json_char * json,
|
||||
size_t length,
|
||||
char * error_buf)
|
||||
{
|
||||
char error [json_error_max];
|
||||
const json_char * end;
|
||||
@@ -999,7 +990,7 @@ json_value * json_parse (const json_char * json, size_t length)
|
||||
return json_parse_ex (&settings, json, length, 0);
|
||||
}
|
||||
|
||||
void json_value_free_ex (json_settings * settings, json_value * value)
|
||||
static void json_value_free_ex (json_settings * settings, json_value * value)
|
||||
{
|
||||
json_value * cur_value;
|
||||
|
||||
|
||||
12
src/json.h
12
src/json.h
@@ -266,21 +266,9 @@ json_value * json_parse (const json_char * json,
|
||||
size_t length);
|
||||
|
||||
#define json_error_max 128
|
||||
json_value * json_parse_ex (json_settings * settings,
|
||||
const json_char * json,
|
||||
size_t length,
|
||||
char * error);
|
||||
|
||||
void json_value_free (json_value *);
|
||||
|
||||
|
||||
/* Not usually necessary, unless you used a custom mem_alloc and now want to
|
||||
* use a custom mem_free.
|
||||
*/
|
||||
void json_value_free_ex (json_settings * settings,
|
||||
json_value *);
|
||||
|
||||
|
||||
#ifdef __cplusplus
|
||||
} /* extern "C" */
|
||||
#endif
|
||||
|
||||
111
src/main.c
111
src/main.c
@@ -50,16 +50,23 @@
|
||||
#include "err.h"
|
||||
|
||||
static void DoReminders(void);
|
||||
static int DoDebug(ParsePtr p);
|
||||
static void ClearLastTriggers(void);
|
||||
static int DoBanner(ParsePtr p);
|
||||
static void SaveLastTimeTrig(TimeTrig const *t);
|
||||
|
||||
/* Macro for simplifying common block so as not to litter code */
|
||||
#define OUTPUT(c) do { if (output) { DBufPutc(output, c); } else { putchar(c); } } while(0)
|
||||
|
||||
void
|
||||
static void
|
||||
exitfunc(void)
|
||||
{
|
||||
/* Kill any execution-time-limiter process */
|
||||
unlimit_execution_time();
|
||||
|
||||
if (DebugFlag & DB_UNUSED_VARS) {
|
||||
DumpUnusedVars();
|
||||
}
|
||||
if (DebugFlag & DB_HASHSTATS) {
|
||||
fflush(stdout);
|
||||
fflush(ErrFp);
|
||||
@@ -174,8 +181,18 @@ int main(int argc, char *argv[])
|
||||
}
|
||||
|
||||
if (!Hush) {
|
||||
if (DestroyOmitContexts(1))
|
||||
if (DestroyOmitContexts(1)) {
|
||||
FreshLine = 1;
|
||||
Eprint("%s", GetErr(E_PUSH_NOPOP));
|
||||
}
|
||||
if (EmptyVarStack(1)) {
|
||||
FreshLine = 1;
|
||||
Eprint("%s", GetErr(E_PUSHV_NO_POP));
|
||||
}
|
||||
if (EmptyUserFuncStack(1)) {
|
||||
FreshLine = 1;
|
||||
Eprint("%s", GetErr(E_PUSHF_NO_POP));
|
||||
}
|
||||
if (!Daemon && !NextMode && !NumTriggered && !NumQueued) {
|
||||
printf("%s\n", GetErr(E_NOREMINDERS));
|
||||
} else if (!Daemon && !NextMode && !NumTriggered) {
|
||||
@@ -228,6 +245,8 @@ PerIterationInit(void)
|
||||
{
|
||||
ClearGlobalOmits();
|
||||
DestroyOmitContexts(1);
|
||||
EmptyVarStack(1);
|
||||
EmptyUserFuncStack(1);
|
||||
DestroyVars(0);
|
||||
DefaultColorR = -1;
|
||||
DefaultColorG = -1;
|
||||
@@ -359,6 +378,18 @@ static void DoReminders(void)
|
||||
case T_Pop: r=PopOmitContext(&p); break;
|
||||
case T_Preserve: r=DoPreserve(&p); break;
|
||||
case T_Push: r=PushOmitContext(&p); break;
|
||||
case T_PushVars:
|
||||
r=PushVars(&p);
|
||||
break;
|
||||
case T_PopVars:
|
||||
r=PopVars(&p);
|
||||
break;
|
||||
case T_PushFuncs:
|
||||
r=PushUserFuncs(&p);
|
||||
break;
|
||||
case T_PopFuncs:
|
||||
r=PopUserFuncs(&p);
|
||||
break;
|
||||
case T_Expr: r = DoExpr(&p); break;
|
||||
case T_Translate: r = DoTranslate(&p); break;
|
||||
case T_RemType: if (tok.val == RUN_TYPE) {
|
||||
@@ -456,6 +487,15 @@ void FromDSE(int dse, int *y, int *m, int *d)
|
||||
try_yr--;
|
||||
try_dse -= DaysInYear(try_yr);
|
||||
}
|
||||
if (y) {
|
||||
*y = try_yr;
|
||||
}
|
||||
|
||||
/* If all we want is the year, we can quit here */
|
||||
if (!d && !m) {
|
||||
return;
|
||||
}
|
||||
|
||||
dse -= try_dse;
|
||||
|
||||
t = DaysInMonth(try_mon, try_yr);
|
||||
@@ -464,9 +504,6 @@ void FromDSE(int dse, int *y, int *m, int *d)
|
||||
try_mon++;
|
||||
t = DaysInMonth(try_mon, try_yr);
|
||||
}
|
||||
if (y) {
|
||||
*y = try_yr;
|
||||
}
|
||||
if (m) {
|
||||
*m = try_mon;
|
||||
}
|
||||
@@ -899,24 +936,17 @@ void Wprint(char const *fmt, ...)
|
||||
{
|
||||
va_list argptr;
|
||||
|
||||
char const *fname = GetCurrentFilename();
|
||||
if (SuppressErrorOutputInCatch) {
|
||||
return;
|
||||
}
|
||||
|
||||
/* We can't use line_range because caller might have used it */
|
||||
if (FileName) {
|
||||
if (strcmp(FileName, "-")) {
|
||||
if (LineNoStart == LineNo) {
|
||||
(void) fprintf(ErrFp, "%s(%d): ", FileName, LineNo);
|
||||
} else {
|
||||
(void) fprintf(ErrFp, "%s(%d:%d): ", FileName, LineNoStart, LineNo);
|
||||
}
|
||||
if (fname) {
|
||||
if (LineNoStart == LineNo) {
|
||||
(void) fprintf(ErrFp, "%s(%d): ", fname, LineNo);
|
||||
} else {
|
||||
if (LineNoStart == LineNo) {
|
||||
(void) fprintf(ErrFp, "-stdin-(%d): ", LineNo);
|
||||
} else {
|
||||
(void) fprintf(ErrFp, "-stdin-(%d:%d): ", LineNoStart, LineNo);
|
||||
}
|
||||
(void) fprintf(ErrFp, "%s(%d:%d): ", fname, LineNoStart, LineNo);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -934,24 +964,27 @@ void Wprint(char const *fmt, ...)
|
||||
void Eprint(char const *fmt, ...)
|
||||
{
|
||||
va_list argptr;
|
||||
char const *fname;
|
||||
|
||||
if (SuppressErrorOutputInCatch) {
|
||||
return;
|
||||
}
|
||||
|
||||
/* Check if more than one error msg. from this line */
|
||||
if (!FreshLine && !ShowAllErrors) return;
|
||||
|
||||
if (!FileName) {
|
||||
if (should_ignore_line()) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (strcmp(FileName, "-")) {
|
||||
fname = FileName;
|
||||
} else {
|
||||
fname = "-stdin-";
|
||||
char const *fname = GetCurrentFilename();
|
||||
if (!fname) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (LineNo < 1) {
|
||||
/* Not yet processing a file */
|
||||
return;
|
||||
}
|
||||
/* Check if more than one error msg. from this line */
|
||||
if (!FreshLine && !ShowAllErrors) return;
|
||||
|
||||
if (FreshLine) {
|
||||
/* We can't use line_range because caller might have used it */
|
||||
if (LineNo == LineNoStart) {
|
||||
@@ -1062,7 +1095,7 @@ int PushToken(char const *tok, ParsePtr p)
|
||||
int SystemTime(int realtime)
|
||||
{
|
||||
time_t now;
|
||||
struct tm *t;
|
||||
struct tm const *t;
|
||||
|
||||
if (!realtime && (SysTime != -1)) return SysTime;
|
||||
|
||||
@@ -1102,7 +1135,7 @@ int MinutesPastMidnight(int realtime)
|
||||
int SystemDate(int *y, int *m, int *d)
|
||||
{
|
||||
time_t now;
|
||||
struct tm *t;
|
||||
struct tm const *t;
|
||||
|
||||
/* In test mode, always return 6 January 2025 */
|
||||
if (TestMode) {
|
||||
@@ -1276,7 +1309,7 @@ int VerifyEoln(ParsePtr p)
|
||||
/* Set the debug options under program control. */
|
||||
/* */
|
||||
/***************************************************************/
|
||||
int DoDebug(ParsePtr p)
|
||||
static int DoDebug(ParsePtr p)
|
||||
{
|
||||
int err;
|
||||
int ch;
|
||||
@@ -1362,6 +1395,11 @@ int DoDebug(ParsePtr p)
|
||||
if (val) DebugFlag |= DB_NONCONST;
|
||||
else DebugFlag &= ~DB_NONCONST;
|
||||
break;
|
||||
case 'u':
|
||||
case 'U':
|
||||
if (val) DebugFlag |= DB_UNUSED_VARS;
|
||||
else DebugFlag &= ~DB_UNUSED_VARS;
|
||||
break;
|
||||
default:
|
||||
Wprint(GetErr(M_BAD_DB_FLAG), ch);
|
||||
break;
|
||||
@@ -1377,7 +1415,7 @@ int DoDebug(ParsePtr p)
|
||||
/* reminder is issued. */
|
||||
/* */
|
||||
/***************************************************************/
|
||||
int DoBanner(ParsePtr p)
|
||||
static int DoBanner(ParsePtr p)
|
||||
{
|
||||
int err;
|
||||
int c;
|
||||
@@ -1561,7 +1599,8 @@ int CalcMinsFromUTC(int dse, int tim, int *mins, int *isdst)
|
||||
/* Convert dse and tim to an Unix tm struct */
|
||||
int yr, mon, day;
|
||||
int tdiff;
|
||||
struct tm local, utc, *temp;
|
||||
struct tm local, utc;
|
||||
struct tm const * temp;
|
||||
time_t loc_t, utc_t;
|
||||
int isdst_tmp;
|
||||
|
||||
@@ -1955,7 +1994,7 @@ FreeTrig(Trigger *t)
|
||||
t->infos = NULL;
|
||||
}
|
||||
|
||||
void
|
||||
static void
|
||||
ClearLastTriggers(void)
|
||||
{
|
||||
LastTrigger.expired = 0;
|
||||
@@ -1990,9 +2029,11 @@ SaveAllTriggerInfo(Trigger const *t, TimeTrig const *tt, int trigdate, int trigt
|
||||
{
|
||||
SaveLastTrigger(t);
|
||||
SaveLastTimeTrig(tt);
|
||||
LastTriggerDate = trigdate;
|
||||
if (trigdate != -1) {
|
||||
LastTriggerDate = trigdate;
|
||||
LastTrigValid = valid;
|
||||
}
|
||||
LastTriggerTime = trigtime;
|
||||
LastTrigValid = valid;
|
||||
}
|
||||
|
||||
void
|
||||
@@ -2013,7 +2054,7 @@ SaveLastTrigger(Trigger const *t)
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
static void
|
||||
SaveLastTimeTrig(TimeTrig const *t)
|
||||
{
|
||||
memcpy(&LastTimeTrig, t, sizeof(LastTimeTrig));
|
||||
|
||||
@@ -20,6 +20,7 @@
|
||||
#include "md5.h"
|
||||
|
||||
static void byteReverse(unsigned char *buf, unsigned longs);
|
||||
static void MD5Transform(uint32 buf[4], uint32 const in[16]);
|
||||
|
||||
/*
|
||||
* Note: this code is harmless on little-endian machines.
|
||||
@@ -163,7 +164,7 @@ void MD5Final(unsigned char digest[16], struct MD5Context *ctx)
|
||||
* reflect the addition of 16 longwords of new data. MD5Update blocks
|
||||
* the data and converts bytes into longwords for this routine.
|
||||
*/
|
||||
void MD5Transform(uint32 buf[4], uint32 const in[16])
|
||||
static void MD5Transform(uint32 buf[4], uint32 const in[16])
|
||||
{
|
||||
register uint32 a, b, c, d;
|
||||
|
||||
|
||||
@@ -29,6 +29,5 @@ void MD5Init(struct MD5Context *context);
|
||||
void MD5Update(struct MD5Context *context, unsigned char const *buf,
|
||||
unsigned len);
|
||||
void MD5Final(unsigned char digest[16], struct MD5Context *context);
|
||||
void MD5Transform(uint32 buf[4], uint32 const in[16]);
|
||||
|
||||
#endif /* !MD5_H */
|
||||
|
||||
@@ -636,7 +636,7 @@ static time_t time_t_from_dse(int dse)
|
||||
|
||||
static int datetime_from_time_t(time_t t)
|
||||
{
|
||||
struct tm *local;
|
||||
struct tm const *local;
|
||||
int ans;
|
||||
|
||||
/* Round to nearest minute */
|
||||
@@ -665,7 +665,7 @@ static double interpolate(double f0, double f1, double f2, double p)
|
||||
|
||||
/* Moon position using fundamental arguments
|
||||
Van Flandern & Pulkkinen, 1979) */
|
||||
void moon_position(double dayOffset, double *ra, double *declination, double *distance)
|
||||
static void moon_position(double dayOffset, double *ra, double *declination, double *distance)
|
||||
{
|
||||
double l = 0.606434 + 0.03660110129 * dayOffset;
|
||||
double m = 0.374897 + 0.03629164709 * dayOffset;
|
||||
|
||||
24
src/omit.c
24
src/omit.c
@@ -36,7 +36,7 @@ int NumFullOmits, NumPartialOmits;
|
||||
/* The structure for saving and restoring OMIT contexts */
|
||||
typedef struct omitcontext {
|
||||
struct omitcontext *next;
|
||||
char *filename;
|
||||
char const *filename;
|
||||
int lineno;
|
||||
int numfull, numpart;
|
||||
int *fullsave;
|
||||
@@ -98,7 +98,6 @@ int DestroyOmitContexts(int print_unmatched)
|
||||
num++;
|
||||
if (c->fullsave) free(c->fullsave);
|
||||
if (c->partsave) free(c->partsave);
|
||||
if (c->filename) free(c->filename);
|
||||
d = c->next;
|
||||
free(c);
|
||||
c = d;
|
||||
@@ -122,28 +121,19 @@ int PushOmitContext(ParsePtr p)
|
||||
context = NEW(OmitContext);
|
||||
if (!context) return E_NO_MEM;
|
||||
|
||||
if (FileName) {
|
||||
context->filename = StrDup(FileName);
|
||||
} else {
|
||||
context->filename = StrDup("");
|
||||
}
|
||||
if (!context->filename) {
|
||||
free(context);
|
||||
return E_NO_MEM;
|
||||
}
|
||||
context->filename = GetCurrentFilename();
|
||||
context->lineno = LineNo;
|
||||
|
||||
context->numfull = NumFullOmits;
|
||||
context->numpart = NumPartialOmits;
|
||||
context->weekdaysave = WeekdayOmits;
|
||||
context->fullsave = malloc(NumFullOmits * sizeof(int));
|
||||
if (NumFullOmits && !context->fullsave) {
|
||||
free(context->filename);
|
||||
free(context);
|
||||
return E_NO_MEM;
|
||||
}
|
||||
context->partsave = malloc(NumPartialOmits * sizeof(int));
|
||||
if (NumPartialOmits && !context->partsave) {
|
||||
free(context->filename);
|
||||
if (context->fullsave) {
|
||||
free(context->fullsave);
|
||||
}
|
||||
@@ -172,6 +162,7 @@ int PopOmitContext(ParsePtr p)
|
||||
{
|
||||
|
||||
OmitContext *c = SavedOmitContexts;
|
||||
char const *fname = GetCurrentFilename();
|
||||
|
||||
if (!c) return E_POP_NO_PUSH;
|
||||
NumFullOmits = c->numfull;
|
||||
@@ -185,13 +176,12 @@ int PopOmitContext(ParsePtr p)
|
||||
/* Remove the context from the stack */
|
||||
SavedOmitContexts = c->next;
|
||||
|
||||
if (c->filename && FileName && strcmp(c->filename, FileName)) {
|
||||
Wprint(tr("POP-OMIT-CONTEXT at %s:%d matches PUSH-OMIT-CONTEXT in different file: %s:%d"), FileName, LineNo, c->filename, c->lineno);
|
||||
if (c->filename && fname && strcmp(c->filename, fname)) {
|
||||
Wprint(tr("POP-OMIT-CONTEXT at %s:%d matches PUSH-OMIT-CONTEXT in different file: %s:%d"), fname, LineNo, c->filename, c->lineno);
|
||||
}
|
||||
/* Free memory used by the saved context */
|
||||
if (c->partsave) free(c->partsave);
|
||||
if (c->fullsave) free(c->fullsave);
|
||||
if (c->filename) free(c->filename);
|
||||
free(c);
|
||||
|
||||
return VerifyEoln(p);
|
||||
@@ -249,7 +239,7 @@ int IsOmitted(int dse, int localomit, char const *omitfunc, int *omit)
|
||||
return OK;
|
||||
}
|
||||
|
||||
FromDSE(dse, &y, &m, &d);
|
||||
FromDSE(dse, NULL, &m, &d);
|
||||
if (BexistsIntArray(PartialOmitArray, NumPartialOmits, (m << 5) + d)) {
|
||||
*omit = 1;
|
||||
return OK;
|
||||
|
||||
51
src/protos.h
51
src/protos.h
@@ -47,32 +47,29 @@ int DoFrename (ParsePtr p);
|
||||
void UnsetAllUserFuncs(void);
|
||||
void ProduceCalendar (void);
|
||||
char const *SimpleTime (int tim);
|
||||
char const *CalendarTime (int tim, int duration);
|
||||
int DoRem (ParsePtr p);
|
||||
int DoFlush (ParsePtr p);
|
||||
void DoExit (ParsePtr p);
|
||||
int ParseRem (ParsePtr s, Trigger *trig, TimeTrig *tim);
|
||||
int TriggerReminder (ParsePtr p, Trigger *t, TimeTrig *tim, int dse, int is_queued, DynamicBuffer *output);
|
||||
int ShouldTriggerReminder (Trigger *t, TimeTrig *tim, int dse, int *err);
|
||||
int DoSubst (ParsePtr p, DynamicBuffer *dbuf, Trigger *t, TimeTrig *tt, int dse, int mode);
|
||||
int TriggerReminder (ParsePtr p, Trigger *t, TimeTrig const *tim, int dse, int is_queued, DynamicBuffer *output);
|
||||
int ShouldTriggerReminder (Trigger const *t, TimeTrig const *tim, int dse, int *err);
|
||||
int DoSubst (ParsePtr p, DynamicBuffer *dbuf, Trigger *t, TimeTrig const *tt, int dse, int mode);
|
||||
int DoSubstFromString (char const *source, DynamicBuffer *dbuf, int dse, int tim);
|
||||
int ParseLiteralDateOrTime (char const **s, int *dse, int *tim);
|
||||
int ParseLiteralTime (char const **s, int *tim);
|
||||
expr_node *parse_expression(char const **e, int *r, Var *locals);
|
||||
|
||||
int evaluate_expression(expr_node *node, Value *locals, Value *ans, int *nonconst);
|
||||
int evaluate_expr_node(expr_node *node, Value *locals, Value *ans, int *nonconst);
|
||||
int truthy(Value const *v);
|
||||
|
||||
void print_expr_tree(expr_node *node, FILE *fp);
|
||||
void unlimit_execution_time(void);
|
||||
expr_node *free_expr_tree(expr_node *node);
|
||||
expr_node *clone_expr_tree(expr_node const *node, int *r);
|
||||
int EvalExpr (char const **e, Value *v, ParsePtr p);
|
||||
int DoCoerce (char type, Value *v);
|
||||
char const *PrintValue (Value *v, FILE *fp);
|
||||
int CopyValue (Value *dest, const Value *src);
|
||||
int ReadLine (void);
|
||||
int OpenFile (char const *fname);
|
||||
int DoInclude (ParsePtr p, enum TokTypes tok);
|
||||
int DoIncludeCmd (ParsePtr p);
|
||||
int IncludeFile (char const *fname);
|
||||
@@ -109,8 +106,6 @@ int DoEndif (ParsePtr p);
|
||||
int DoIfTrig (ParsePtr p);
|
||||
int ShouldIgnoreLine (void);
|
||||
int VerifyEoln (ParsePtr p);
|
||||
int DoDebug (ParsePtr p);
|
||||
int DoBanner (ParsePtr p);
|
||||
int DoRun (ParsePtr p);
|
||||
int DoExpr (ParsePtr p);
|
||||
int DoTranslate (ParsePtr p);
|
||||
@@ -124,13 +119,12 @@ int PushOmitContext (ParsePtr p);
|
||||
int PopOmitContext (ParsePtr p);
|
||||
int IsOmitted (int dse, int localomit, char const *omitfunc, int *omit);
|
||||
int DoOmit (ParsePtr p);
|
||||
int QueueReminder (ParsePtr p, Trigger *trig, TimeTrig *tim, char const *sched);
|
||||
int QueueReminder (ParsePtr p, Trigger *trig, TimeTrig const *tim, char const *sched);
|
||||
void HandleQueuedReminders (void);
|
||||
char const *FindInitialToken (Token *tok, char const *s);
|
||||
void FindToken (char const *s, Token *tok);
|
||||
void FindNumericToken (char const *s, Token *t);
|
||||
int ComputeTrigger (int today, Trigger *trig, TimeTrig *tim, int *err, int save_in_globals);
|
||||
int ComputeTriggerNoAdjustDuration (int today, Trigger *trig, TimeTrig *tim, int *err, int save_in_globals, int duration_days);
|
||||
int ComputeTriggerNoAdjustDuration (int today, Trigger *trig, TimeTrig const *tim, int *err, int save_in_globals, int duration_days);
|
||||
int AdjustTriggerForDuration(int today, int r, Trigger *trig, TimeTrig *tim, int save_in_globals);
|
||||
char *StrnCpy (char *dest, char const *source, int n);
|
||||
|
||||
@@ -150,20 +144,24 @@ void strtolower(char *s);
|
||||
|
||||
Var *FindVar (char const *str, int create);
|
||||
SysVar *FindSysVar (char const *name);
|
||||
int DeleteVar (char const *str);
|
||||
int SetVar (char const *str, Value const *val, int nonconst_expr);
|
||||
int GetVarValue (char const *str, Value *val);
|
||||
int DoSet (Parser *p);
|
||||
int DoUnset (Parser *p);
|
||||
int DoDump (ParsePtr p);
|
||||
int PushVars(ParsePtr p);
|
||||
int EmptyVarStack(int print_unmatched);
|
||||
int PopVars(ParsePtr p);
|
||||
int PushUserFuncs(ParsePtr p);
|
||||
int EmptyUserFuncStack(int print_unmatched);
|
||||
int PopUserFuncs(ParsePtr p);
|
||||
void DumpVarTable (int dump_constness);
|
||||
void DumpUnusedVars(void);
|
||||
void DestroyVars (int all);
|
||||
int PreserveVar (char const *name);
|
||||
int DoPreserve (Parser *p);
|
||||
int DoSatRemind (Trigger *trig, TimeTrig *tt, ParsePtr p);
|
||||
int DoMsgCommand (char const *cmd, char const *msg, int is_queued);
|
||||
int ParseNonSpaceChar (ParsePtr p, int *err, int peek);
|
||||
unsigned int HashVal_ignorecase(char const *str);
|
||||
unsigned int HashVal_preservecase(char const *str);
|
||||
int DateOK (int y, int m, int d);
|
||||
BuiltinFunc *FindBuiltinFunc (char const *name);
|
||||
@@ -174,10 +172,6 @@ int UserFuncExists (char const *fn);
|
||||
void DSEToHeb (int dse, int *hy, int *hm, int *hd);
|
||||
int HebNameToNum (char const *mname);
|
||||
char const *HebMonthName (int m, int y);
|
||||
int RoshHashana (int i);
|
||||
long DaysToHebYear (int y);
|
||||
int DaysInHebYear (int y);
|
||||
char const *DaysInHebMonths (int ylen);
|
||||
int HebToDSE (int hy, int hm, int hd);
|
||||
int GetValidHebDate (int yin, int min, int din, int adarbehave, int *mout, int *dout, int yahr);
|
||||
int GetNextHebrewDate (int dsestart, int hm, int hd, int yahr, int adarbehave, int *ans);
|
||||
@@ -198,9 +192,7 @@ void PurgeEchoLine(char const *fmt, ...);
|
||||
void FreeTrig(Trigger *t);
|
||||
void AppendTag(DynamicBuffer *buf, char const *s);
|
||||
char const *SynthesizeTag(void);
|
||||
void ClearLastTriggers(void);
|
||||
void SaveLastTrigger(Trigger const *t);
|
||||
void SaveLastTimeTrig(TimeTrig const *t);
|
||||
void SaveAllTriggerInfo(Trigger const *t, TimeTrig const *tt, int trigdate, int trigtime, int valid);
|
||||
|
||||
void PerIterationInit(void);
|
||||
@@ -209,13 +201,9 @@ char const *Colorize(int r, int g, int b, int bg, int clamp);
|
||||
void PrintJSONString(char const *s);
|
||||
void PrintJSONKeyPairInt(char const *name, int val);
|
||||
void PrintJSONKeyPairString(char const *name, char const *val);
|
||||
void PrintJSONKeyPairDate(char const *name, int dse);
|
||||
void PrintJSONKeyPairDateTime(char const *name, int dt);
|
||||
void PrintJSONKeyPairTime(char const *name, int t);
|
||||
void System(char const *cmd, int queued);
|
||||
int ShellEscape(char const *in, DynamicBuffer *out);
|
||||
int AddGlobalOmit(int dse);
|
||||
void set_lat_and_long_from_components(void);
|
||||
void set_components_from_lat_and_long(void);
|
||||
|
||||
void DebugExitFunc(void);
|
||||
@@ -225,7 +213,6 @@ int GetTerminalBackground(void);
|
||||
char const *get_day_name(int wkday);
|
||||
char const *get_month_name(int mon);
|
||||
|
||||
void set_cloexec(FILE *fp);
|
||||
int push_call(char const *filename, char const *func, int lineno, int lineno_start);
|
||||
void clear_callstack(void);
|
||||
int print_callstack(FILE *fp);
|
||||
@@ -268,6 +255,7 @@ void InitDedupeTable(void);
|
||||
void InitVars(void);
|
||||
void InitUserFunctions(void);
|
||||
void InitTranslationTable(void);
|
||||
void InitFiles(void);
|
||||
char const *GetTranslatedString(char const *orig);
|
||||
int GetTranslatedStringTryingVariants(char const *orig, DynamicBuffer *out);
|
||||
char const *GetErr(int r);
|
||||
@@ -277,12 +265,8 @@ void print_escaped_string(FILE *fp, char const *s);
|
||||
void print_escaped_string_helper(FILE *fp, char const *s, int esc_for_remind, int json);
|
||||
void GenerateSysvarTranslationTemplates(void);
|
||||
void TranslationTemplate(char const *msg);
|
||||
TrigInfo *NewTrigInfo(char const *i);
|
||||
void FreeTrigInfo(TrigInfo *ti);
|
||||
void FreeTrigInfoChain(TrigInfo *ti);
|
||||
int AppendTrigInfo(Trigger *t, char const *info);
|
||||
int TrigInfoHeadersAreTheSame(char const *i1, char const *i2);
|
||||
int TrigInfoIsValid(char const *info);
|
||||
char const *FindTrigInfo(Trigger *t, char const *header);
|
||||
void WriteJSONInfoChain(TrigInfo *ti);
|
||||
char const *line_range(int lineno_start, int lineno);
|
||||
@@ -304,8 +288,5 @@ int should_ignore_line(void);
|
||||
int in_constant_context(void);
|
||||
void pop_excess_ifs(char const *fname);
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
void SetCurrentFilename(char const *fname);
|
||||
char const *GetCurrentFilename(void);
|
||||
|
||||
82
src/queue.c
82
src/queue.c
@@ -12,12 +12,6 @@
|
||||
|
||||
#include "config.h"
|
||||
|
||||
/* Solaris needs this to get select() prototype */
|
||||
#ifdef __sun__
|
||||
#define __EXTENSIONS__ 1
|
||||
#endif
|
||||
|
||||
/* We only want object code generated if we have queued reminders */
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <signal.h>
|
||||
@@ -45,13 +39,6 @@ static void consume_inotify_events(int fd);
|
||||
static int setup_inotify_watch(void);
|
||||
#endif
|
||||
|
||||
/* A list of filenames associated with queued reminders */
|
||||
typedef struct queuedfname {
|
||||
struct queuedfname *next;
|
||||
char const *fname;
|
||||
} QueuedFilename;
|
||||
|
||||
|
||||
/* List structure for holding queued reminders */
|
||||
typedef struct queuedrem {
|
||||
struct queuedrem *next;
|
||||
@@ -72,7 +59,6 @@ typedef struct queuedrem {
|
||||
/* Global variables */
|
||||
|
||||
static QueuedRem *QueueHead = NULL;
|
||||
static QueuedFilename *Files = NULL;
|
||||
static time_t FileModTime;
|
||||
static struct stat StatBuf;
|
||||
|
||||
@@ -83,7 +69,6 @@ static int CalculateNextTimeUsingSched (QueuedRem *q);
|
||||
static void ServerWait (struct timeval *sleep_tv);
|
||||
static void reread (void);
|
||||
static void PrintQueue(void);
|
||||
static char const *QueueFilename(char const *fname);
|
||||
|
||||
static void chomp(DynamicBuffer *buf)
|
||||
{
|
||||
@@ -100,7 +85,7 @@ static void chomp(DynamicBuffer *buf)
|
||||
}
|
||||
}
|
||||
|
||||
char const *SimpleTimeNoSpace(int tim)
|
||||
static char const *SimpleTimeNoSpace(int tim)
|
||||
{
|
||||
char *s = (char *) SimpleTime(tim);
|
||||
if (s && *s) {
|
||||
@@ -112,49 +97,7 @@ char const *SimpleTimeNoSpace(int tim)
|
||||
return s;
|
||||
}
|
||||
|
||||
/***************************************************************/
|
||||
/* */
|
||||
/* QueueFilename */
|
||||
/* */
|
||||
/* Add fname to the list of queued filenames if it's not */
|
||||
/* already present. Either way, return a pointer to the */
|
||||
/* filename. Returns NULL if out of memory */
|
||||
/* */
|
||||
/***************************************************************/
|
||||
static QueuedFilename *last_file_found = NULL;
|
||||
static char const *QueueFilename(char const *fname)
|
||||
{
|
||||
QueuedFilename *elem = Files;
|
||||
|
||||
/* Optimization: We are very likely in the same file as
|
||||
before... */
|
||||
if (last_file_found && !strcmp(fname, last_file_found->fname)) {
|
||||
return last_file_found->fname;
|
||||
}
|
||||
|
||||
/* No such luck; search the list */
|
||||
while(elem) {
|
||||
if (!strcmp(elem->fname, fname)) {
|
||||
last_file_found = elem;
|
||||
return elem->fname;
|
||||
}
|
||||
elem = elem->next;
|
||||
}
|
||||
/* Not found... queue it */
|
||||
elem = NEW(QueuedFilename);
|
||||
if (!elem) return NULL;
|
||||
elem->fname = StrDup(fname);
|
||||
if (!elem->fname) {
|
||||
free(elem);
|
||||
return NULL;
|
||||
}
|
||||
elem->next = Files;
|
||||
Files = elem;
|
||||
last_file_found = elem;
|
||||
return elem->fname;
|
||||
}
|
||||
|
||||
static void del_reminder(QueuedRem *qid)
|
||||
static void del_reminder(QueuedRem const *qid)
|
||||
{
|
||||
QueuedRem *q = QueueHead;
|
||||
QueuedRem *next;
|
||||
@@ -194,7 +137,7 @@ static void del_reminder_ul(unsigned long qid) {
|
||||
/* */
|
||||
/***************************************************************/
|
||||
int QueueReminder(ParsePtr p, Trigger *trig,
|
||||
TimeTrig *tim, char const *sched)
|
||||
TimeTrig const *tim, char const *sched)
|
||||
{
|
||||
QueuedRem *qelem;
|
||||
|
||||
@@ -217,13 +160,7 @@ int QueueReminder(ParsePtr p, Trigger *trig,
|
||||
free(qelem);
|
||||
return E_NO_MEM;
|
||||
}
|
||||
qelem->fname = QueueFilename(FileName);
|
||||
if (!qelem->fname) {
|
||||
free((void *) qelem->text);
|
||||
free(qelem);
|
||||
return E_NO_MEM;
|
||||
}
|
||||
|
||||
qelem->fname = GetCurrentFilename();
|
||||
qelem->lineno = LineNo;
|
||||
qelem->lineno_start = LineNoStart;
|
||||
NumQueued++;
|
||||
@@ -272,7 +209,7 @@ maybe_close(int fd)
|
||||
(void) close(new_fd);
|
||||
}
|
||||
|
||||
void
|
||||
static void
|
||||
SigContHandler(int d)
|
||||
{
|
||||
UNUSED(d);
|
||||
@@ -327,12 +264,6 @@ void HandleQueuedReminders(void)
|
||||
/* Turn off sorting -- otherwise, TriggerReminder has no effect! */
|
||||
SortByDate = 0;
|
||||
|
||||
/* Free FileName if necessary */
|
||||
if (FileName) {
|
||||
free(FileName);
|
||||
FileName = NULL;
|
||||
}
|
||||
|
||||
/* We don't need to keep the dedupe table around */
|
||||
ClearDedupeTable();
|
||||
|
||||
@@ -495,7 +426,7 @@ void HandleQueuedReminders(void)
|
||||
/* Set up global variables so some functions like trigdate()
|
||||
and trigtime() work correctly */
|
||||
SaveAllTriggerInfo(&(q->t), &(q->tt), DSEToday, q->tt.ttime, 1);
|
||||
FileName = (char *) q->fname;
|
||||
SetCurrentFilename(q->fname);
|
||||
DefaultColorR = q->red;
|
||||
DefaultColorG = q->green;
|
||||
DefaultColorB = q->blue;
|
||||
@@ -516,7 +447,6 @@ void HandleQueuedReminders(void)
|
||||
} else {
|
||||
(void) TriggerReminder(&p, &tcopy, &q->tt, DSEToday, 1, NULL);
|
||||
}
|
||||
FileName = NULL;
|
||||
if (IsServerMode() && !DaemonJSON && q->typ != RUN_TYPE) {
|
||||
printf("NOTE endreminder\n");
|
||||
}
|
||||
|
||||
44
src/rem2ps.c
44
src/rem2ps.c
@@ -131,16 +131,16 @@ int LeftMarg, RightMarg, TopMarg, BotMarg;
|
||||
int FillPage;
|
||||
int Verbose = 0;
|
||||
|
||||
void Init (int argc, char *argv[]);
|
||||
void Usage (char const *s);
|
||||
void DoPsCal (void);
|
||||
int DoQueuedPs (void);
|
||||
void DoSmallCal (char const *m, int days, int first, int col, int which);
|
||||
void WriteProlog (void);
|
||||
void WriteCalEntry (void);
|
||||
void WriteOneEntry (CalEntry *c);
|
||||
void GetSmallLocations (void);
|
||||
char const *EatToken(char const *in, char *out, int maxlen);
|
||||
static void Init (int argc, char const *argv[]);
|
||||
static void Usage (char const *s);
|
||||
static void DoPsCal (void);
|
||||
static int DoQueuedPs (void);
|
||||
static void DoSmallCal (char const *m, int days, int first, int col, int which);
|
||||
static void WriteProlog (void);
|
||||
static void WriteCalEntry (void);
|
||||
static void WriteOneEntry (CalEntry const *c);
|
||||
static void GetSmallLocations (void);
|
||||
static char const *EatToken(char const *in, char *out, int maxlen);
|
||||
|
||||
static void
|
||||
put_escaped_string(char const *s)
|
||||
@@ -161,7 +161,7 @@ put_escaped_string(char const *s)
|
||||
/* Compare strings, case insensitive. */
|
||||
/* */
|
||||
/***************************************************************/
|
||||
int StrCmpi(char const *s1, char const *s2)
|
||||
static int StrCmpi(char const *s1, char const *s2)
|
||||
{
|
||||
int r;
|
||||
while (*s1 && *s2) {
|
||||
@@ -178,7 +178,7 @@ int StrCmpi(char const *s1, char const *s2)
|
||||
/* */
|
||||
/***************************************************************/
|
||||
static CalEntry *
|
||||
JSONToCalEntry(DynamicBuffer *buf)
|
||||
JSONToCalEntry(DynamicBuffer const *buf)
|
||||
{
|
||||
CalEntry *c;
|
||||
json_value *val;
|
||||
@@ -325,7 +325,7 @@ TextToCalEntry(DynamicBuffer *buf)
|
||||
/* MAIN PROGRAM */
|
||||
/* */
|
||||
/***************************************************************/
|
||||
int main(int argc, char *argv[])
|
||||
int main(int argc, char const *argv[])
|
||||
{
|
||||
/* If stdin is a tty - probably wrong. */
|
||||
|
||||
@@ -375,7 +375,7 @@ int main(int argc, char *argv[])
|
||||
/* DoPsCal - emit PostScript for the calendar. */
|
||||
/* */
|
||||
/***************************************************************/
|
||||
void DoPsCal(void)
|
||||
static void DoPsCal(void)
|
||||
{
|
||||
char month[40], year[40];
|
||||
char prevm[40], nextm[40];
|
||||
@@ -595,7 +595,7 @@ void DoPsCal(void)
|
||||
/* WriteProlog - write the PostScript prologue */
|
||||
/* */
|
||||
/***************************************************************/
|
||||
void WriteProlog(void)
|
||||
static void WriteProlog(void)
|
||||
{
|
||||
int i;
|
||||
int x = CurPage->xsize;
|
||||
@@ -702,7 +702,7 @@ void WriteProlog(void)
|
||||
/* WriteCalEntry - write all entries for one day */
|
||||
/* */
|
||||
/***************************************************************/
|
||||
void WriteCalEntry(void)
|
||||
static void WriteCalEntry(void)
|
||||
{
|
||||
CalEntry *c = CurEntries;
|
||||
CalEntry *d;
|
||||
@@ -789,7 +789,7 @@ void WriteCalEntry(void)
|
||||
/* WriteOneEntry - write an entry for one day */
|
||||
/* */
|
||||
/***************************************************************/
|
||||
void WriteOneEntry(CalEntry *c)
|
||||
static void WriteOneEntry(CalEntry const *c)
|
||||
{
|
||||
int ch, i;
|
||||
char const *s = c->entry;
|
||||
@@ -851,7 +851,7 @@ void WriteOneEntry(CalEntry *c)
|
||||
/* Init - set up parameters */
|
||||
/* */
|
||||
/***************************************************************/
|
||||
void Init(int argc, char *argv[])
|
||||
static void Init(int argc, char const *argv[])
|
||||
{
|
||||
char const *s;
|
||||
char const *t;
|
||||
@@ -1043,7 +1043,7 @@ void Usage(char const *s)
|
||||
/* month. */
|
||||
/* */
|
||||
/***************************************************************/
|
||||
void DoSmallCal(char const *m, int days, int first, int col, int which)
|
||||
static void DoSmallCal(char const *m, int days, int first, int col, int which)
|
||||
{
|
||||
/* Do the small calendar */
|
||||
int i, j;
|
||||
@@ -1097,7 +1097,7 @@ void DoSmallCal(char const *m, int days, int first, int col, int which)
|
||||
/* DoQueuedPs - do the queued PS and PSFILE reminders. */
|
||||
/* */
|
||||
/***************************************************************/
|
||||
int DoQueuedPs(void)
|
||||
static int DoQueuedPs(void)
|
||||
{
|
||||
int i;
|
||||
int HadPS = 0;
|
||||
@@ -1305,7 +1305,7 @@ int DoQueuedPs(void)
|
||||
/* Set up the locations for the small calendars. */
|
||||
/* */
|
||||
/***************************************************************/
|
||||
void GetSmallLocations(void)
|
||||
static void GetSmallLocations(void)
|
||||
{
|
||||
char c;
|
||||
char const *s = SmallLocation;
|
||||
@@ -1370,7 +1370,7 @@ void GetSmallLocations(void)
|
||||
/* Read a space-delimited token into an output buffer. */
|
||||
/* */
|
||||
/***************************************************************/
|
||||
char const *EatToken(char const *in, char *out, int maxlen)
|
||||
static char const *EatToken(char const *in, char *out, int maxlen)
|
||||
{
|
||||
int i = 0;
|
||||
|
||||
|
||||
21
src/token.c
21
src/token.c
@@ -27,11 +27,11 @@
|
||||
executes 'return' if an initial non-numeric char is found. */
|
||||
#define PARSENUM(var, string) \
|
||||
if (!isdigit(*(string))) return; \
|
||||
var = 0; \
|
||||
(var) = 0; \
|
||||
while (isdigit(*(string))) { \
|
||||
var *= 10; \
|
||||
var += *(string) - '0'; \
|
||||
string++; \
|
||||
(var) *= 10; \
|
||||
(var) += *(string) - '0'; \
|
||||
(string)++; \
|
||||
}
|
||||
|
||||
/* The big array holding all recognized (literal) tokens in reminder file.
|
||||
@@ -90,12 +90,16 @@ Token TokArray[] = {
|
||||
{ "omit", 4, T_Omit, 0 },
|
||||
{ "omitfunc", 8, T_OmitFunc, 0 },
|
||||
{ "once", 4, T_Once, 0 },
|
||||
{ "pop-funcs", 9, T_PopFuncs, 0 },
|
||||
{ "pop-omit-context", 3, T_Pop, 0 },
|
||||
{ "pop-vars", 8, T_PopVars, 0 },
|
||||
{ "preserve", 8, T_Preserve, 0 },
|
||||
{ "priority", 8, T_Priority, 0 },
|
||||
{ "ps", 2, T_RemType, PS_TYPE },
|
||||
{ "psfile", 6, T_RemType, PSF_TYPE },
|
||||
{ "psfile", 6, T_RemType, PSF_TYPE },
|
||||
{ "push-funcs", 10, T_PushFuncs, 0 },
|
||||
{ "push-omit-context", 4, T_Push, 0 },
|
||||
{ "push-vars", 9, T_PushVars, 0 },
|
||||
{ "rem", 3, T_Rem, 0 },
|
||||
{ "run", 3, T_RemType, RUN_TYPE },
|
||||
{ "satisfy", 7, T_RemType, SAT_TYPE },
|
||||
@@ -122,6 +126,7 @@ Token TokArray[] = {
|
||||
};
|
||||
|
||||
static int TokStrCmp (Token const *t, char const *s);
|
||||
static void FindNumericToken(char const *s, Token *t);
|
||||
|
||||
static void
|
||||
init_token(Token *t)
|
||||
@@ -247,7 +252,7 @@ void FindToken(char const *s, Token *tok)
|
||||
/* Rep - *n */
|
||||
/* */
|
||||
/***************************************************************/
|
||||
void FindNumericToken(char const *s, Token *t)
|
||||
static void FindNumericToken(char const *s, Token *t)
|
||||
{
|
||||
int mult = 1, hour, min;
|
||||
char const *s_orig = s;
|
||||
@@ -443,7 +448,7 @@ static int TokStrCmp(Token const *t, char const *s)
|
||||
}
|
||||
|
||||
static void
|
||||
print_token(Token *tok)
|
||||
print_token(Token const *tok)
|
||||
{
|
||||
if (tok->MinLen < (int) strlen(tok->name)) {
|
||||
printf("%.*s\n", tok->MinLen, tok->name);
|
||||
@@ -455,7 +460,7 @@ void
|
||||
print_remind_tokens(void)
|
||||
{
|
||||
int i;
|
||||
Token *tok;
|
||||
Token const *tok;
|
||||
int num = (int) (sizeof(TokArray) / sizeof(TokArray[0]));
|
||||
printf("# Remind Tokens\n\n");
|
||||
for (i=0; i<num; i++) {
|
||||
|
||||
12
src/trans.c
12
src/trans.c
@@ -272,17 +272,17 @@ DumpTranslationTable(FILE *fp, int json)
|
||||
}
|
||||
|
||||
static unsigned int
|
||||
HashXlateItem(void *x)
|
||||
HashXlateItem(void const *x)
|
||||
{
|
||||
XlateItem *item = (XlateItem *) x;
|
||||
XlateItem const *item = (XlateItem const *) x;
|
||||
return HashVal_preservecase(item->orig);
|
||||
}
|
||||
|
||||
static int
|
||||
CompareXlateItems(void *a, void *b)
|
||||
CompareXlateItems(void const *a, void const *b)
|
||||
{
|
||||
XlateItem *i = (XlateItem *) a;
|
||||
XlateItem *j = (XlateItem *) b;
|
||||
XlateItem const *i = (XlateItem const *) a;
|
||||
XlateItem const *j = (XlateItem const *) b;
|
||||
return strcmp(i->orig, j->orig);
|
||||
}
|
||||
|
||||
@@ -339,7 +339,7 @@ InsertTranslation(char const *orig, char const *translated)
|
||||
char const *
|
||||
GetTranslatedString(char const *orig)
|
||||
{
|
||||
XlateItem *item = FindTranslation(orig);
|
||||
XlateItem const *item = FindTranslation(orig);
|
||||
if (!item) return NULL;
|
||||
return item->translated;
|
||||
}
|
||||
|
||||
@@ -29,8 +29,10 @@
|
||||
|
||||
static int DSEYear(int dse);
|
||||
static int DSEMonth(int dse);
|
||||
static int NextSimpleTrig(int startdate, Trigger *trig, int *err);
|
||||
static int NextSimpleTrig(int startdate, Trigger const *trig, int *err);
|
||||
static int GetNextTriggerDate(Trigger *trig, int start, int *err, int *nextstart);
|
||||
static int TrigInfoIsValid(char const *info);
|
||||
static int TrigInfoHeadersAreTheSame(char const *i1, char const *i2);
|
||||
|
||||
/***************************************************************/
|
||||
/* */
|
||||
@@ -44,7 +46,7 @@ static int GetNextTriggerDate(Trigger *trig, int start, int *err, int *nextstart
|
||||
/* so that dates with a REP can be handled properly. */
|
||||
/* */
|
||||
/***************************************************************/
|
||||
static int NextSimpleTrig(int startdate, Trigger *trig, int *err)
|
||||
static int NextSimpleTrig(int startdate, Trigger const *trig, int *err)
|
||||
{
|
||||
int typ = 0;
|
||||
int d, m, y, j, d2, m2, y2;
|
||||
@@ -310,15 +312,15 @@ static int GetNextTriggerDate(Trigger *trig, int start, int *err, int *nextstart
|
||||
{
|
||||
int simple, mod, omit;
|
||||
|
||||
/* First: Have we passed the UNTIL date? */
|
||||
/* First: Have we passed the UNTIL date? */
|
||||
if (trig->until != NO_UNTIL &&
|
||||
trig->until < start) {
|
||||
trig->expired = 1;
|
||||
return -1; /* expired */
|
||||
}
|
||||
|
||||
/* Next: If it's an "AFTER"-type skip, back up
|
||||
until we're at the start of a block of holidays */
|
||||
/* Next: If it's an "AFTER"-type skip, back up
|
||||
until we're at the start of a block of holidays */
|
||||
if (trig->skip == AFTER_SKIP) {
|
||||
int iter = 0;
|
||||
while (iter++ <= MaxSatIter) {
|
||||
@@ -339,16 +341,16 @@ static int GetNextTriggerDate(Trigger *trig, int start, int *err, int *nextstart
|
||||
}
|
||||
}
|
||||
|
||||
/* Find the next simple trigger */
|
||||
/* Find the next simple trigger */
|
||||
simple = NextSimpleTrig(start, trig, err);
|
||||
|
||||
/* Problems? */
|
||||
/* Problems? */
|
||||
if (*err || (simple == -1)) return -1;
|
||||
|
||||
/* Suggested starting point for next attempt */
|
||||
/* Suggested starting point for next attempt */
|
||||
*nextstart = simple+1;
|
||||
|
||||
/* If there's a BACK, back up... */
|
||||
/* If there's a BACK, back up... */
|
||||
if (trig->back != NO_BACK) {
|
||||
mod = trig->back;
|
||||
if (mod < 0) {
|
||||
@@ -376,7 +378,7 @@ static int GetNextTriggerDate(Trigger *trig, int start, int *err, int *nextstart
|
||||
}
|
||||
}
|
||||
|
||||
/* If there's a REP, calculate the next occurrence */
|
||||
/* If there's a REP, calculate the next occurrence */
|
||||
if (trig->rep != NO_REP) {
|
||||
if (simple < start) {
|
||||
mod = (start - simple) / trig->rep;
|
||||
@@ -385,7 +387,7 @@ static int GetNextTriggerDate(Trigger *trig, int start, int *err, int *nextstart
|
||||
}
|
||||
}
|
||||
|
||||
/* If it's a "BEFORE"-type skip, back up */
|
||||
/* If it's a "BEFORE"-type skip, back up */
|
||||
if (trig->skip == BEFORE_SKIP) {
|
||||
int iter = 0;
|
||||
while(iter++ <= MaxSatIter) {
|
||||
@@ -406,7 +408,7 @@ static int GetNextTriggerDate(Trigger *trig, int start, int *err, int *nextstart
|
||||
}
|
||||
}
|
||||
|
||||
/* If it's an "AFTER"-type skip, jump ahead */
|
||||
/* If it's an "AFTER"-type skip, jump ahead */
|
||||
if (trig->skip == AFTER_SKIP) {
|
||||
int iter = 0;
|
||||
while (iter++ <= MaxSatIter) {
|
||||
@@ -423,7 +425,12 @@ static int GetNextTriggerDate(Trigger *trig, int start, int *err, int *nextstart
|
||||
}
|
||||
}
|
||||
|
||||
/* Return the date */
|
||||
/* If we've passed the UNTIL, then it's expired */
|
||||
if (trig->until != NO_UNTIL && simple > trig->until) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* Return the date */
|
||||
return simple;
|
||||
}
|
||||
|
||||
@@ -453,7 +460,7 @@ AdjustTriggerForDuration(int today, int r, Trigger *trig, TimeTrig *tim, int sav
|
||||
if (DebugFlag & DB_PRTTRIG) {
|
||||
FromDSE(r, &y, &m, &d);
|
||||
fprintf(ErrFp, "%s(%s): Trig(adj) = %s, %d %s, %d",
|
||||
FileName, line_range(LineNoStart, LineNo),
|
||||
GetCurrentFilename(), line_range(LineNoStart, LineNo),
|
||||
get_day_name(r % 7),
|
||||
d,
|
||||
get_month_name(m),
|
||||
@@ -524,7 +531,7 @@ int ComputeTrigger(int today, Trigger *trig, TimeTrig *tim,
|
||||
/* duration. */
|
||||
/* */
|
||||
/***************************************************************/
|
||||
int ComputeTriggerNoAdjustDuration(int today, Trigger *trig, TimeTrig *tim,
|
||||
int ComputeTriggerNoAdjustDuration(int today, Trigger *trig, TimeTrig const *tim,
|
||||
int *err, int save_in_globals, int duration_days)
|
||||
{
|
||||
int nattempts = 0,
|
||||
@@ -536,6 +543,7 @@ int ComputeTriggerNoAdjustDuration(int today, Trigger *trig, TimeTrig *tim,
|
||||
trig->expired = 0;
|
||||
if (save_in_globals) {
|
||||
LastTrigValid = 0;
|
||||
LastTriggerDate = -1;
|
||||
}
|
||||
|
||||
/* Assume everything works */
|
||||
@@ -574,14 +582,13 @@ int ComputeTriggerNoAdjustDuration(int today, Trigger *trig, TimeTrig *tim,
|
||||
|
||||
while (nattempts++ < TRIG_ATTEMPTS) {
|
||||
result = GetNextTriggerDate(trig, start, err, &nextstart);
|
||||
|
||||
/* If there's an error, die immediately */
|
||||
if (*err) return -1;
|
||||
if (result == -1) {
|
||||
trig->expired = 1;
|
||||
if (DebugFlag & DB_PRTTRIG) {
|
||||
fprintf(ErrFp, "%s(%s): %s\n",
|
||||
FileName, line_range(LineNoStart, LineNo), GetErr(E_EXPIRED));
|
||||
GetCurrentFilename(), line_range(LineNoStart, LineNo), GetErr(E_EXPIRED));
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
@@ -604,7 +611,7 @@ int ComputeTriggerNoAdjustDuration(int today, Trigger *trig, TimeTrig *tim,
|
||||
if (DebugFlag & DB_PRTTRIG) {
|
||||
FromDSE(result, &y, &m, &d);
|
||||
fprintf(ErrFp, "%s(%s): Trig = %s, %d %s, %d",
|
||||
FileName, line_range(LineNoStart, LineNo),
|
||||
GetCurrentFilename(), line_range(LineNoStart, LineNo),
|
||||
get_day_name(result % 7),
|
||||
d,
|
||||
get_month_name(m),
|
||||
@@ -630,8 +637,9 @@ int ComputeTriggerNoAdjustDuration(int today, Trigger *trig, TimeTrig *tim,
|
||||
trig->rep == NO_REP) {
|
||||
trig->expired = 1;
|
||||
if (DebugFlag & DB_PRTTRIG) {
|
||||
fprintf(ErrFp, "%s(%s): %s\n",
|
||||
FileName, line_range(LineNoStart, LineNo), GetErr(E_EXPIRED));
|
||||
FromDSE(result, &y, &m, &d);
|
||||
fprintf(ErrFp, "%s(%s): %s: %04d-%02d-%02d\n",
|
||||
GetCurrentFilename(), line_range(LineNoStart, LineNo), GetErr(E_EXPIRED), y, m+1, d);
|
||||
}
|
||||
if (save_in_globals) {
|
||||
LastTriggerDate = result;
|
||||
@@ -656,7 +664,7 @@ int ComputeTriggerNoAdjustDuration(int today, Trigger *trig, TimeTrig *tim,
|
||||
trig->expired = 1;
|
||||
if (DebugFlag & DB_PRTTRIG) {
|
||||
fprintf(ErrFp, "%s(%s): %s\n",
|
||||
FileName, line_range(LineNoStart, LineNo), GetErr(E_EXPIRED));
|
||||
GetCurrentFilename(), line_range(LineNoStart, LineNo), GetErr(E_EXPIRED));
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
@@ -677,7 +685,7 @@ int ComputeTriggerNoAdjustDuration(int today, Trigger *trig, TimeTrig *tim,
|
||||
/* Returns NULL if memory allocation fails. */
|
||||
/* */
|
||||
/***************************************************************/
|
||||
TrigInfo *
|
||||
static TrigInfo *
|
||||
NewTrigInfo(char const *i)
|
||||
{
|
||||
TrigInfo *ti = malloc(sizeof(TrigInfo));
|
||||
@@ -701,7 +709,7 @@ NewTrigInfo(char const *i)
|
||||
/* Free a TrigInfo objects. */
|
||||
/* */
|
||||
/***************************************************************/
|
||||
void
|
||||
static void
|
||||
FreeTrigInfo(TrigInfo *ti)
|
||||
{
|
||||
if (ti->info) {
|
||||
@@ -768,7 +776,7 @@ AppendTrigInfo(Trigger *t, char const *info)
|
||||
return OK;
|
||||
}
|
||||
|
||||
int
|
||||
static int
|
||||
TrigInfoHeadersAreTheSame(char const *i1, char const *i2)
|
||||
{
|
||||
char const *c1 = strchr(i1, ':');
|
||||
@@ -779,7 +787,7 @@ TrigInfoHeadersAreTheSame(char const *i1, char const *i2)
|
||||
return 0;
|
||||
}
|
||||
|
||||
int
|
||||
static int
|
||||
TrigInfoIsValid(char const *info)
|
||||
{
|
||||
char const *t;
|
||||
|
||||
30
src/types.h
30
src/types.h
@@ -105,7 +105,10 @@ typedef struct var {
|
||||
struct hash_link link;
|
||||
char name[VAR_NAME_LEN+1];
|
||||
char preserve;
|
||||
char nonconstant;
|
||||
char is_constant;
|
||||
char used_since_set;
|
||||
char const *filename;
|
||||
int lineno;
|
||||
Value v;
|
||||
} Var;
|
||||
|
||||
@@ -218,19 +221,22 @@ typedef Parser *ParsePtr; /* Pointer to parser structure */
|
||||
#define DB_HASHSTATS 0x080
|
||||
#define DB_TRANSLATE 0x100
|
||||
#define DB_NONCONST 0x200
|
||||
#define DB_UNUSED_VARS 0x400
|
||||
|
||||
/* Enumeration of the tokens */
|
||||
enum TokTypes
|
||||
{ T_Illegal,
|
||||
T_AddOmit, T_At, T_Back, T_BackAdj, T_Banner, T_Clr, T_Comment,
|
||||
T_Date, T_DateTime, T_Day, T_Debug, T_Delta, T_Dumpvars, T_Duration,
|
||||
T_Else, T_Empty, T_EndIf, T_ErrMsg, T_Exit, T_Expr,
|
||||
T_Flush, T_Frename, T_Fset, T_Funset, T_If, T_IfTrig, T_In,
|
||||
T_Include, T_IncludeCmd, T_IncludeR, T_IncludeSys, T_Info, T_LastBack,
|
||||
T_LongTime, T_MaybeUncomputable, T_Month, T_NoQueue, T_Number, T_Omit,
|
||||
T_OmitFunc, T_Once, T_Ordinal, T_Pop, T_Preserve, T_Priority, T_Push,T_Rem,
|
||||
T_RemType, T_Rep, T_Scanfrom, T_Sched, T_Set, T_Skip, T_Tag, T_Through,
|
||||
T_Time, T_Translate, T_UnSet, T_Until, T_Warn, T_WkDay, T_Year
|
||||
T_Else, T_Empty, T_EndIf, T_ErrMsg, T_Exit, T_Expr, T_Flush,
|
||||
T_Frename, T_Fset, T_Funset, T_If, T_IfTrig, T_In, T_Include,
|
||||
T_IncludeCmd, T_IncludeR, T_IncludeSys, T_Info, T_LastBack,
|
||||
T_LongTime, T_MaybeUncomputable, T_Month, T_NoQueue, T_Number,
|
||||
T_Omit, T_OmitFunc, T_Once, T_Ordinal, T_Pop, T_PopFuncs, T_PopVars,
|
||||
T_Preserve, T_Priority, T_Push, T_PushFuncs, T_PushVars, T_Rem,
|
||||
T_RemType, T_Rep, T_Scanfrom, T_Sched, T_Set, T_Skip, T_Tag,
|
||||
T_Through, T_Time, T_Translate, T_UnSet, T_Until, T_Warn, T_WkDay,
|
||||
T_Year
|
||||
};
|
||||
|
||||
/* The structure of a token */
|
||||
@@ -252,6 +258,7 @@ typedef struct {
|
||||
#define RUN_CMDLINE 0x01
|
||||
#define RUN_SCRIPT 0x02
|
||||
#define RUN_NOTOWNER 0x04
|
||||
#define RUN_IN_EVAL 0x08
|
||||
|
||||
/* Flags for the SimpleCalendar format */
|
||||
#define SC_AMPM 0 /* Time shown as 3:00am, etc. */
|
||||
@@ -305,4 +312,11 @@ typedef struct udf_struct {
|
||||
int lineno;
|
||||
int lineno_start;
|
||||
int recurse_flag;
|
||||
int been_pushed;
|
||||
} UserFunc;
|
||||
|
||||
/* A pushed systtem variable */
|
||||
typedef struct {
|
||||
char const *name;
|
||||
Value v;
|
||||
} PushedSysvar;
|
||||
|
||||
280
src/userfns.c
280
src/userfns.c
@@ -36,16 +36,16 @@ static void FUnset (char const *name);
|
||||
static void FSet (UserFunc *f);
|
||||
static void RenameUserFunc(char const *oldname, char const *newname);
|
||||
|
||||
static unsigned int HashUserFunc(void *x)
|
||||
static unsigned int HashUserFunc(void const *x)
|
||||
{
|
||||
UserFunc *f = (UserFunc *) x;
|
||||
UserFunc const *f = (UserFunc const *) x;
|
||||
return HashVal_preservecase(f->name);
|
||||
}
|
||||
|
||||
static int CompareUserFuncs(void *a, void *b)
|
||||
static int CompareUserFuncs(void const *a, void const *b)
|
||||
{
|
||||
UserFunc *f = (UserFunc *) a;
|
||||
UserFunc *g = (UserFunc *) b;
|
||||
UserFunc const *f = (UserFunc const *) a;
|
||||
UserFunc const *g = (UserFunc const *) b;
|
||||
return strcmp(f->name, g->name);
|
||||
}
|
||||
|
||||
@@ -181,12 +181,34 @@ int DoFset(ParsePtr p)
|
||||
Var *locals = NULL;
|
||||
Var local_array[MAX_FUNC_ARGS];
|
||||
int orig_namelen;
|
||||
int suppress_redefined_function_warning = 0;
|
||||
int ch;
|
||||
|
||||
DynamicBuffer buf;
|
||||
DBufInit(&buf);
|
||||
|
||||
|
||||
ch = ParseNonSpaceChar(p, &r, 1);
|
||||
if (r) {
|
||||
return r;
|
||||
}
|
||||
if (ch == '-') {
|
||||
r = ParseToken(p, &buf);
|
||||
if (r) {
|
||||
return r;
|
||||
}
|
||||
if (strcmp(DBufValue(&buf), "-")) {
|
||||
DBufFree(&buf);
|
||||
return E_PARSE_ERR;
|
||||
}
|
||||
suppress_redefined_function_warning = 1;
|
||||
DBufFree(&buf);
|
||||
}
|
||||
|
||||
/* Get the function name */
|
||||
if ( (r=ParseIdentifier(p, &buf)) ) return r;
|
||||
if ( (r=ParseIdentifier(p, &buf)) ) {
|
||||
return r;
|
||||
}
|
||||
if (*DBufValue(&buf) == '$') {
|
||||
DBufFree(&buf);
|
||||
return E_BAD_ID;
|
||||
@@ -214,7 +236,7 @@ int DoFset(ParsePtr p)
|
||||
file, do nothing */
|
||||
existing = FindUserFunc(DBufValue(&buf));
|
||||
if (existing) {
|
||||
if (!strcmp(existing->filename, FileName) &&
|
||||
if (!strcmp(existing->filename, GetCurrentFilename()) &&
|
||||
strcmp(existing->filename, "[cmdline]") &&
|
||||
existing->lineno == LineNo) {
|
||||
DBufFree(&buf);
|
||||
@@ -222,8 +244,10 @@ int DoFset(ParsePtr p)
|
||||
return OK;
|
||||
}
|
||||
/* Warn about redefinition */
|
||||
Wprint(tr("Function `%s' redefined: previously defined at %s(%s)"),
|
||||
existing->name, existing->filename, line_range(existing->lineno_start, existing->lineno));
|
||||
if (!suppress_redefined_function_warning && !existing->been_pushed) {
|
||||
Wprint(tr("Function `%s' redefined: previously defined at %s(%s)"),
|
||||
existing->name, existing->filename, line_range(existing->lineno_start, existing->lineno));
|
||||
}
|
||||
}
|
||||
|
||||
/* Should be followed by '(' */
|
||||
@@ -242,18 +266,15 @@ int DoFset(ParsePtr p)
|
||||
DBufFree(&buf);
|
||||
return E_NO_MEM;
|
||||
}
|
||||
if (FileName) {
|
||||
func->filename = StrDup(FileName);
|
||||
if (GetCurrentFilename()) {
|
||||
func->filename = GetCurrentFilename();
|
||||
} else {
|
||||
func->filename = StrDup("[cmdline]");
|
||||
}
|
||||
if (!func->filename) {
|
||||
free(func);
|
||||
return E_NO_MEM;
|
||||
func->filename = "[cmdline]";
|
||||
}
|
||||
func->lineno = LineNo;
|
||||
func->lineno_start = LineNoStart;
|
||||
func->recurse_flag = 0;
|
||||
func->been_pushed = 0;
|
||||
if (in_constant_context()) {
|
||||
func->is_constant = 1;
|
||||
} else {
|
||||
@@ -358,6 +379,10 @@ int DoFset(ParsePtr p)
|
||||
/* Save the argument names */
|
||||
if (func->nargs) {
|
||||
func->args = calloc(func->nargs, sizeof(char *));
|
||||
if (!func->args) {
|
||||
DestroyUserFunc(func);
|
||||
return E_NO_MEM;
|
||||
}
|
||||
for (i=0; i<func->nargs; i++) {
|
||||
func->args[i] = StrDup(local_array[i].name);
|
||||
if (!func->args[i]) {
|
||||
@@ -393,9 +418,6 @@ static void DestroyUserFunc(UserFunc *f)
|
||||
/* Free the function definition */
|
||||
if (f->node) free_expr_tree(f->node);
|
||||
|
||||
/* Free the filename */
|
||||
if (f->filename) free( (char *) f->filename);
|
||||
|
||||
/* Free arg names */
|
||||
if (f->args) {
|
||||
for (i=0; i<f->nargs; i++) {
|
||||
@@ -532,3 +554,223 @@ dump_userfunc_hash_stats(void)
|
||||
hash_table_dump_stats(&FuncHash, ErrFp);
|
||||
}
|
||||
|
||||
typedef struct pushed_userfuncs {
|
||||
struct pushed_userfuncs *next;
|
||||
char const *filename;
|
||||
int lineno;
|
||||
int num_funcs;
|
||||
int alloc_funcs;
|
||||
UserFunc **funcs;
|
||||
} PushedUserFuncs;
|
||||
|
||||
static PushedUserFuncs *UserFuncStack = NULL;
|
||||
static UserFunc *clone_userfunc(char const *name, int *r)
|
||||
{
|
||||
int i;
|
||||
UserFunc *src;
|
||||
UserFunc *dest = NEW(UserFunc);
|
||||
*r = E_NO_MEM;
|
||||
if (!dest) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/* Find the source function */
|
||||
src = FindUserFunc(name);
|
||||
|
||||
/* If it doesn't exist, use sentinal values to indicate that */
|
||||
if (!src) {
|
||||
*r = OK;
|
||||
StrnCpy(dest->name, name, VAR_NAME_LEN);
|
||||
dest->is_constant = 0;
|
||||
dest->node = NULL;
|
||||
dest->args = NULL;
|
||||
dest->nargs = -1;
|
||||
dest->filename = NULL;
|
||||
dest->lineno = -1;
|
||||
dest->lineno_start = -1;
|
||||
dest->recurse_flag = 0;
|
||||
dest->been_pushed = 0;
|
||||
return dest;
|
||||
}
|
||||
/* Copy the whole thing; then adjust */
|
||||
*dest = *src;
|
||||
|
||||
/* Allow warning-free redefinition of original function */
|
||||
src->been_pushed = 1;
|
||||
|
||||
/* For safety */
|
||||
dest->node = NULL;
|
||||
dest->args = NULL;
|
||||
|
||||
/* Copy args */
|
||||
if (dest->nargs) {
|
||||
dest->args = calloc(dest->nargs, sizeof(char *));
|
||||
if (!dest->args) {
|
||||
DestroyUserFunc(dest);
|
||||
return NULL;
|
||||
}
|
||||
for (i=0; i<dest->nargs; i++) {
|
||||
dest->args[i] = StrDup(src->args[i]);
|
||||
if (!dest->args[i]) {
|
||||
DestroyUserFunc(dest);
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* Copy expr */
|
||||
dest->node = clone_expr_tree(src->node, r);
|
||||
if (!dest->node) {
|
||||
DestroyUserFunc(dest);
|
||||
return NULL;
|
||||
}
|
||||
*r = OK;
|
||||
return dest;
|
||||
}
|
||||
|
||||
static int add_func_to_push(char const *name, PushedUserFuncs *pf)
|
||||
{
|
||||
int r;
|
||||
UserFunc *clone = clone_userfunc(name, &r);
|
||||
if (!clone) {
|
||||
return r;
|
||||
}
|
||||
if (!pf->alloc_funcs) {
|
||||
pf->funcs = calloc(4, sizeof(UserFunc *));
|
||||
if (!pf->funcs) {
|
||||
DestroyUserFunc(clone);
|
||||
return E_NO_MEM;
|
||||
}
|
||||
pf->alloc_funcs = 4;
|
||||
} else {
|
||||
if (pf->num_funcs == pf->alloc_funcs) {
|
||||
pf->funcs = realloc(pf->funcs, 2 * pf->alloc_funcs * sizeof(UserFunc *));
|
||||
if (!pf->funcs) {
|
||||
DestroyUserFunc(clone);
|
||||
return E_NO_MEM;
|
||||
}
|
||||
pf->alloc_funcs *= 2;
|
||||
}
|
||||
}
|
||||
pf->funcs[pf->num_funcs] = clone;
|
||||
pf->num_funcs++;
|
||||
return OK;
|
||||
}
|
||||
|
||||
static void free_pushed_funcs(PushedUserFuncs *pf)
|
||||
{
|
||||
int i;
|
||||
if (pf->funcs) {
|
||||
for(i=0; i<pf->num_funcs; i++) {
|
||||
if (pf->funcs[i]) {
|
||||
DestroyUserFunc(pf->funcs[i]);
|
||||
}
|
||||
}
|
||||
free(pf->funcs);
|
||||
}
|
||||
free(pf);
|
||||
}
|
||||
|
||||
int PushUserFuncs(ParsePtr p)
|
||||
{
|
||||
int r;
|
||||
DynamicBuffer buf;
|
||||
char const *name;
|
||||
|
||||
DBufInit(&buf);
|
||||
PushedUserFuncs *pf = NEW(PushedUserFuncs);
|
||||
if (!pf) {
|
||||
return E_NO_MEM;
|
||||
}
|
||||
pf->next = NULL;
|
||||
pf->funcs = NULL;
|
||||
pf->filename = GetCurrentFilename();
|
||||
pf->lineno = LineNo;
|
||||
pf->num_funcs = 0;
|
||||
pf->alloc_funcs = 0;
|
||||
|
||||
while(1) {
|
||||
r = ParseIdentifier(p, &buf);
|
||||
if (r == E_EOLN) {
|
||||
break;
|
||||
}
|
||||
if (r) {
|
||||
DBufFree(&buf);
|
||||
free_pushed_funcs(pf);
|
||||
return r;
|
||||
}
|
||||
name = DBufValue(&buf);
|
||||
if (*name == '$') {
|
||||
DBufFree(&buf);
|
||||
free_pushed_funcs(pf);
|
||||
return E_BAD_ID;
|
||||
}
|
||||
|
||||
r = add_func_to_push(name, pf);
|
||||
|
||||
DBufFree(&buf);
|
||||
if (r != OK) {
|
||||
free_pushed_funcs(pf);
|
||||
return r;
|
||||
}
|
||||
}
|
||||
if (pf->num_funcs == 0) {
|
||||
free_pushed_funcs(pf);
|
||||
return E_EOLN;
|
||||
}
|
||||
pf->next = UserFuncStack;
|
||||
UserFuncStack = pf;
|
||||
return OK;
|
||||
}
|
||||
|
||||
int PopUserFuncs(ParsePtr p)
|
||||
{
|
||||
int i;
|
||||
PushedUserFuncs *pf = UserFuncStack;
|
||||
int r = VerifyEoln(p);
|
||||
if (r != OK) {
|
||||
return r;
|
||||
}
|
||||
if (!pf) {
|
||||
return E_POPF_NO_PUSH;
|
||||
}
|
||||
UserFuncStack = UserFuncStack->next;
|
||||
if (strcmp(pf->filename, GetCurrentFilename())) {
|
||||
Wprint(tr("POP-FUNCS at %s:%d matches PUSH-FUNCS in different file: %s:%d"), GetCurrentFilename(), LineNo, pf->filename, pf->lineno);
|
||||
}
|
||||
for (i=0; i<pf->num_funcs; i++) {
|
||||
UserFunc *clone = pf->funcs[i];
|
||||
FUnset(clone->name);
|
||||
if (clone->nargs < 0 && !clone->node) {
|
||||
/* Popping a function that should simply be unset... we are done */
|
||||
continue;
|
||||
}
|
||||
|
||||
/* Insert the clone into the hash table */
|
||||
FSet(clone);
|
||||
|
||||
/* Make sure we don't free the clone! */
|
||||
pf->funcs[i] = NULL;
|
||||
}
|
||||
free_pushed_funcs(pf);
|
||||
return OK;
|
||||
}
|
||||
|
||||
int EmptyUserFuncStack(int print_unmatched)
|
||||
{
|
||||
int j = 0;
|
||||
PushedUserFuncs *next;
|
||||
while(UserFuncStack) {
|
||||
if (print_unmatched) {
|
||||
Wprint(tr("Unmatched PUSH-FUNCS at %s(%d)"),
|
||||
UserFuncStack->filename,
|
||||
UserFuncStack->lineno);
|
||||
}
|
||||
j++;
|
||||
next = UserFuncStack->next;
|
||||
free_pushed_funcs(UserFuncStack);
|
||||
UserFuncStack = next;
|
||||
}
|
||||
return j;
|
||||
}
|
||||
|
||||
|
||||
@@ -247,7 +247,7 @@ print_callstack_aux(FILE *fp, cs *entry)
|
||||
{
|
||||
int i = 0;
|
||||
char const *in = tr("In");
|
||||
cs *prev = NULL;
|
||||
cs const *prev = NULL;
|
||||
while(entry) {
|
||||
if (prev) {
|
||||
in = tr("Called from");
|
||||
|
||||
388
src/var.c
388
src/var.c
@@ -37,14 +37,16 @@ static int IntMax = INT_MAX;
|
||||
|
||||
static hash_table VHashTbl;
|
||||
static int SetSysVarHelper(SysVar *v, Value *value);
|
||||
static unsigned int HashVal_ignorecase(char const *str);
|
||||
static void set_lat_and_long_from_components(void);
|
||||
|
||||
static unsigned int VarHashFunc(void *x)
|
||||
static unsigned int VarHashFunc(void const *x)
|
||||
{
|
||||
Var *v = (Var *) x;
|
||||
Var const *v = (Var const *) x;
|
||||
return HashVal_ignorecase(v->name);
|
||||
}
|
||||
|
||||
static int VarCompareFunc(void *a, void *b)
|
||||
static int VarCompareFunc(void const *a, void const *b)
|
||||
{
|
||||
Var *x = (Var *) a;
|
||||
Var *y = (Var *) b;
|
||||
@@ -153,7 +155,7 @@ static int latitude_longitude_func(int do_set, Value *val, double *var, double m
|
||||
if (loc) {
|
||||
setlocale(LC_NUMERIC, "C");
|
||||
}
|
||||
snprintf(buf, sizeof(buf), "%f", *var);
|
||||
snprintf(buf, sizeof(buf), "%.8f", *var);
|
||||
if (loc) {
|
||||
setlocale(LC_NUMERIC, loc);
|
||||
}
|
||||
@@ -285,7 +287,7 @@ static int trig_until_func(int do_set, Value *val)
|
||||
|
||||
static int trig_day_func(int do_set, Value *val)
|
||||
{
|
||||
int y, m, d;
|
||||
int d;
|
||||
UNUSED(do_set);
|
||||
val->type = INT_TYPE;
|
||||
if (!LastTrigValid) {
|
||||
@@ -293,7 +295,7 @@ static int trig_day_func(int do_set, Value *val)
|
||||
return OK;
|
||||
}
|
||||
|
||||
FromDSE(LastTriggerDate, &y, &m, &d);
|
||||
FromDSE(LastTriggerDate, NULL, NULL, &d);
|
||||
val->v.val = d;
|
||||
return OK;
|
||||
}
|
||||
@@ -312,7 +314,7 @@ static int timet_is_64_func(int do_set, Value *val)
|
||||
|
||||
static int trig_mon_func(int do_set, Value *val)
|
||||
{
|
||||
int y, m, d;
|
||||
int m;
|
||||
UNUSED(do_set);
|
||||
val->type = INT_TYPE;
|
||||
if (!LastTrigValid) {
|
||||
@@ -320,14 +322,14 @@ static int trig_mon_func(int do_set, Value *val)
|
||||
return OK;
|
||||
}
|
||||
|
||||
FromDSE(LastTriggerDate, &y, &m, &d);
|
||||
FromDSE(LastTriggerDate, NULL, &m, NULL);
|
||||
val->v.val = m+1;
|
||||
return OK;
|
||||
}
|
||||
|
||||
static int trig_year_func(int do_set, Value *val)
|
||||
{
|
||||
int y, m, d;
|
||||
int y;
|
||||
UNUSED(do_set);
|
||||
val->type = INT_TYPE;
|
||||
if (!LastTrigValid) {
|
||||
@@ -335,7 +337,7 @@ static int trig_year_func(int do_set, Value *val)
|
||||
return OK;
|
||||
}
|
||||
|
||||
FromDSE(LastTriggerDate, &y, &m, &d);
|
||||
FromDSE(LastTriggerDate, &y, NULL, NULL);
|
||||
val->v.val = y;
|
||||
return OK;
|
||||
}
|
||||
@@ -362,30 +364,30 @@ static int today_date_func(int do_set, Value *val)
|
||||
}
|
||||
static int today_day_func(int do_set, Value *val)
|
||||
{
|
||||
int y, m, d;
|
||||
int d;
|
||||
UNUSED(do_set);
|
||||
val->type = INT_TYPE;
|
||||
FromDSE(DSEToday, &y, &m, &d);
|
||||
FromDSE(DSEToday, NULL, NULL, &d);
|
||||
val->v.val = d;
|
||||
return OK;
|
||||
}
|
||||
|
||||
static int today_mon_func(int do_set, Value *val)
|
||||
{
|
||||
int y, m, d;
|
||||
int m;
|
||||
UNUSED(do_set);
|
||||
val->type = INT_TYPE;
|
||||
FromDSE(DSEToday, &y, &m, &d);
|
||||
FromDSE(DSEToday, NULL, &m, NULL);
|
||||
val->v.val = m+1;
|
||||
return OK;
|
||||
}
|
||||
|
||||
static int today_year_func(int do_set, Value *val)
|
||||
{
|
||||
int y, m, d;
|
||||
int y;
|
||||
UNUSED(do_set);
|
||||
val->type = INT_TYPE;
|
||||
FromDSE(DSEToday, &y, &m, &d);
|
||||
FromDSE(DSEToday, &y, NULL, NULL);
|
||||
val->v.val = y;
|
||||
return OK;
|
||||
}
|
||||
@@ -523,7 +525,7 @@ static int time_sep_func(int do_set, Value *val)
|
||||
/* Given a string, compute the hash value case-insensitively */
|
||||
/* */
|
||||
/***************************************************************/
|
||||
unsigned int HashVal_ignorecase(char const *str)
|
||||
static unsigned int HashVal_ignorecase(char const *str)
|
||||
{
|
||||
unsigned int h = 0, high;
|
||||
while(*str) {
|
||||
@@ -560,6 +562,9 @@ Var *FindVar(char const *str, int create)
|
||||
v->v.type = INT_TYPE;
|
||||
v->v.v.val = 0;
|
||||
v->preserve = 0;
|
||||
v->is_constant = 1;
|
||||
v->filename = "";
|
||||
v->lineno = 0;
|
||||
StrnCpy(v->name, str, VAR_NAME_LEN);
|
||||
|
||||
hash_table_insert(&VHashTbl, v);
|
||||
@@ -573,12 +578,15 @@ Var *FindVar(char const *str, int create)
|
||||
/* string and delete it. */
|
||||
/* */
|
||||
/***************************************************************/
|
||||
int DeleteVar(char const *str)
|
||||
static int DeleteVar(char const *str)
|
||||
{
|
||||
Var *v;
|
||||
|
||||
v = FindVar(str, 0);
|
||||
if (!v) return E_NOSUCH_VAR;
|
||||
if ((DebugFlag & DB_UNUSED_VARS) && !v->used_since_set) {
|
||||
Eprint(tr("`%s' UNSET without being used (previous SET: %s:%d)"), str, v->filename, v->lineno);
|
||||
}
|
||||
DestroyValue(v->v);
|
||||
hash_table_delete(&VHashTbl, v);
|
||||
return OK;
|
||||
@@ -593,36 +601,29 @@ int DeleteVar(char const *str)
|
||||
/***************************************************************/
|
||||
int SetVar(char const *str, Value const *val, int nonconst_expr)
|
||||
{
|
||||
Var *v = FindVar(str, 1);
|
||||
Var *v = NULL;
|
||||
|
||||
if (DebugFlag & DB_UNUSED_VARS) {
|
||||
v = FindVar(str, 0);
|
||||
if (v && !(v->used_since_set)) {
|
||||
Eprint(tr("`%s' re-SET without being used (previous SET: %s:%d)"), str, v->filename, v->lineno);
|
||||
}
|
||||
}
|
||||
|
||||
if (!v) {
|
||||
v = FindVar(str, 1);
|
||||
}
|
||||
if (!v) return E_NO_MEM; /* Only way FindVar can fail */
|
||||
|
||||
DestroyValue(v->v);
|
||||
v->v = *val;
|
||||
v->nonconstant = nonconst_expr;
|
||||
v->is_constant = ! nonconst_expr;
|
||||
v->used_since_set = 0;
|
||||
v->filename = GetCurrentFilename();
|
||||
v->lineno = LineNo;
|
||||
return OK;
|
||||
}
|
||||
|
||||
/***************************************************************/
|
||||
/* */
|
||||
/* GetVarValue */
|
||||
/* */
|
||||
/* Get a copy of the value of the variable. */
|
||||
/* */
|
||||
/***************************************************************/
|
||||
int GetVarValue(char const *str, Value *val)
|
||||
{
|
||||
Var *v;
|
||||
|
||||
v=FindVar(str, 0);
|
||||
|
||||
if (!v) {
|
||||
Eprint("%s: `%s'", GetErr(E_NOSUCH_VAR), str);
|
||||
return E_NOSUCH_VAR;
|
||||
}
|
||||
return CopyValue(val, &v->v);
|
||||
}
|
||||
|
||||
/***************************************************************/
|
||||
/* */
|
||||
/* DoSet - set a variable. */
|
||||
@@ -641,7 +642,13 @@ int DoSet (Parser *p)
|
||||
Var *var;
|
||||
|
||||
r = ParseIdentifier(p, &buf);
|
||||
if (r) return r;
|
||||
if (r) {
|
||||
DBufFree(&buf);
|
||||
if (ignoring) {
|
||||
return OK;
|
||||
}
|
||||
return r;
|
||||
}
|
||||
|
||||
if (ignoring) {
|
||||
/* We're only here to mark a variable as non-const */
|
||||
@@ -651,8 +658,8 @@ int DoSet (Parser *p)
|
||||
}
|
||||
var = FindVar(DBufValue(&buf), 0);
|
||||
if (var) {
|
||||
nonconst_debug(var->nonconstant, tr("Potential variable assignment considered non-constant because of context"));
|
||||
var->nonconstant = 1;
|
||||
nonconst_debug(!var->is_constant, tr("Potential variable assignment considered non-constant because of context"));
|
||||
var->is_constant = 0;
|
||||
}
|
||||
DBufFree(&buf);
|
||||
return OK;
|
||||
@@ -785,7 +792,7 @@ int DoDump(ParsePtr p)
|
||||
fprintf(ErrFp, "%s ", v->name);
|
||||
PrintValue(&(v->v), ErrFp);
|
||||
if (dump_constness) {
|
||||
if (!v->nonconstant) {
|
||||
if (v->is_constant) {
|
||||
fprintf(ErrFp, " <const>");
|
||||
}
|
||||
}
|
||||
@@ -820,7 +827,7 @@ void DumpVarTable(int dump_constness)
|
||||
fprintf(ErrFp, "%s ", v->name);
|
||||
PrintValue(&(v->v), ErrFp);
|
||||
if (dump_constness) {
|
||||
if (!v->nonconstant) {
|
||||
if (v->is_constant) {
|
||||
fprintf(ErrFp, " <const>");
|
||||
}
|
||||
}
|
||||
@@ -828,6 +835,23 @@ void DumpVarTable(int dump_constness)
|
||||
}
|
||||
}
|
||||
|
||||
void DumpUnusedVars(void)
|
||||
{
|
||||
Var *v;
|
||||
int done_header = 0;
|
||||
|
||||
hash_table_for_each(v, &VHashTbl) {
|
||||
if (v->used_since_set) {
|
||||
continue;
|
||||
}
|
||||
if (!done_header) {
|
||||
fprintf(ErrFp, "%s\n", tr("The following variables were set, but not subsequently used:"));
|
||||
done_header = 1;
|
||||
}
|
||||
fprintf(ErrFp, "\t%s - %s %s:%d\n", v->name, tr("defined at"), v->filename, v->lineno);
|
||||
}
|
||||
}
|
||||
|
||||
/***************************************************************/
|
||||
/* */
|
||||
/* DestroyVars */
|
||||
@@ -871,6 +895,8 @@ int PreserveVar(char const *name)
|
||||
v = FindVar(name, 1);
|
||||
if (!v) return E_NO_MEM;
|
||||
v->preserve = 1;
|
||||
/* Assume we're gonna use the variable */
|
||||
v->used_since_set = 1;
|
||||
return OK;
|
||||
}
|
||||
|
||||
@@ -886,11 +912,10 @@ int DoPreserve (Parser *p)
|
||||
DynamicBuffer buf;
|
||||
DBufInit(&buf);
|
||||
|
||||
r = ParseToken(p, &buf);
|
||||
if (r) return r;
|
||||
if (!DBufLen(&buf)) {
|
||||
r = ParseIdentifier(p, &buf);
|
||||
if (r) {
|
||||
DBufFree(&buf);
|
||||
return E_EOLN;
|
||||
return r;
|
||||
}
|
||||
|
||||
r = PreserveVar(DBufValue(&buf));
|
||||
@@ -899,12 +924,14 @@ int DoPreserve (Parser *p)
|
||||
|
||||
/* Keep going... */
|
||||
while(1) {
|
||||
r = ParseToken(p, &buf);
|
||||
if (r) return r;
|
||||
if (!DBufLen(&buf)) {
|
||||
r = ParseIdentifier(p, &buf);
|
||||
if (r == E_EOLN) {
|
||||
DBufFree(&buf);
|
||||
return OK;
|
||||
}
|
||||
if (r) {
|
||||
return r;
|
||||
}
|
||||
r = PreserveVar(DBufValue(&buf));
|
||||
DBufFree(&buf);
|
||||
if (r) return r;
|
||||
@@ -1052,14 +1079,263 @@ static SysVar SysVarArr[] = {
|
||||
};
|
||||
|
||||
#define NUMSYSVARS ( sizeof(SysVarArr) / sizeof(SysVar) )
|
||||
|
||||
typedef struct pushed_vars {
|
||||
struct pushed_vars *next;
|
||||
char const *filename;
|
||||
int lineno;
|
||||
int num_sysvars;
|
||||
int num_vars;
|
||||
int alloc_sysvars;
|
||||
int alloc_vars;
|
||||
PushedSysvar *sysvars;
|
||||
Var *vars;
|
||||
} PushedVars;
|
||||
|
||||
static void free_pushedvars(PushedVars *pv);
|
||||
|
||||
static PushedVars *VarStack = NULL;
|
||||
|
||||
int EmptyVarStack(int print_unmatched)
|
||||
{
|
||||
int j=0;
|
||||
PushedVars *next;
|
||||
while(VarStack) {
|
||||
if (print_unmatched) {
|
||||
Wprint(tr("Unmatched PUSH-VARS at %s(%d)"),
|
||||
VarStack->filename,
|
||||
VarStack->lineno);
|
||||
}
|
||||
j++;
|
||||
next = VarStack->next;
|
||||
free_pushedvars(VarStack);
|
||||
VarStack = next;
|
||||
}
|
||||
return j;
|
||||
}
|
||||
|
||||
static int add_sysvar_to_push(char const *name, PushedVars *pv)
|
||||
{
|
||||
int n = pv->alloc_sysvars;
|
||||
if (*name == '$') {
|
||||
name++;
|
||||
}
|
||||
SysVar *v = FindSysVar(name);
|
||||
if (!v) {
|
||||
return E_NOSUCH_VAR;
|
||||
}
|
||||
if (!v->modifiable) {
|
||||
Eprint("%s: `$%s'", GetErr(E_CANT_MODIFY), v->name);
|
||||
return E_CANT_MODIFY;
|
||||
}
|
||||
if (!n) {
|
||||
n = 4;
|
||||
pv->sysvars = malloc(n * sizeof(PushedSysvar));
|
||||
pv->alloc_sysvars = n;
|
||||
} else {
|
||||
if (pv->num_sysvars >= n) {
|
||||
n *= 2;
|
||||
pv->sysvars = realloc(pv->sysvars, n * sizeof(PushedSysvar));
|
||||
pv->alloc_sysvars = n;
|
||||
}
|
||||
}
|
||||
if (!pv->sysvars) {
|
||||
return E_NO_MEM;
|
||||
}
|
||||
n = pv->num_sysvars;
|
||||
pv->num_sysvars++;
|
||||
pv->sysvars[n].name = v->name;
|
||||
pv->sysvars[n].v.type = ERR_TYPE;
|
||||
return GetSysVar(name, &(pv->sysvars[n].v));
|
||||
}
|
||||
|
||||
static int add_var_to_push(char const *name, PushedVars *pv)
|
||||
{
|
||||
int n = pv->alloc_vars;
|
||||
if (!n) {
|
||||
n = 4;
|
||||
pv->vars = malloc(n * sizeof(Var));
|
||||
pv->alloc_vars = n;
|
||||
} else {
|
||||
if (pv->num_vars >= n) {
|
||||
n *= 2;
|
||||
pv->vars = realloc(pv->vars, n * sizeof(Var));
|
||||
pv->alloc_vars = n;
|
||||
}
|
||||
}
|
||||
if (!pv->vars) {
|
||||
return E_NO_MEM;
|
||||
}
|
||||
n = pv->num_vars;
|
||||
pv->num_vars++;
|
||||
Var *v = FindVar(name, 0);
|
||||
Var *dest = &(pv->vars[n]);
|
||||
int r = OK;
|
||||
if (!v) {
|
||||
StrnCpy(dest->name, name, VAR_NAME_LEN);
|
||||
dest->preserve = 0;
|
||||
dest->is_constant = 0;
|
||||
dest->used_since_set = 0;
|
||||
dest->filename = NULL;
|
||||
dest->lineno = -1;
|
||||
dest->v.type = ERR_TYPE;
|
||||
dest->v.v.val = E_NOSUCH_VAR;
|
||||
} else {
|
||||
StrnCpy(dest->name, v->name, VAR_NAME_LEN);
|
||||
dest->preserve = v->preserve;
|
||||
dest->is_constant = v->is_constant;
|
||||
dest->used_since_set = v->used_since_set;
|
||||
dest->filename = v->filename;
|
||||
dest->lineno = v->lineno;
|
||||
r = CopyValue(&(dest->v), &(v->v));
|
||||
/* Pretend we've used v */
|
||||
v->used_since_set = 1;
|
||||
}
|
||||
return r;
|
||||
}
|
||||
|
||||
static void free_pushedvars(PushedVars *pv)
|
||||
{
|
||||
int i;
|
||||
for (i=0; i<pv->num_sysvars; i++) {
|
||||
DestroyValue(pv->sysvars[i].v);
|
||||
}
|
||||
for (i=0; i<pv->num_vars; i++) {
|
||||
DestroyValue(pv->vars[i].v);
|
||||
}
|
||||
if (pv->sysvars) {
|
||||
free(pv->sysvars);
|
||||
}
|
||||
if (pv->vars) {
|
||||
free(pv->vars);
|
||||
}
|
||||
free(pv);
|
||||
}
|
||||
|
||||
int
|
||||
PushVars(ParsePtr p)
|
||||
{
|
||||
int r;
|
||||
DynamicBuffer buf;
|
||||
char const *name;
|
||||
|
||||
PushedVars *pv = NEW(PushedVars);
|
||||
if (!pv) {
|
||||
return E_NO_MEM;
|
||||
}
|
||||
pv->next = NULL;
|
||||
pv->filename = GetCurrentFilename();
|
||||
pv->lineno = LineNo;
|
||||
pv->num_sysvars = 0;
|
||||
pv->num_vars = 0;
|
||||
pv->alloc_sysvars = 0;
|
||||
pv->alloc_vars = 0;
|
||||
pv->sysvars = NULL;
|
||||
pv->vars = NULL;
|
||||
|
||||
DBufInit(&buf);
|
||||
while(1) {
|
||||
r = ParseIdentifier(p, &buf);
|
||||
if (r == E_EOLN) {
|
||||
break;
|
||||
}
|
||||
if (r) {
|
||||
DBufFree(&buf);
|
||||
free_pushedvars(pv);
|
||||
return r;
|
||||
}
|
||||
name = DBufValue(&buf);
|
||||
if (*name == '$') {
|
||||
r = add_sysvar_to_push(name+1, pv);
|
||||
} else {
|
||||
r = add_var_to_push(name, pv);
|
||||
}
|
||||
DBufFree(&buf);
|
||||
if (r != OK) {
|
||||
free_pushedvars(pv);
|
||||
return r;
|
||||
}
|
||||
}
|
||||
if ((pv->num_vars + pv->num_sysvars) == 0) {
|
||||
free_pushedvars(pv);
|
||||
return E_EOLN;
|
||||
}
|
||||
pv->next = VarStack;
|
||||
VarStack = pv;
|
||||
return OK;
|
||||
}
|
||||
|
||||
int
|
||||
PopVars(ParsePtr p)
|
||||
{
|
||||
int r = VerifyEoln(p);
|
||||
int i;
|
||||
int ret = OK;
|
||||
PushedVars *pv = VarStack;
|
||||
if (r != OK) {
|
||||
return r;
|
||||
}
|
||||
if (!pv) {
|
||||
return E_POPV_NO_PUSH;
|
||||
}
|
||||
VarStack = VarStack->next;
|
||||
if (strcmp(pv->filename, GetCurrentFilename())) {
|
||||
Wprint(tr("POP-VARS at %s:%d matches PUSH-VARS in different file: %s:%d"), GetCurrentFilename(), LineNo, pv->filename, pv->lineno);
|
||||
}
|
||||
|
||||
/* Pop the sysvars */
|
||||
for (i=0; i<pv->num_sysvars; i++) {
|
||||
r = SetSysVar(pv->sysvars[i].name, &(pv->sysvars[i].v));
|
||||
if (r != OK) {
|
||||
ret = r;
|
||||
}
|
||||
}
|
||||
|
||||
/* Pop the vars */
|
||||
for (i=0; i<pv->num_vars; i++) {
|
||||
Var *src = &(pv->vars[i]);
|
||||
if (src->v.type == ERR_TYPE && src->v.v.val == E_NOSUCH_VAR) {
|
||||
/* Delete the variable if it exists */
|
||||
(void) DeleteVar(src->name);
|
||||
} else {
|
||||
Var *dest = FindVar(src->name, 0);
|
||||
if ((DebugFlag & DB_UNUSED_VARS) && dest && !dest->used_since_set) {
|
||||
Eprint(tr("`%s' UNSET without being used (previous SET: %s:%d)"), dest->name, dest->filename, dest->lineno);
|
||||
}
|
||||
if (!dest) {
|
||||
dest = FindVar(src->name, 1);
|
||||
}
|
||||
if (!dest) {
|
||||
ret = E_NO_MEM;
|
||||
continue;
|
||||
}
|
||||
dest->preserve = src->preserve;
|
||||
dest->is_constant = src->is_constant;
|
||||
dest->used_since_set = src->used_since_set;
|
||||
dest->filename = src->filename;
|
||||
dest->lineno = src->lineno;
|
||||
DestroyValue(dest->v);
|
||||
|
||||
/* Destructively copy value */
|
||||
dest->v = src->v;
|
||||
|
||||
/* Make sure free_pushedvars doesn't destroy our value! */
|
||||
src->v.type = ERR_TYPE;
|
||||
src->v.v.val = 0;
|
||||
}
|
||||
}
|
||||
free_pushedvars(pv);
|
||||
return ret;
|
||||
}
|
||||
|
||||
static void DumpSysVar (char const *name, const SysVar *v);
|
||||
|
||||
static int SetTranslatableVariable(SysVar *v, Value *value)
|
||||
static int SetTranslatableVariable(SysVar const *v, Value const *value)
|
||||
{
|
||||
return InsertTranslation((char const *) v->value, value->v.str);
|
||||
}
|
||||
|
||||
static int GetTranslatableVariable(SysVar *v, Value *value)
|
||||
static int GetTranslatableVariable(SysVar const *v, Value *value)
|
||||
{
|
||||
char const *translated = tr((char const *) v->value);
|
||||
if (translated) {
|
||||
@@ -1210,7 +1486,7 @@ SysVar *FindSysVar(char const *name)
|
||||
void DumpSysVarByName(char const *name)
|
||||
{
|
||||
size_t i;
|
||||
SysVar *v;
|
||||
SysVar const *v;
|
||||
|
||||
if (!name || !*name) {
|
||||
for (i=0; i<NUMSYSVARS; i++) DumpSysVar(name, SysVarArr + i);
|
||||
@@ -1287,7 +1563,7 @@ static void DumpSysVar(char const *name, const SysVar *v)
|
||||
return;
|
||||
}
|
||||
|
||||
void
|
||||
static void
|
||||
set_lat_and_long_from_components(void)
|
||||
{
|
||||
Latitude = (double) LatDeg + ((double) LatMin) / 60.0 + ((double) LatSec) / 3600.0;
|
||||
|
||||
@@ -65,8 +65,8 @@ FSET not_const(x) x+nonconst(a)
|
||||
REM [const(5)] Jan 1992 MSG expired... should be commented out
|
||||
REM [const(a)] Jan 1992 MSG expired... should be commented out
|
||||
REM [not_const(5)] Jan 1992 MSG nonconstant expression
|
||||
REM [value("a")] Jan 1992 MSG nonconstant expression
|
||||
|
||||
REM [value("a")] Jan 1992 MSG constant expression
|
||||
REM [value("__cabbage", 1)] Jan 1992 MSG non-constant expression
|
||||
IF 0
|
||||
# A comment in a false IF block
|
||||
#!P This should be nuked
|
||||
@@ -83,6 +83,8 @@ UNSET a
|
||||
CLEAR-OMIT-CONTEXT
|
||||
PUSH-OMIT-CONTEXT
|
||||
POP-OMIT-CONTEXT
|
||||
PUSH-VARS foo
|
||||
POP-VARS
|
||||
BANNER wow
|
||||
DEBUG +x
|
||||
DEBUG -x
|
||||
|
||||
@@ -3,6 +3,9 @@
|
||||
# If you're writing a back-end, test it by feeding it the output
|
||||
# of: remind -pp test-for-backends.rem
|
||||
|
||||
# All back-ends should endeavour to support: WEEK, SHADE, MOON, and
|
||||
# COLOR/COLOUR. They may support other back-end-specific SPECIALs.
|
||||
|
||||
# Color and shade
|
||||
REM 1 SPECIAL COLOR 128 0 0 Red
|
||||
REM 2 SPECIAL COLOUR 0 128 0 British Green
|
||||
@@ -17,11 +20,18 @@ REM [moondate(3)] SPECIAL MOON 3 -1 -1 [moontime(3)]
|
||||
# Week
|
||||
REM Monday SPECIAL WEEK (W[weekno()])
|
||||
|
||||
# PostScript
|
||||
REM Wed PS Border Border 2 div moveto /Helvetica-Oblique findfont 6 scalefont setfont (oof!) show
|
||||
# A normal reminder
|
||||
REM 16 MSG A normal reminder
|
||||
|
||||
# PostScript - currently only supported by rem2ps
|
||||
REM Wed PS Border Border 2 div moveto /Helvetica-Oblique findfont 6 scalefont setfont (oof PostScript!) show
|
||||
|
||||
# A SPECIAL that should be ignored
|
||||
REM 15 SPECIAL RANDOM-STUFF ignore me and be happy
|
||||
|
||||
# A normal reminder
|
||||
REM 16 MSG A normal reminder
|
||||
# HTML - currently only supported by rem2html
|
||||
REM 17 SPECIAL HTML I am <b>bold</b> HTML
|
||||
|
||||
# Pango - currently only supported by rem2pdf
|
||||
REM 18 SPECIAL PANGO I am <b>bold</b> PANGO
|
||||
|
||||
|
||||
@@ -730,8 +730,23 @@ EOF
|
||||
# Test year-folding
|
||||
TZ=America/Toronto ../src/remind -dx ../tests/yearfold.rem >> ../tests/test.out 2>&1
|
||||
|
||||
# Test unused-variable debugging
|
||||
../src/remind -du - <<'EOF' >> ../tests/test.out 2>&1
|
||||
set a 1
|
||||
set b a*2
|
||||
set c "What"
|
||||
if c
|
||||
set d "Told ya!"
|
||||
endif
|
||||
|
||||
set x 44
|
||||
set x 45
|
||||
set y 1000
|
||||
unset y
|
||||
EOF
|
||||
|
||||
# Make sure all the include files are ok
|
||||
find ../include -type f -name '*.rem' | while read x; do ../src/remind -n $x 1 Jan 2024 2>>../tests/test.out 1>/dev/null; done
|
||||
find ../include -type f -name '*.rem' | while read x; do ../src/remind -du -n $x 1 Jan 2024 2>>../tests/test.out 1>/dev/null; done
|
||||
|
||||
cmp -s ../tests/test.out ../tests/test.cmp
|
||||
if [ "$?" = "0" ]; then
|
||||
|
||||
2027
tests/test.cmp
2027
tests/test.cmp
File diff suppressed because one or more lines are too long
128
tests/test.rem
128
tests/test.rem
@@ -224,7 +224,7 @@ REM 1 March OMITFUNC _ofunc AFTER MSG OmitFunc Test
|
||||
REM 8 March OMITFUNC _ofunc -1 MSG OmitFunc Test 2
|
||||
|
||||
# omitfunc ignores local/global omits
|
||||
fset _ofunc(x) 0
|
||||
fset - _ofunc(x) 0
|
||||
OMIT 1 March
|
||||
OMIT 2 March 1991
|
||||
REM 1 March OMIT Sun OMITFUNC _ofunc AFTER MSG Should trigger 1 March
|
||||
@@ -272,7 +272,7 @@ set $LatDeg 30
|
||||
set $LatMin 30
|
||||
set $LatSec 0
|
||||
set $LongDeg -25
|
||||
set $LongMin 15
|
||||
set $LongMin -15
|
||||
set $LongSec 0
|
||||
|
||||
set a000 abs(1)
|
||||
@@ -478,7 +478,16 @@ REM MAYBE-UNCOMPUTABLE Mon OMIT Mon SKIP MSG Never ever ever...
|
||||
REM MAYBE-UNCOMPUTABLE Mon SATISFY [wkdaynum($T) == 3] MSG Nope nope...
|
||||
|
||||
dump
|
||||
dump $
|
||||
set axx 1
|
||||
PUSH-VARS $Tomorrow $Latitude $DefaultColor axx bxbxbx
|
||||
set $Tomorrow "HAHA, tomorrow"
|
||||
set $Latitude "0"
|
||||
set $DefaultColor "42 42 42"
|
||||
set bxbxbx 1
|
||||
dump $Tomorrow $Latitude $DefaultColor axx bxbxbx a136 $Today
|
||||
POP-VARS
|
||||
dump $Tomorrow $Latitude $DefaultColor axx bxbxbx a136 $Today
|
||||
|
||||
msg [$April]%
|
||||
msg [$August]%
|
||||
msg [$CalcUTC]%
|
||||
@@ -1556,7 +1565,8 @@ IF today() < '1990-01-01'
|
||||
SET a 2
|
||||
ENDIF
|
||||
|
||||
dump -c a
|
||||
set b const(today())
|
||||
dump -c a b
|
||||
|
||||
DEBUG -n
|
||||
|
||||
@@ -1572,6 +1582,27 @@ set a eval("1 / / 2")
|
||||
set a catch(eval("1 +"), 33)
|
||||
set a catch(eval("1/0"), 34)
|
||||
set a catch(eval("1 / / 2"), 35)
|
||||
|
||||
# Ensure RUN is disabled in eval
|
||||
set a shell("echo foo")
|
||||
set a eval("shell(\"echo foo\")")
|
||||
set a shell("echo foo")
|
||||
|
||||
FSET i() shell("echo foo")
|
||||
set a i()
|
||||
set a eval("i()")
|
||||
set a i()
|
||||
FUNSET i
|
||||
set a "eval(\"1\")+ shell(\"ls\")"
|
||||
set b eval(a)
|
||||
|
||||
# "value" should use lazy evaluation
|
||||
set a value(4:33)
|
||||
set a value('2020-01-01', 42)
|
||||
set a value("nosuchvar")
|
||||
set a value("nosuchvar", 42)
|
||||
set a value("a", 42)
|
||||
set a value("a")
|
||||
DEBUG -x
|
||||
|
||||
DEBUG -e
|
||||
@@ -1584,9 +1615,98 @@ set a eval(a)
|
||||
REM 9 Feb 1991 *7 MSG Base: [trigbase()]
|
||||
REM 9 Feb 1991 *1 MSG Base: [$Tb]
|
||||
|
||||
# The UNTIL bug
|
||||
DEBUG +t
|
||||
REM SECOND SATURDAY +300 UNTIL 1991-02-02 MSG [$T]
|
||||
REM SECOND SATURDAY +300 UNTIL 1991-02-16 MSG [$T]
|
||||
DEBUG -t
|
||||
|
||||
# Fully-specified trigger date in the past
|
||||
REM 14 Jan 1991 MSG In the past
|
||||
set a trigvalid()
|
||||
set b trigdate()
|
||||
|
||||
REM MSG trigvalid = [a]; trigdate = [b]
|
||||
|
||||
# SATISFY clause that's never satisfied...
|
||||
REM 14 Jan 1991 SATISFY [$Ty == 2022] MSG I can't get no satisfaction
|
||||
set a trigvalid()
|
||||
set b trigdate()
|
||||
|
||||
REM MSG trigvalid = [a]; trigdate = [b]
|
||||
|
||||
DEBUG +x
|
||||
set a daysinmon(2, 2000)
|
||||
set a daysinmon(2, 2001)
|
||||
set a daysinmon(3, 2000)
|
||||
set a daysinmon(3, 2001)
|
||||
|
||||
set a daysinmon("Feb", 2000)
|
||||
set a daysinmon("Feb", 2001)
|
||||
set a daysinmon("March", 2000)
|
||||
set a daysinmon("March", 2001)
|
||||
set a daysinmon("Cabbage", 2001)
|
||||
|
||||
set a daysinmon('2000-02-14')
|
||||
set a daysinmon('2001-02-14')
|
||||
set a daysinmon('2000-04-14')
|
||||
set a daysinmon('2001-04-14')
|
||||
|
||||
set a date(2020, "April", 15)
|
||||
set a date(2020, "Carrot", 12)
|
||||
set a datetime(2020, "April", 13, 4:44)
|
||||
set a datetime(2020, "April", 13, 4, 44)
|
||||
set a datetime(2020, "Lettuce", 13, 4:44)
|
||||
set a datetime(2020, "Lettuce", 13, 4, 44)
|
||||
|
||||
set a wkdaynum("Tue")
|
||||
set a wkdaynum("Wednesday")
|
||||
set a wkdaynum("telephone")
|
||||
|
||||
DEBUG -x
|
||||
# Output expression-node stats
|
||||
DEBUG +h
|
||||
|
||||
# Long list of pushing/popping variables
|
||||
PUSH-VARS $AddBlankLines $Ago $Am $And $April $At $August $CalcUTC $DateSep $DateTimeSep $December $DedupeReminders $DefaultColor $DefaultDelta $DefaultPrio $DefaultTDelta $EndSent $EndSentIg $ExpressionTimeLimit $February $FirstIndent $FoldYear $FormWidth $Friday $Fromnow $Hour $Hplu $Is $January $July $June $LatDeg $Latitude $LatMin $LatSec $Location $LongDeg $Longitude $LongMin $LongSec $March $MaxLateMinutes $MaxSatIter $MaxStringLen $May $MinsFromUTC $Minute $Monday $Mplu $November $Now $October $On $OnceFile $ParseUntriggered $Pm $Saturday $September $SubsIndent $Sunday $SuppressImplicitWarnings $SuppressLRM $Thursday $TimeSep $Today $Tomorrow $Tuesday $Was $Wednesday a1 a2 a3 a4 a5 a6 a7 a8 a9 a10 a11 a12 a13 a14 a15 a16 a17 a18 a19 a20 a21 a22 a23 a24 a25 a26 a27 a28 a29 a30 a31 a32 a33 a34 a35 a36 a37 a38 a39 a40 a41 a42 a43 a44 a45 a46 a47 a48 a49 a50 a51 a52 a53 a54 a55 a56 a57 a58 a59 a60 a61 a62 a63 a64 a65 a66 a67 a68 a69 a70 a71 a72 a73 a74 a75 a76 a77 a78 a79 a80 a81 a82 a83 a84 a85 a86 a87 a88 a89 a90 a91 a92 a93 a94 a95 a96 a97 a98 a99 a100 a101 a102 a103 a104 a105 a106 a107 a108 a109 a110 a111 a112 a113 a114 a115 a116 a117 a118 a119 a120 a121 a122 a123 a124 a125 a126 a127 a128 a129 a130 a131 a132 a133 a134 a135 a136 a137 a138 a139 a140 a141 a142 a143 a144 a145 a146 a147 a148 a149 a150 a151 a152 a153 a154 a155 a156 a157 a158 a159 a160 a161 a162 a163 a164 a165 a166 a167 a168 a169 a170 a171 a172 a173 a174 a175 a176 a177 a178 a179 a180 a181 a182 a183 a184 a185 a186 a187 a188 a189 a190 a191 a192 a193 a194 a195 a196 a197 a198 a199 a200 a201 a202 a203 a204 a205 a206 a207 a208 a209 a210 a211 a212 a213 a214 a215 a216 a217 a218 a219 a220 a221 a222 a223 a224 a225 a226 a227 a228 a229 a230 a231 a232 a233 a234 a235 a236 a237 a238 a239 a240 a241 a242 a243 a244 a245 a246 a247 a248 a249 a250 a251 a252 a253 a254 a255 a256 a257 a258 a259 a260 a261 a262 a263 a264 a265 a266 a267 a268 a269 a270 a271 a272 a273 a274 a275 a276 a277 a278 a279 a280 a281 a282 a283 a284 a285 a286 a287 a288 a289 a290 a291 a292 a293 a294 a295 a296 a297 a298 a299 a300
|
||||
POP-VARS
|
||||
|
||||
# Try pushing a read-only one
|
||||
PUSH-VARS $NumTrig
|
||||
POP-VARS
|
||||
|
||||
# Test push/pop of functions
|
||||
DEBUG +xe
|
||||
|
||||
FUNSET a
|
||||
FSET b(x, y) x*y
|
||||
FSET c() 33
|
||||
|
||||
set a a(2)
|
||||
set a b(2)
|
||||
set a b(2, 3)
|
||||
set a c()
|
||||
|
||||
PUSH-FUNCS a b c
|
||||
|
||||
FSET a(x) 42
|
||||
FSET b(x, y) x*y*2
|
||||
FSET c() 66
|
||||
|
||||
set a a(2)
|
||||
set a b(2)
|
||||
set a b(2, 3)
|
||||
set a c()
|
||||
|
||||
POP-FUNCS
|
||||
|
||||
set a a(2)
|
||||
set a b(2)
|
||||
set a b(2, 3)
|
||||
set a c()
|
||||
|
||||
DEBUG -xe
|
||||
|
||||
# Don't want Remind to queue reminders
|
||||
EXIT
|
||||
|
||||
|
||||
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
Reference in New Issue
Block a user