Compare commits

..

369 Commits

Author SHA1 Message Date
Dianne Skoll
8b5fe4f2a0 Update WHATSNEW for 04.02.01 release. 2022-12-15 09:34:02 -05:00
Dianne Skoll
98fc4a917f Bump version to 04.02.01 2022-12-15 09:24:30 -05:00
Dianne Skoll
e633530a36 Fix stray %" 2022-11-15 08:24:52 -05:00
Dianne Skoll
bfea9915b9 Remove unnecessary %"...%" markers. 2022-11-14 12:37:17 -05:00
Clément Bœsch
d68ed6e75d Add French holidays courtesy of Clément Bœsch 2022-11-14 12:20:43 -05:00
Dianne Skoll
a22631d768 Document need for Noto Fonts in TkRemind. 2022-11-01 13:40:44 -04:00
Dianne Skoll
552bf84e33 Make test *not* depend on the current date... *sigh*. 2022-10-24 09:41:40 -04:00
Dianne Skoll
28d0251093 If we use "-m" in ExtraRemindArgs, set $MondayFirst in tkremind
Patch courtesy of Luís Henriques
2022-10-24 09:35:27 -04:00
Dianne Skoll
f3d969f658 Make sure we print the banner on each iteration of a command-line '*rep' 2022-10-20 18:21:57 -04:00
Dianne Skoll
2afe95d090 Fix typo in comment. 2022-10-18 17:25:59 -04:00
Dianne Skoll
3692a6b265 Avoid ambiguous local<->UTC conversions right around when the clocks change. 2022-10-17 09:58:32 -04:00
Dianne Skoll
8fc19358bb Double-up on "%" in a printf formatting string. 2022-10-17 08:29:38 -04:00
Dianne Skoll
c8f9773d83 Speed up FindFunc. 2022-10-14 13:53:50 -04:00
Dianne Skoll
e1091db82f Don't try to use -ffat-lto-objects with clang 2022-10-14 13:31:57 -04:00
Dianne Skoll
9f8ed13434 Remove a whole lot of unused / dead code. 2022-10-14 13:26:56 -04:00
Dianne Skoll
914f03d5eb Fix bad comment. 2022-10-14 11:45:04 -04:00
Dianne Skoll
a801f6d4ce Token names are already lower-case. 2022-10-14 11:43:36 -04:00
Dianne Skoll
fde5a7b4ca Can use strcmp rather than StrCmpI in FindOperator since they are not alphabetic 2022-10-14 11:41:11 -04:00
Dianne Skoll
0e1fff6339 Update WHATSNEW for release. 2022-10-14 11:06:27 -04:00
Dianne Skoll
60fdeac2e9 Add RPM dependencies. 2022-10-14 11:02:51 -04:00
Dianne Skoll
3b3f10d448 Document prereqs on Gentoo and Arch Linux. 2022-10-14 10:53:35 -04:00
Dianne Skoll
48a4314dd2 Remove "validate" field from system variables. It was never used. 2022-10-14 10:42:05 -04:00
Dianne Skoll
9beff3a24a Tweak demo 2022-10-13 15:36:26 -04:00
Dianne Skoll
1ef90c7a61 Fix comments. 2022-10-13 13:55:09 -04:00
Dianne Skoll
5c886d181e Make overline clearer. 2022-10-13 13:54:06 -04:00
Dianne Skoll
da4d830163 More effects. 2022-10-13 13:53:10 -04:00
Dianne Skoll
c7abb7986c Add ansitext demo 2022-10-13 13:51:51 -04:00
Dianne Skoll
5a3b3d8a06 Add standard include file with various ANSI text attribute-changing sequences. 2022-10-13 10:42:28 -04:00
Dianne Skoll
127cee03df Add gmon.out to gitignore 2022-10-13 10:42:12 -04:00
Dianne Skoll
7455748d54 Eliminate compiler warning. 2022-10-13 08:28:09 -04:00
Dianne Skoll
e278d0e768 Fix typo 2022-10-12 20:13:47 -04:00
Dianne Skoll
a5acc12239 Try a ridiculously long line to excercise dynamic-buffer resizing 2022-10-12 20:11:23 -04:00
Dianne Skoll
a25afb9771 Fix ancient logic error in dynamic buffer code. 2022-10-12 19:38:18 -04:00
Dianne Skoll
6252a472b5 Get rid of useless macro. 2022-10-12 19:21:35 -04:00
Dianne Skoll
dbe4c662c1 Add the "FUNSET" command to delete user-defined functions. 2022-10-12 14:12:13 -04:00
Dianne Skoll
b77a261c87 Add Jewish holidays to the list of standard holiday files. 2022-10-12 14:05:55 -04:00
Dianne Skoll
351c54cc50 Print today. 2022-10-12 13:48:15 -04:00
Dianne Skoll
72d0b13ad5 Make the CI setup run "make all" to catch possible errors compiling the Perl modules. 2022-10-12 11:32:37 -04:00
Dianne Skoll
bea2a6541c Fix docs. 2022-10-12 10:20:20 -04:00
Dianne Skoll
5258e98f54 Add translations for various astronomical events in German localization, courtesy of Gunther Reißig. 2022-10-12 08:39:02 -04:00
Dianne Skoll
af9d42721c Separate Sun from Moon output. 2022-10-11 15:44:19 -04:00
Dianne Skoll
8ed43f5c3e Update WHATSNEW 2022-10-11 14:19:32 -04:00
Dianne Skoll
ec02a87c2b Fix some bugs in US holidays. 2022-10-11 14:19:00 -04:00
Dianne Skoll
6c2ec04d40 Visual tweaks. 2022-10-11 13:57:00 -04:00
Dianne Skoll
9f91cdf0b9 Update WHATSNEW. 2022-10-11 13:23:55 -04:00
Dianne Skoll
8ada68ce54 Add the "columns(str)" variant. 2022-10-11 13:18:44 -04:00
Dianne Skoll
d7975634af Update WHATSNEW 2022-10-11 11:56:41 -04:00
Dianne Skoll
87be68fecf Document rows() and columns() 2022-10-11 11:54:52 -04:00
Dianne Skoll
b42d5fd412 Add rows() and columns() built-in function. 2022-10-11 11:52:35 -04:00
Dianne Skoll
603228b944 Update prerequisite list. 2022-10-11 10:41:57 -04:00
Dianne Skoll
c62f676813 Diagnose unterminated %{...} sequence 2022-10-11 10:35:31 -04:00
Dianne Skoll
c7654c27a6 Update WHATSNEW. 2022-10-11 09:16:04 -04:00
Dianne Skoll
b00bf05fea Add test for %{custom} substitution. 2022-10-11 09:14:47 -04:00
Dianne Skoll
29bd07d4ef Document %{name} substitution sequences. 2022-10-11 09:11:12 -04:00
Dianne Skoll
b7047da89e Allow user-defined substitutions of the form: %{name} or %*{name} that call subst_name. 2022-10-11 09:07:08 -04:00
Dianne Skoll
f26334e25f Add doc about %_ to insert a blank line if $AddBlankLines is 0. 2022-10-11 08:31:13 -04:00
Dianne Skoll
b80bc5f788 Test that ending a reminder with %_ does add a blank line. 2022-10-11 08:30:17 -04:00
Dianne Skoll
91549e18ce Make use of $AddBlankLines 2022-10-10 22:52:48 -04:00
Dianne Skoll
07fd975935 Add the $AddBlankLines system variable. 2022-10-10 22:49:28 -04:00
Dianne Skoll
f9d968cf68 Fix CI script. 2022-10-10 17:31:14 -04:00
Dianne Skoll
6a7e696a60 Minor doc tweak 2022-10-10 17:17:31 -04:00
Dianne Skoll
6734fae1db Update docs/WHATSNEW 2022-10-10 17:15:21 -04:00
Dianne Skoll
481fbc20a1 Bump version to 04.02.00 2022-10-10 17:05:00 -04:00
Dianne Skoll
3c120bf561 Avoid compiler warning. 2022-10-10 17:04:51 -04:00
Dianne Skoll
ee65e04974 Top-level test does not depend on top-level all. 2022-10-10 17:04:35 -04:00
Dianne Skoll
4ee6bb0eca Add test for embedded %_ in MSF reminders. 2022-10-10 11:12:47 -04:00
Dianne Skoll
b9839421f2 make "MSF" correctly wrap UTF-8 text. 2022-10-10 11:05:38 -04:00
Dianne Skoll
67601507fa More robust handling of ANSI color escape sequences. 2022-10-09 22:00:06 -04:00
Dianne Skoll
c2e5534462 Make "REM ... MSF ..." handle ANSI color escape sequences correctly. 2022-10-09 21:55:09 -04:00
Dianne Skoll
f4ea3af6fc Update test output. 2022-10-09 21:32:04 -04:00
Dianne Skoll
e0998a3991 Implement trigtags() 2022-10-09 21:31:24 -04:00
Dianne Skoll
d67e580d0a More tweaks 2022-10-09 18:24:49 -04:00
Dianne Skoll
d6ce54eea4 Tweak astro example script. 2022-10-09 18:22:56 -04:00
Dianne Skoll
8b9ec43029 Add "astro" example script. 2022-10-09 18:21:03 -04:00
Dianne Skoll
9d68134f0f Make PrintValue escape only byte values < 32 2022-10-09 17:53:40 -04:00
Dianne Skoll
3d91371870 Correct and clarify man page. 2022-10-09 17:53:21 -04:00
Dianne Skoll
d1c0ef63b0 Fix inconsistency in man page. 2022-10-09 17:34:09 -04:00
Dianne Skoll
2a59da61e1 Update man page. 2022-10-09 13:40:21 -04:00
Dianne Skoll
2bc5e21627 Document ansicolor and the new color-related special variables. 2022-10-09 13:36:41 -04:00
Dianne Skoll
7d77bfd12a Add tests for invalid ansicolor() calls. 2022-10-09 13:10:28 -04:00
Dianne Skoll
0ff589c288 Merge branch 'utf8' into 'master'
Convert files to UTF-8
2022-10-09 17:02:45 +00:00
Dianne Skoll
f3cca092be Add tests for ansicolors function and new $Use...Colors variables. 2022-10-09 12:59:52 -04:00
Dianne Skoll
7218d55f08 Add $TerminalBackground special variable. 2022-10-09 12:40:48 -04:00
Dianne Skoll
ec72c74016 Add $Use256Colors, $UseBGVTColors, $UseTrueColors and $UseVTColors special variables. 2022-10-09 12:16:33 -04:00
Dianne Skoll
c946f08235 Fix spelling error. 2022-10-07 18:55:07 -04:00
Dianne Skoll
a8543ac349 Fix regression test. 2022-10-06 17:53:01 -04:00
Dianne Skoll
dd3c0e14ed Make wording more consistent. 2022-10-06 17:52:19 -04:00
Dianne Skoll
a2bc0acd3c Use English day names in "OMIT DUMP" 2022-10-06 15:20:37 -04:00
Dianne Skoll
a34266741a Clarify that we use the union of globally- and locally-omitted weekdays. 2022-10-06 08:40:05 -04:00
Dianne Skoll
dedb9766c9 Make a SATISFY-type reminder with ADDOMIT but no MSG actually add to the omits.
Previously, something like: REM 1 May ADDOMIT SATISFY 1
would not add to the global OMIT list.
2022-10-06 08:35:50 -04:00
Dianne Skoll
aedd759f50 Tweak wording. 2022-10-05 16:39:18 -04:00
Dianne Skoll
a24c2f6905 Refactor code. 2022-10-05 16:36:08 -04:00
Dianne Skoll
fac31a10b8 Add the timezone() built-in function. 2022-10-05 16:28:38 -04:00
Dianne Skoll
fba9f139ed Add global OMIT of the form:
OMIT wkday [wkday...]

For example:  OMIT Saturday Sunday
2022-10-05 14:12:53 -04:00
Dianne Skoll
588d9debe8 Simplify American Independence Day example. 2022-10-05 11:12:21 -04:00
Dianne Skoll
805c2e0c69 Implement the utctolocal and localtoutc functions. 2022-10-04 16:23:45 -04:00
Dianne Skoll
2c2b1440b3 Make tests work in non-utf-8 locale. 2022-09-27 21:49:33 -04:00
Jochen Sprickerhof
6973f62d74 Convert files to UTF-8 2022-09-26 20:03:05 +02:00
Dianne Skoll
f547c1e714 Update release notes. 2022-09-26 12:08:49 -04:00
Dianne Skoll
f8ea124b1f Add OS error message if we can't open file. 2022-09-24 10:57:32 -04:00
Dianne Skoll
820e2aec4d Document that "-wcol" also sets $FormWidth 2022-09-24 10:48:43 -04:00
Dianne Skoll
01ce6b2d8f Clamp min CalWidth at 71. 2022-09-24 10:40:04 -04:00
Dianne Skoll
b39e0eab7e Get rid of ComputeCalWidth - it's obsolete 2022-09-24 10:39:05 -04:00
Dianne Skoll
d6fc451d74 Refactor code. 2022-09-24 10:34:05 -04:00
Dianne Skoll
ac91556fc2 Make '-wn' initialize FormWidth as well. 2022-09-24 10:29:23 -04:00
Dianne Skoll
ccf639efe6 Make '-wt' accept FormWidth as well as CalWidth 2022-09-24 10:27:19 -04:00
Dianne Skoll
a8aa3b328b Add "-wt" option to size calendar according to terminal window. 2022-09-24 10:26:06 -04:00
Dianne Skoll
74a3b3e73d Yet more doc fixes. 2022-09-24 09:56:16 -04:00
Dianne Skoll
c0e68b57ea Fix pod 2022-09-24 09:53:11 -04:00
Dianne Skoll
0ad4ea26eb Properly set version and release date in man pages for rem2html and rem2pdf 2022-09-24 09:50:15 -04:00
Dianne Skoll
ea7aafaf5e Refactor code to reduce copy-paste coding. 2022-09-24 09:16:50 -04:00
Dianne Skoll
18043080ba Properly detect missing quote after escape sequence. 2022-09-23 20:42:57 -04:00
Dianne Skoll
7cd8cf3a77 Dump strings more sensibly in PrintValue. 2022-09-23 19:10:36 -04:00
Dianne Skoll
21da52ec36 Update unit tests. 2022-09-23 19:05:51 -04:00
Dianne Skoll
7a0c164843 Dump strings more sensibly. 2022-09-23 19:05:26 -04:00
Dianne Skoll
5cf4961f19 More clarification. 2022-09-23 08:38:00 -04:00
Dianne Skoll
68926d145b Fix innacuracy in how string constants are described. 2022-09-23 08:32:12 -04:00
Dianne Skoll
fdc3e4d23d Update WHATSNEW 2022-09-22 15:00:30 -04:00
Dianne Skoll
f179c837e1 Update regression tests. 2022-09-22 08:56:58 -04:00
Dianne Skoll
740bb44956 Don't consider IFTRIG true if we could not compute a trigger date.
Bug noted by Gunther Reißig
2022-09-22 08:48:19 -04:00
Dianne Skoll
5b953769fe Obey $DefaultColor in a SATISFY-type reminder.
Bug found by Gunther Reißig.
2022-09-22 08:37:37 -04:00
Dianne Skoll
1ae00ce778 No need to reset NumTriggered. 2022-09-21 19:11:30 -04:00
Dianne Skoll
a01e05c1db Fix bug introduced in commit 98c5bf511e:
Don't print a banner when issuing a queued reminder.
2022-09-21 18:17:25 -04:00
Dianne Skoll
63fb3e99f3 Make "test" depend on "all" rather than just "remind" 2022-09-19 13:56:11 -04:00
Dianne Skoll
6cf7f5d2d8 Merge branch 'add_ci' into 'master'
Add ci

See merge request dskoll/remind!2
2022-09-19 17:54:45 +00:00
Jochen Sprickerhof
316eb43303 Add Gitlab CI 2022-09-19 19:51:15 +02:00
Dianne Skoll
576112a39a Merge branch 'drop_fgrep' into 'master'
Replace deprecated fgrep by grep

See merge request dskoll/remind!1
2022-09-19 17:50:03 +00:00
Jochen Sprickerhof
6607223abb Replace deprecated fgrep by grep -F 2022-09-19 19:49:20 +02:00
Dianne Skoll
9e85b1932d Mark today in bold iff "remind -c" color output is enabled. 2022-09-19 11:32:10 -04:00
Dianne Skoll
4ba7f5b1f2 Only embolden today if stdout is a tty 2022-09-19 10:44:21 -04:00
Dianne Skoll
fc93ae890a Allow NULL pointers to be supplied to FromJulian if we are not interested in specific values 2022-09-17 23:04:34 -04:00
Dianne Skoll
8051d01945 Document change in Makefile install/install-stripped targets. 2022-09-17 09:07:27 -04:00
Dianne Skoll
63430c59f7 Make "make install" *not* strip debugging symbols; add "make install-stripped" target to strip them. 2022-09-17 09:04:45 -04:00
Dianne Skoll
c646bfc63f Make today's date bold in -c mode. 2022-09-16 21:01:10 -04:00
Dianne Skoll
58dea8f69b Support greyscale version of SHADE. 2022-09-16 20:44:59 -04:00
Dianne Skoll
f1c82dcb37 Update docs; bump version to 04.01.00. 2022-09-16 19:54:04 -04:00
Dianne Skoll
b984b66819 Put a space before the "***" representing today in -c mode. 2022-09-16 16:15:01 -04:00
Dianne Skoll
44bdae302b Allow 2 (=TERMINAL_BACKGROUND_UNKNOWN) for m in -@n,m,b 2022-09-16 15:58:51 -04:00
Dianne Skoll
8eb6b250fb Add support for the WEEK speical. 2022-09-16 15:08:53 -04:00
Dianne Skoll
d838c41bf2 Add tests for stdout() function. 2022-09-16 14:14:06 -04:00
Dianne Skoll
f9dbf36496 Don't backgroundize the row with day numbers. 2022-09-16 13:53:33 -04:00
Dianne Skoll
fe1427db28 Finalize support for SPECIAL SHADE in "remind -c" 2022-09-16 13:50:23 -04:00
Dianne Skoll
2621ad5604 Tweak calendar column-to-day handling. 2022-09-16 13:43:20 -04:00
Dianne Skoll
efecf2e1ea Make "remind -c" optionally support the SPECIAL SHADE 2022-09-16 11:41:18 -04:00
Dianne Skoll
8666e6357e Start working on support for SHADE in remind -c output. 2022-09-16 08:42:20 -04:00
Dianne Skoll
ae7069c9cb Gotta use the right sscanf format. :( 2022-09-15 18:43:58 -04:00
Dianne Skoll
0c6ab3e607 Properly parse args to MOON special 2022-09-15 18:37:46 -04:00
Dianne Skoll
17d6a60c0a Fix moon-phase-in-terminal printing and add tests. 2022-09-15 18:23:03 -04:00
Dianne Skoll
e3e0a541dc Print moon phases in terminal if terminal supports UTF-8 2022-09-15 18:18:05 -04:00
Jochen Sprickerhof
712aa08fbc make test depend on all 2022-09-08 16:32:04 +02:00
Dianne Skoll
98c5bf511e Print banner prior to first MSG-type reminder. 2022-09-06 09:14:55 -04:00
Dianne Skoll
1f9281628f Add home page to rem2pdf.1 and rem2html.1 2022-08-27 11:21:24 -04:00
Dianne Skoll
8fb15aed17 Do a sanity-check to make sure we pick up a release date. 2022-08-27 10:26:51 -04:00
Dianne Skoll
a24c3a8542 Remove generated man pages when running "make clean" 2022-08-27 10:24:29 -04:00
Dianne Skoll
8f8059e3f3 Generate man files from *.in versions to include release date and version number. 2022-08-27 10:22:31 -04:00
Dianne Skoll
24bb462199 Rename *.1 to *.1.in 2022-08-27 10:14:16 -04:00
Dianne Skoll
38e914f171 Get release date. 2022-08-27 10:06:02 -04:00
Dianne Skoll
4a02c54e8d Add home page to man pages. 2022-08-26 16:33:39 -04:00
Dianne Skoll
5fe169438a Document behavior of DO and filedir() with respect to symbolic links. 2022-08-22 09:19:30 -04:00
Dianne Skoll
a7ef6e851a Fix error in Makefile - remove duplicate clean: definition 2022-08-21 10:24:30 -04:00
Dianne Skoll
4d57b9d0aa Pass CFLAGS at link-time
Thanks to Zoltan Puskas for suggestion.
2022-08-21 10:23:16 -04:00
Dianne Skoll
5a7452d9f6 Add install-nostripped top-level target.
Thanks to Zoltan Puskas for suggestion.
2022-08-21 10:22:58 -04:00
Dianne Skoll
3916887aff Update change log. 2022-08-16 09:24:51 -04:00
Dianne Skoll
f84f59fa91 Bump version to 04.00.03. 2022-08-15 14:48:59 -04:00
Dianne Skoll
1032f8908e Don't create mysterious files named '&1' when creating new reminders. Sigh. 2022-08-11 11:32:59 -04:00
Dianne Skoll
6c2e8fc608 Document calendar_body and plain_body. 2022-08-08 11:49:06 -04:00
Dianne Skoll
012e527fb5 Fix parsing of old-style output. 2022-08-06 12:06:09 -04:00
Dianne Skoll
62198c9807 Use the new calendar_body/plain_body fields. 2022-08-06 11:54:32 -04:00
Dianne Skoll
de95224d62 Use new calendar_body / plain_body elements. 2022-08-06 11:49:35 -04:00
Dianne Skoll
be374a0464 Update test suite for new JSON output. 2022-08-06 09:09:06 -04:00
Dianne Skoll
fe9b3186d7 Add plain_body and calendar_body keys to JSON output. 2022-08-06 09:06:54 -04:00
Dianne Skoll
8405ea6c53 Add note about how to kill remind in queue mode. 2022-08-06 08:34:16 -04:00
Dianne Skoll
4274d05e10 Fix man page typo 2022-08-05 22:09:36 -04:00
Dianne Skoll
4e80ce1159 Don't make SIGINT kill a background process; don't call printf from a signal-handler; use sigaction instead of signal 2022-08-05 22:04:44 -04:00
Dianne Skoll
52f473f2af Update .gitignore 2022-08-04 10:34:45 -04:00
Dianne Skoll
1d6ca51bf9 Update docs. 2022-08-02 14:58:15 -04:00
Dianne Skoll
e662d0b3dd Bump version to 04.00.02 2022-08-02 14:51:00 -04:00
Dianne Skoll
b910d557d1 Document new form of OMIT command. 2022-07-27 15:16:23 -04:00
Dianne Skoll
a4ad0a9e97 Rename error constant. 2022-07-27 15:06:04 -04:00
Dianne Skoll
07f67e7dd7 Better error messages 2022-07-27 15:03:48 -04:00
Dianne Skoll
d6575773fb Don't let THROUGH date be before START date in OMIT. 2022-07-27 14:55:34 -04:00
Dianne Skoll
ac1303886e Add another test. 2022-07-27 14:47:11 -04:00
Dianne Skoll
1569992184 Add test for more flexible OMIT 2022-07-27 14:43:54 -04:00
Dianne Skoll
55a1f1d746 Implement more flexible OMIT. We can do things like:
OMIT May       - equivalent to "OMIT May 1" ... "OMIT May 31"
    OMIT Nov 20 THROUGH Dec 4
    OMIT Apr THROUGH May
    OMIT 2023-12-25 THROUGH 2024-01-06
2022-07-27 14:39:43 -04:00
Dianne Skoll
ef7742a3cc Add GitHub README 2022-07-19 10:12:46 -04:00
Dianne Skoll
ef48c2020b Fix typo 2022-07-12 20:44:57 -04:00
Dianne Skoll
6dcb25073b Make $T behave as documented: If trigger date is not valid, should return 0. 2022-07-04 14:23:39 -04:00
Dianne Skoll
4824b07ec8 Document inotifywait 2022-07-03 19:47:06 -04:00
Dianne Skoll
a8f1228fb7 Update TkRemind man page. 2022-07-03 19:13:05 -04:00
Dianne Skoll
80e51d1d0f Make calendar with 6 rows in a month handle resizing properly.
Fixes https://github.com/dfskoll/remind/issues/1
2022-07-01 16:45:25 -04:00
Dianne Skoll
80e30638a5 Update changelog 2022-06-03 16:22:19 -04:00
Dianne Skoll
dd2fc30364 Add test for $SuppressLRM 2022-05-29 17:28:45 -04:00
Dianne Skoll
a5865fb5fe Add $SuppressLRM system variable; bump version to 04.00.01. 2022-05-27 12:22:26 -04:00
Dianne Skoll
aca2f28341 Add liberapay button. 2022-05-19 13:58:03 -04:00
Dianne Skoll
7a3f5f7ac9 Add github action to run tests. 2022-05-19 09:46:32 -04:00
Dianne Skoll
1731710ef2 Minor reformatting of source. 2022-05-19 09:01:11 -04:00
Dianne Skoll
dc2a8f48bf Update man page. 2022-04-07 11:53:20 -04:00
Dianne Skoll
5e16179bfa Update docs for 04.04.00 release. 2022-04-04 09:36:08 -04:00
Dianne Skoll
a7c1bc81b2 Remove a bug from man page. 2022-04-03 12:59:25 -04:00
Dianne Skoll
5f5ec8ef19 More intelligent handling of --prefix wrt ExtUtils::MakeMaker. 2022-04-03 12:23:28 -04:00
Dianne Skoll
712ff56792 Update docs 2022-04-01 12:11:04 -04:00
Dianne Skoll
99af1f964c Fix bug that broke "-m" option to tkreminder. 2022-04-01 12:08:25 -04:00
Dianne Skoll
de5d1347e5 Make the operator stack static 2022-03-26 19:05:18 -04:00
Dianne Skoll
5e07fbde6d Fix formatting. 2022-03-26 18:03:31 -04:00
Dianne Skoll
c523c7f3b3 Allow a subst_N or subst_Nx function to return 0 to indicate "use the normal substitution" 2022-03-26 18:02:39 -04:00
Dianne Skoll
6b3c6b0ec7 Fix a couple of typos. 2022-03-26 10:11:17 -04:00
Dianne Skoll
62b94ab065 Update WHATSNEW. 2022-03-25 16:08:33 -04:00
Dianne Skoll
49c7399599 Add "pad" function 2022-03-25 16:07:17 -04:00
Dianne Skoll
5fa9297aba Bump version to 04.00.00 2022-03-25 15:52:07 -04:00
Dianne Skoll
4ada31798b Document language packs. 2022-03-25 15:14:59 -04:00
Dianne Skoll
e78f953e90 Document "pad" function. 2022-03-25 14:47:42 -04:00
Dianne Skoll
af7a9ad8b5 Use Eprint instead of Wprint 2022-03-25 14:20:40 -04:00
Dianne Skoll
35eae045a6 Fix up test file. 2022-03-25 14:18:12 -04:00
Dianne Skoll
98a20ae058 Better call-stack printing. 2022-03-25 14:17:43 -04:00
Dianne Skoll
df9ef6e13a Print call stack if an error occurs in a user-defined function. 2022-03-25 14:03:06 -04:00
Dianne Skoll
10f5802069 Add callstack-management functions. 2022-03-25 13:56:00 -04:00
Dianne Skoll
780044219f Store the filename / lineno at which a user-defined function is defined. 2022-03-25 13:40:07 -04:00
Dianne Skoll
d015c061e7 Add site/ subdir and README. 2022-03-25 11:26:42 -04:00
Dianne Skoll
6f6326d433 Add another pad() test. 2022-03-25 11:13:51 -04:00
Dianne Skoll
9488e7ca13 Don't let pad function make over-long strings. 2022-03-25 11:08:43 -04:00
Dianne Skoll
71c11672c2 Add null "en.rem" 2022-03-25 10:59:51 -04:00
Dianne Skoll
0acefa800e Add Spanish language pack. 2022-03-25 10:58:57 -04:00
Dianne Skoll
d45cee4712 Add Romanian language pack. 2022-03-25 10:53:20 -04:00
Dianne Skoll
c026aa05e2 Warn if a substitution expression evaluates incorrectly. 2022-03-25 10:53:08 -04:00
Dianne Skoll
50076c74fa Implement Portuguese language pack. 2022-03-25 08:54:13 -04:00
Dianne Skoll
1563d77c06 More extensive tests. 2022-03-24 18:53:55 -04:00
Dianne Skoll
ed72ef8629 Use built-in "pad" function 2022-03-24 17:34:08 -04:00
Dianne Skoll
06c5996086 Add tests for pad function 2022-03-24 17:33:16 -04:00
Dianne Skoll
570ca857a0 Add "pad" function; make compare-language-mods.pl quiet. 2022-03-24 17:31:37 -04:00
Dianne Skoll
f8f20b7afc Add Polish language pack 2022-03-24 16:33:48 -04:00
Dianne Skoll
f55ef7ff20 Add Norwegian language pack. 2022-03-24 16:04:54 -04:00
Dianne Skoll
79220a74cf Add Italian language pack. 2022-03-24 15:49:25 -04:00
Dianne Skoll
77111ef628 Convert to utf-8 2022-03-24 15:01:37 -04:00
Dianne Skoll
bf96063311 Convert is.rem to utf-8 2022-03-24 14:45:57 -04:00
Dianne Skoll
58a201fceb Fix typo 2022-03-24 14:42:01 -04:00
Dianne Skoll
47cecb210b Add an auto.rem file to pick language file based on locale. 2022-03-24 14:39:18 -04:00
Dianne Skoll
bfbf744b0a Implement Icelandic language pack. 2022-03-24 14:14:42 -04:00
Dianne Skoll
0cf56ac1de Error-check -@ values. 2022-03-24 14:07:07 -04:00
Dianne Skoll
2880a718f4 Fix bug in compiled Dutch language support. 2022-03-24 12:34:58 -04:00
Dianne Skoll
da0dd0f7c6 Tweak nl language pack. 2022-03-24 12:32:43 -04:00
Dianne Skoll
c456d3e0ff More extensive testing. 2022-03-24 12:30:04 -04:00
Dianne Skoll
59059736e6 Add remembrance day 2022-03-24 11:42:45 -04:00
Dianne Skoll
f5cf2ab832 Working version of Finnish language pack! 2022-03-24 11:22:15 -04:00
Dianne Skoll
cc4ff2582d More work on getting Finnish language pack working properly. 2022-03-24 11:05:58 -04:00
Dianne Skoll
90f5fde3bb Progress on Finnish language pack. 2022-03-24 10:38:03 -04:00
Dianne Skoll
9fbe9f5132 Add more tests. 2022-03-23 17:30:28 -04:00
Dianne Skoll
f05661fa6c Fix typo 2022-03-23 17:22:47 -04:00
Dianne Skoll
d6882c3378 Add more tests. 2022-03-23 17:20:13 -04:00
Dianne Skoll
e32cab937e Install everything under include/ in $SysInclude 2022-03-23 16:43:15 -04:00
Dianne Skoll
14bb939977 Add US holidays. 2022-03-23 15:44:23 -04:00
Dianne Skoll
13e830782d Port over NL 2022-03-23 15:37:49 -04:00
Dianne Skoll
f39bb5e2d9 Tweaks 2022-03-23 14:53:28 -04:00
Dianne Skoll
8b795e81b7 Port Danish to da.rem 2022-03-23 14:47:22 -04:00
Dianne Skoll
aef7eeda5a Make "de" runtime localization match compiled version. 2022-03-23 12:04:54 -04:00
Dianne Skoll
0641a6f8f1 Add support for the "subst_#x" functions to simplify language customization. 2022-03-23 11:52:51 -04:00
Dianne Skoll
4fdf7b706b More work on making run-time language module match compile-time module. 2022-03-23 11:47:00 -04:00
Dianne Skoll
0653b9420a Add "q" suboption to "-p" to not suppress quote markers. 2022-03-23 11:02:16 -04:00
Dianne Skoll
27ede1ce37 Start working on runtime language files; make sure they give
the same tstlang.rem output as compiled language files.
2022-03-23 10:16:59 -04:00
Dianne Skoll
a303fb9cba Tweak configure script to use autoconf macros 2022-03-22 10:40:41 -04:00
Dianne Skoll
92af4e9c3e Only use -flto=auto and -ffat-lto-objects if C compiler supports them. 2022-03-22 10:33:36 -04:00
Dianne Skoll
abc4f45fed Compile with link-time optimization enabled if we're using gcc 2022-03-22 09:18:28 -04:00
Dianne Skoll
e651f92bd9 Make tests pass even if we use LTO. 2022-03-22 09:17:31 -04:00
Dianne Skoll
b2d3d98d72 Update de.rem 2022-03-20 14:22:15 -04:00
Dianne Skoll
cb8b7f85af Language tweaks 2022-03-20 14:20:01 -04:00
Dianne Skoll
d30f347a0b More language work. 2022-03-20 13:05:24 -04:00
Dianne Skoll
5e9b1e7464 Fix compilation errors for non-English languages. 2022-03-20 10:49:37 -04:00
Dianne Skoll
58085470c5 Install fr.rem 2022-03-20 10:31:53 -04:00
Dianne Skoll
8f0de805d5 More work on fr.rem 2022-03-20 10:27:04 -04:00
Dianne Skoll
3f879a1b97 Add subst_ampm and subst_ordinal 2022-03-20 10:20:50 -04:00
Dianne Skoll
94270c3d98 Add sys vars 2022-03-20 10:01:31 -04:00
Dianne Skoll
bb8a689186 Add a whole slew of system variables to customize language. 2022-03-20 09:53:31 -04:00
Dianne Skoll
a7e73cdac8 Remove IN_DOSUBST guards. 2022-03-20 09:44:42 -04:00
Dianne Skoll
d38c324340 Start making language stuff dynamic. 2022-03-20 09:42:24 -04:00
Dianne Skoll
fade38d522 Add $SysInclude system variable. 2022-03-20 08:56:01 -04:00
Dianne Skoll
858a7601aa Add support for "subst_X" functions to modify dosubst. 2022-03-19 15:53:21 -04:00
Dianne Skoll
37e3d3d1d1 Add $Today and $Tomorrow system variables. 2022-03-19 15:17:18 -04:00
Dianne Skoll
ff67ab3c86 We only need 6 digits of precision. 2022-03-17 17:37:40 -04:00
Dianne Skoll
ad7faa8ad9 Don't check errno 2022-03-17 17:33:50 -04:00
Dianne Skoll
c927166a8a Accept but warn if $Latitude/$Longituded uses locale decimal separator instead of "." 2022-03-17 11:29:27 -04:00
Dianne Skoll
9d22fba842 Document that decimal separator for $Latitude and $Longitude is always "." 2022-03-17 11:23:16 -04:00
Dianne Skoll
3d5adf6c42 Always interpret $Latitude and $Longitude values in the C locale. 2022-03-17 11:21:27 -04:00
Dianne Skoll
5ba862cbd7 Don't define RET as 'remind-indent-line 2022-03-17 10:22:13 -04:00
Dianne Skoll
6f20e056c9 Allow day numbers to be anchored to left, center or right.
Based on a patch from Paulo <qsmodo *AT* tutanota.com>
2022-03-16 17:30:06 -04:00
Dianne Skoll
878ab1a8bc Fix a bunch of spelling mistakes found by Jens Schleusener 2022-03-15 14:40:46 -04:00
Dianne Skoll
4d17494371 Bump copyright date. 2022-03-14 21:12:20 -04:00
Dianne Skoll
65763b9522 Document release date. 2022-03-14 17:37:03 -04:00
Dianne Skoll
52840d40de Update docs. 2022-03-14 17:07:04 -04:00
Dianne Skoll
6892e7a805 Better mode name. 2022-03-13 16:59:27 -04:00
Dianne Skoll
24d0264f92 Improve remind-conf-mode syntax highlighting to make it case-insensitive. 2022-03-13 16:56:47 -04:00
Dianne Skoll
56c37e4e05 Bump version. 2022-03-13 16:26:44 -04:00
Dianne Skoll
86c99102b5 Update remind-conf-mode.el with new keywords, built-in variables and functions 2022-03-13 16:25:58 -04:00
Dianne Skoll
de4a23ee1e Add DO keyword to remind.vim 2022-03-13 16:09:06 -04:00
Dianne Skoll
6a9f7c186a Refactor code to reduce cut-n-paste. 2022-03-13 09:15:48 -04:00
Dianne Skoll
eaed22a42b Fix typo 2022-03-13 09:11:03 -04:00
Dianne Skoll
f47cf2320e Catch expression-pasting errors on all REM commands. 2022-03-12 15:51:30 -05:00
Dianne Skoll
eb100e57e2 Parse untriggered reminder lines to catch expression-pasting errors. 2022-03-12 15:48:31 -05:00
Dianne Skoll
948548c73f Update docs. 2022-03-12 12:57:24 -05:00
Dianne Skoll
7495ae1e05 Uniquify lines in error message to avoid overwhelming. 2022-03-12 11:32:26 -05:00
Dianne Skoll
51ae17bd0a Improve the way TkRemind handles errors in the reminder script. 2022-03-12 11:23:54 -05:00
Dianne Skoll
61d665ef7d Turn a bunch of Eprint calls into Wprint calls to indicate warnings instead of errors. 2022-03-12 10:27:58 -05:00
Dianne Skoll
5aaf19ffdb Send LRM sequence in PrintLeft and PrintCentered. 2022-03-12 09:39:28 -05:00
Dianne Skoll
2eb672e380 Add LRM marks in UTF-8 locales. 2022-03-12 09:33:16 -05:00
Dianne Skoll
4a59bf686b Check for langinfo.h 2022-03-12 09:26:41 -05:00
Dianne Skoll
f98ab6f686 Document special behavior of "-cu" 2022-03-11 23:31:04 -05:00
Dianne Skoll
3600cd95cd Add LRM char if we're using Unicode drawing chars 2022-03-11 23:28:03 -05:00
Dianne Skoll
f8bd79fbb2 Fix bug in calendar formatting 2022-03-11 23:18:38 -05:00
Dianne Skoll
4c403047eb Tweaks 2022-03-11 23:10:37 -05:00
Dianne Skoll
25009de417 Update defs.rem 2022-03-11 23:06:24 -05:00
Dianne Skoll
c4588654ec Clean up cruft in defs.rem 2022-03-11 23:02:37 -05:00
Dianne Skoll
c1e5279272 Tweak meeting reminder. 2022-03-11 22:55:51 -05:00
Dianne Skoll
cda8396690 Update copyright date. 2022-03-11 22:52:29 -05:00
Dianne Skoll
c0f79d1e69 Bump mininum remind version. 2022-03-11 22:52:05 -05:00
Dianne Skoll
375a0fb7a2 Update examples to use syntactic sugar. 2022-03-11 22:51:22 -05:00
Dianne Skoll
2069114ef1 More wrap testing. 2022-03-11 22:39:29 -05:00
Dianne Skoll
f6d9e8724d Make test to test wrapping of wide chars 2022-03-11 22:37:40 -05:00
Dianne Skoll
8e55438200 Minor tweak 2022-03-11 22:36:52 -05:00
Dianne Skoll
1ca6feb112 Fix formatting bug when printing calendar with wide spaces. 2022-03-11 22:31:40 -05:00
Dianne Skoll
732ce8283f Update docs. 2022-03-11 21:47:50 -05:00
Dianne Skoll
122bd3e07e Add comment 2022-03-11 21:27:33 -05:00
Dianne Skoll
0ac5cbb837 Properly cope with two of the same moon phase in a given month. 2022-03-11 21:26:22 -05:00
Dianne Skoll
7f3d4812a8 Add Lastday and Lastworkday syntactic sugar 2022-03-11 21:11:16 -05:00
Dianne Skoll
e1fa11c94c Add the First/Second/Third/Fourth/Last syntactic sugar and the
~N/~~N forms of "back"
2022-03-11 20:53:52 -05:00
Dianne Skoll
c06c65acf1 Properly apply options in the right order. 2022-03-11 19:57:20 -05:00
Dianne Skoll
a84fa0bc8f Add canned "Light Theme" and "Dark Theme" buttons. 2022-03-11 19:46:40 -05:00
Dianne Skoll
054648e02b More display tweakage. 2022-03-11 14:35:39 -05:00
Dianne Skoll
9548041334 Tweak display; make keyboard traversal better. 2022-03-11 14:29:07 -05:00
Dianne Skoll
da306f2900 Tweak wording 2022-03-11 13:46:43 -05:00
Dianne Skoll
26587aea02 Give more control over TkRemind colors. 2022-03-11 13:38:11 -05:00
Dianne Skoll
adc86e0f00 Allow setting of "Today" highlight color. 2022-03-10 11:53:00 -05:00
Dianne Skoll
a9ed5f075e Document that trig() and SATISFY should not be mixed. 2022-03-05 11:35:55 -05:00
Dianne Skoll
21e30c980e Test multiple-argument version of trig() 2022-03-04 17:29:23 -05:00
Dianne Skoll
a657b2e55a Update man page. 2022-03-04 15:40:39 -05:00
Dianne Skoll
ff8c55b8b6 Rename "wouldtrig" to just "trig" 2022-03-04 15:38:07 -05:00
Dianne Skoll
eb36c5bca0 Allow wouldtrig() to take an arbitrary number of args; document it. 2022-03-04 15:24:52 -05:00
Dianne Skoll
89173ce1ee Allow logical operators to accept any non-string operands.
Make wouldtrig() return a date.
2022-03-04 14:59:17 -05:00
Dianne Skoll
5d115ba3e3 Document actual behavior of IF command. 2022-03-04 14:58:49 -05:00
Dianne Skoll
7e3adeb9c9 Make wouldtrig return the trigger date (as an INT, coercable to a date)
Update man page.
2022-03-04 12:28:13 -05:00
Dianne Skoll
080cda86fa Document new || and && return values. 2022-03-04 12:12:49 -05:00
Dianne Skoll
6274cbad52 Make || return first true val and && return last val if first val is true. 2022-03-04 12:11:25 -05:00
Dianne Skoll
85c4ad821d Add note about Remind lacking short-circuit logical operators. 2022-03-04 11:45:37 -05:00
Dianne Skoll
b758a2fea8 Tweak formatting. 2022-03-04 11:40:46 -05:00
Dianne Skoll
6619cc7ca4 Add wouldtrig tests. 2022-03-04 11:33:03 -05:00
Dianne Skoll
961f7a8a62 Document wouldtrig() 2022-03-04 11:21:14 -05:00
Dianne Skoll
905287901f Add zero-argument form of wouldtrig. 2022-03-04 11:16:33 -05:00
Dianne Skoll
669be7bf57 Add wouldtrig function. 2022-03-04 11:00:09 -05:00
Dianne Skoll
9b8eb2dc4c Support calling EvalExpr recursively 2022-03-04 10:49:20 -05:00
Dianne Skoll
00ab7b196d Set default of $MaxSatIter to 1000 instead of 150.
Computers are much faster than when Remind was first written;
we can handle a much higher limit.
2022-03-04 08:18:49 -05:00
Dianne Skoll
f616be4bdd Add comment about operator precedence. 2022-03-04 08:16:58 -05:00
Dianne Skoll
8ae9ce8523 Tweak man page. 2022-03-02 15:30:56 -05:00
Dianne Skoll
6d2bbbd7e2 Another diagnostic message. 2022-03-02 15:25:27 -05:00
Dianne Skoll
1453be83b2 Add more diagnostics for bad UNTIL dates. 2022-03-02 15:17:03 -05:00
Dianne Skoll
8659131be2 Use proper keyword in error message. 2022-03-02 14:43:11 -05:00
Dianne Skoll
0276ce322d Diagnose if UNTIL is earlier than start date unless there is a nonconst expr 2022-03-02 09:11:01 -05:00
Dianne Skoll
b36c99a34b Move successful exit to one spot. 2022-03-02 09:01:33 -05:00
Dianne Skoll
ad575f1485 Proper check for overfull box. 2022-03-01 16:15:00 -05:00
Dianne Skoll
a9162f1472 Proper calculation for warning of overfull box. 2022-03-01 16:12:55 -05:00
Dianne Skoll
221e2554a9 Prep for 03.04.01 release. 2022-02-23 11:09:39 -05:00
Dianne Skoll
04ec6c3695 Update TodayDay, TodayMonth and TodayYear in Initialize, in case date has rolled over 2022-02-15 10:04:30 -05:00
Dianne Skoll
b1594980fc Add --disable-perl-build-artifacts flag to configure. 2022-02-13 10:42:50 -05:00
Dianne Skoll
024a8ef38d Double-check that chosen font size for small calendars won't overflow box. 2022-02-13 10:33:21 -05:00
Dianne Skoll
b281051421 Don't overflow small calendar box. 2022-02-12 23:30:08 -05:00
Dianne Skoll
aa1b275b51 Support INSTALL_BASE 2022-02-11 10:55:59 -05:00
Dianne Skoll
c22ca68857 Support INSTALL_BASE env var 2022-02-11 10:39:31 -05:00
Dianne Skoll
3804ce3fe3 Prep for 03.04.00 release. 2022-02-10 17:15:01 -05:00
Dianne Skoll
0977f1db04 Don't export the 'php' directory. 2022-02-10 10:07:41 -05:00
Dianne Skoll
83c97934c9 Fix typo 2022-02-09 09:43:11 -05:00
Dianne Skoll
44c9d74caa Preserve #include "custom.h" in config.h.in. Patch due to Jochen Sprickerhof 2022-02-09 09:10:47 -05:00
Dianne Skoll
172f56754a Fix groff errors - patch from Jochen Sprickerhof 2022-02-09 08:59:58 -05:00
Dianne Skoll
dc184cc713 Don't fail "make clean" in src - patch from Jochen Sprickerhof. 2022-02-09 08:58:47 -05:00
113 changed files with 10211 additions and 2173 deletions

3
.gitattributes vendored
View File

@@ -1,4 +1,5 @@
.gitignore export-ignore
.gitattributes export-ignore
remind.php export-ignore
sync-to-dianne-git export-ignore
sync-to-dianne-git export-ignore
php export-ignore

2
.github/FUNDING.yml vendored Normal file
View File

@@ -0,0 +1,2 @@
liberapay: dskoll

7
.github/README.md vendored Normal file
View File

@@ -0,0 +1,7 @@
# Remind has moved
For various reasons, I have decided to move Remind off GitHub. This repo
will be archived. To create merge requests or issues, please visit
Remind's new home at https://salsa.debian.org/dskoll/remind
-- Dianne Skoll

29
.github/workflows/github-action.yml vendored Normal file
View File

@@ -0,0 +1,29 @@
# language: bash
---
name: Remind unit tests
on:
push
jobs:
tests:
runs-on: ubuntu-latest
steps:
- name: Checkout Remind
uses: actions/checkout@v2
- name: Add test user
run: |
sudo adduser --home /home/testuser --gecos 'Test User' --disabled-password testuser
- name: Fix ownership
run: |
sudo chown -R testuser .
- name: Build
run: |
sudo su -c './configure && make' testuser
- name: Run Tests
run: |
sudo su -c 'make test' testuser
- name: Fix up permissions so GitHub does not complain
run: |
sudo chmod -R a+rwX .

27
.gitignore vendored
View File

@@ -1,27 +1,34 @@
rem2pdf/Makefile.old
*.bak
*.o
*~
.gitignore
MYMETA.json
MYMETA.yml
Makefile
TAGS
autom4te.cache
blib/
config.log
config.status
man/rem.1
man/rem2ps.1
man/remind.1
man/tkremind.1
pm_to_blib
rem2html/Makefile
rem2html/rem2html.1
rem2pdf/Makefile.PL
rem2pdf/Makefile.old
rem2pdf/Makefile.top
rem2pdf/bin/rem2pdf
set-irc-topic
src/*.tar.gz*
src/Makefile
src/config.h
src/rem2ps
src/remind
src/test-*.out
src/version.h
tests/test.out
www/Makefile
rem2pdf/Makefile.PL
MYMETA.json
MYMETA.yml
Makefile
blib/
pm_to_blib
rem2pdf/Makefile.top
rem2pdf/bin/rem2pdf
rem2html/rem2html.1
gmon.out

13
.gitlab-ci.yml Normal file
View File

@@ -0,0 +1,13 @@
tests:
image: 'debian:stable-slim'
before_script:
- apt update && apt-get -y install gcc make
- useradd --create-home testuser
- chown -R testuser .
- chmod -R go-w .
script:
- LANG=C.UTF-8 su testuser -c './configure && make all && make test'
artifacts:
when: always
paths:
- tests/test.out

View File

@@ -3,7 +3,7 @@ THE REMIND COPYRIGHT
1. REMIND refers to the entire set of files and documentation in the
REMIND package.
2. REMIND is Copyright 1992-2021 Dianne Skoll, except where noted in
2. REMIND is Copyright 1992-2022 Dianne Skoll, except where noted in
individual files.
3. DISTRIBUTION AND USE

View File

@@ -12,20 +12,33 @@ all: src/Makefile
@$(MAKE) -C rem2pdf -f Makefile.top
install:
@echo ""
@echo "*********************"
@echo "* *"
@echo "* Installing REMIND *"
@echo "* *"
@echo "*********************"
@echo "**********************************"
@echo "* *"
@echo "* Installing REMIND (unstripped) *"
@echo "* *"
@echo "**********************************"
@echo ""
@$(MAKE) -C src install
@$(MAKE) -C rem2html install
@$(MAKE) -C rem2pdf -f Makefile.top install
@$(MAKE) -C rem2pdf -f Makefile.top install INSTALL_BASE=$(INSTALL_BASE)
clean:
find . -name '*~' -exec rm {} \;
$(MAKE) -C src clean
-rm man/rem.1 man/rem2ps.1 man/remind.1 man/tkremind.1
-$(MAKE) -C src clean
-$(MAKE) -C rem2pdf clean
install-stripped:
@echo ""
@echo "********************************"
@echo "* *"
@echo "* Installing REMIND (stripped) *"
@echo "* *"
@echo "**********************************"
@echo ""
@$(MAKE) -C src install-stripped
@$(MAKE) -C rem2html install
@$(MAKE) -C rem2pdf -f Makefile.top install INSTALL_BASE=$(INSTALL_BASE)
test:
@$(MAKE) -C src -s test

40
README
View File

@@ -34,5 +34,45 @@ If you do NOT have Tcl/Tk or are NOT running X Windows:
5) Type: "make install" -- you may need to be root to do this.
PREREQUISITES:
--------------
Remind and rem2ps have no prerequisites beyond the standard C library and
the standard math library.
Rem2HTML requires the JSON::MaybeXS Perl module.
Rem2PDF requires the JSON::MaybeXS, Pango and Cairo Perl modules.
- On Debian-like systems, these prerequisites may be installed with:
apt install libjson-maybexs-perl libpango-perl libcairo-perl
- On RPM-based systems, you need perl-Pango, perl-Cairo and perl-JSON-MaybeXS
- On Gentoo, you need dev-perl/Pango, dev-perl/Cairo and dev-perl/JSON-MaybeXS.
- On Arch linux, you need pango-perl, cairo-perl and perl-json-maybexs
TkRemind requires Tcl/Tk and the tcllib library.
- On Debian-like systems, install with:
apt install tcl tk tcllib
- On RPM-based systems, you need tcl, tk and tcllib
- On Arch Linux, you need tk and tcllib. The latter is available at
https://aur.archlinux.org/packages/tcllib
If the little arrows for "Previous Month" and "Next Month" do not display
correctly in TkRemind, you may need to install the Noto Fonts. Install
all of your distribution's Nonto Font-related packages.
- On Debian-like systems, install with:
apt install fonts-noto-core fonts-noto-color-emoji \
fonts-noto-extra fonts-noto-ui-core fonts-noto-ui-extra
==========================================================================
Contact info: mailto:dianne@skoll.ca
Home page: https://dianne.skoll.ca/projects/remind/

View File

@@ -355,7 +355,7 @@ proc RunCommand { cmd } {
# %RETURNS:
# Nothing
# %DESCRIPTION:
# Reads characters from command pipelin and appends them to .msg.
# Reads characters from command pipeline and appends them to .msg.
#***********************************************************************
proc CommandReadable { f } {
global CmdDone

70
configure vendored
View File

@@ -622,6 +622,8 @@ ac_includes_default="\
ac_header_list=
ac_subst_vars='LTLIBOBJS
LIBOBJS
RELEASE_DATE
PERLARTIFACTS
VERSION
EGREP
GREP
@@ -681,6 +683,7 @@ SHELL'
ac_subst_files=''
ac_user_opts='
enable_option_checking
enable_perl_build_artifacts
'
ac_precious_vars='build_alias
host_alias
@@ -1305,6 +1308,13 @@ if test -n "$ac_init_help"; then
cat <<\_ACEOF
Optional Features:
--disable-option-checking ignore unrecognized --enable/--with options
--disable-FEATURE do not include FEATURE (same as --enable-FEATURE=no)
--enable-FEATURE[=ARG] include FEATURE [ARG=yes]
--disable-perl-build-artifacts
Disable perllocal.pod and .packlist generation
Some influential environment variables:
CC C compiler command
CFLAGS C compiler flags
@@ -2292,6 +2302,16 @@ EOF
ac_config_headers="$ac_config_headers src/config.h"
# Check whether --enable-perl-build-artifacts was given.
if test "${enable_perl_build_artifacts+set}" = set; then :
enableval=$enable_perl_build_artifacts; ac_cv_perlartifacts=$enableval
else
ac_cv_perlartifacts=yes
fi
ac_ext=c
ac_cpp='$CPP $CPPFLAGS'
ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
@@ -3287,7 +3307,6 @@ fi
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for sqrt in -lm" >&5
$as_echo_n "checking for sqrt in -lm... " >&6; }
if ${ac_cv_lib_m_sqrt+:} false; then :
@@ -3798,7 +3817,7 @@ _ACEOF
for ac_header in sys/types.h sys/file.h glob.h wctype.h locale.h
for ac_header in sys/types.h sys/file.h glob.h wctype.h locale.h langinfo.h
do :
as_ac_Header=`$as_echo "ac_cv_header_$ac_header" | $as_tr_sh`
ac_fn_c_check_header_mongrel "$LINENO" "$ac_header" "$as_ac_Header" "$ac_includes_default"
@@ -3955,8 +3974,45 @@ fi
if test "$GCC" = yes; then
CFLAGS="$CFLAGS -Wall -Wextra -Wstrict-prototypes"
# Check for link-time optimization support
f=-flto=auto
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether $CC supports $f" >&5
$as_echo_n "checking whether $CC supports $f... " >&6; }
if $CC -E $f /dev/null > /dev/null 2>&1 ; then
{ $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
$as_echo "yes" >&6; }
CFLAGS="$CFLAGS $f"
f=-ffat-lto-objects
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether $CC supports $f" >&5
$as_echo_n "checking whether $CC supports $f... " >&6; }
if $CC -E $f /dev/null > /dev/null 2>&1 ; then
{ $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
$as_echo "yes" >&6; }
CFLAGS="$CFLAGS $f"
else
{ $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
$as_echo "no" >&6; }
fi
else
{ $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
$as_echo "no" >&6; }
fi
fi
if test "$ac_cv_perlartifacts" = "yes" ; then
PERLARTIFACTS=
else
PERLARTIFACTS='NO_PACKLIST=1 NO_PERLLOCAL=1'
fi
RELEASE_DATE=`grep '[0-9][0-9][0-9][0-9]-[0-9][0-9]-[0-9][0-9]' docs/WHATSNEW | head -n 1 | awk '{print $NF}'`
# Sanity-check release date
echo "$RELEASE_DATE" | grep '^....-..-..$' > /dev/null 2>&1
if test "$?" != 0 ; then
echo "*** COULD NOT DETERMINE RELEASE DATE: docs/WHATSNEW is incorrect!"
exit 1
fi
for ac_func in setenv unsetenv glob mbstowcs setlocale initgroups
do :
as_ac_var=`$as_echo "ac_cv_func_$ac_func" | $as_tr_sh`
@@ -3969,10 +4025,12 @@ _ACEOF
fi
done
VERSION=03.04.00
VERSION=04.02.01
ac_config_files="$ac_config_files src/Makefile www/Makefile src/version.h rem2html/Makefile rem2pdf/Makefile.PL rem2pdf/Makefile.top rem2pdf/bin/rem2pdf"
ac_config_files="$ac_config_files src/Makefile www/Makefile src/version.h rem2html/Makefile rem2pdf/Makefile.PL rem2pdf/Makefile.top rem2pdf/bin/rem2pdf man/rem.1 man/rem2ps.1 man/remind.1 man/tkremind.1"
cat >confcache <<\_ACEOF
# This file is a shell script that caches the results of configure
@@ -4672,6 +4730,10 @@ do
"rem2pdf/Makefile.PL") CONFIG_FILES="$CONFIG_FILES rem2pdf/Makefile.PL" ;;
"rem2pdf/Makefile.top") CONFIG_FILES="$CONFIG_FILES rem2pdf/Makefile.top" ;;
"rem2pdf/bin/rem2pdf") CONFIG_FILES="$CONFIG_FILES rem2pdf/bin/rem2pdf" ;;
"man/rem.1") CONFIG_FILES="$CONFIG_FILES man/rem.1" ;;
"man/rem2ps.1") CONFIG_FILES="$CONFIG_FILES man/rem2ps.1" ;;
"man/remind.1") CONFIG_FILES="$CONFIG_FILES man/remind.1" ;;
"man/tkremind.1") CONFIG_FILES="$CONFIG_FILES man/tkremind.1" ;;
*) as_fn_error $? "invalid argument: \`$ac_config_target'" "$LINENO" 5;;
esac

View File

@@ -14,6 +14,12 @@ EOF
AC_CONFIG_HEADER(src/config.h)
AC_ARG_ENABLE(perl-build-artifacts,
[ --disable-perl-build-artifacts
Disable perllocal.pod and .packlist generation], ac_cv_perlartifacts=$enableval, ac_cv_perlartifacts=yes)
AH_BOTTOM([#include <custom.h>])
dnl Checks for programs.
AC_PROG_CC
AC_PROG_INSTALL
@@ -22,8 +28,6 @@ AC_PROG_MAKE_SET
AC_PATH_PROG([PERL], [perl])
dnl Checks for libraries.
dnl Replace `main' with a function in -lm:
AC_CHECK_LIB(m, sqrt)
dnl Integer sizes
@@ -31,7 +35,7 @@ AC_CHECK_SIZEOF(unsigned int)
AC_CHECK_SIZEOF(unsigned long)
dnl Checks for header files.
AC_CHECK_HEADERS(sys/types.h sys/file.h glob.h wctype.h locale.h)
AC_CHECK_HEADERS(sys/types.h sys/file.h glob.h wctype.h locale.h langinfo.h)
dnl Checks for typedefs, structures, and compiler characteristics.
AC_STRUCT_TM
@@ -42,11 +46,44 @@ AC_HEADER_TIME
if test "$GCC" = yes; then
CFLAGS="$CFLAGS -Wall -Wextra -Wstrict-prototypes"
# Check for link-time optimization support
f=-flto=auto
AC_MSG_CHECKING([whether $CC supports $f])
if $CC -E $f /dev/null > /dev/null 2>&1 ; then
AC_MSG_RESULT([yes])
CFLAGS="$CFLAGS $f"
f=-ffat-lto-objects
AC_MSG_CHECKING([whether $CC supports $f])
if $CC -E $f /dev/null > /dev/null 2>&1 ; then
AC_MSG_RESULT([yes])
CFLAGS="$CFLAGS $f"
else
AC_MSG_RESULT([no])
fi
else
AC_MSG_RESULT([no])
fi
fi
if test "$ac_cv_perlartifacts" = "yes" ; then
PERLARTIFACTS=
else
PERLARTIFACTS='NO_PACKLIST=1 NO_PERLLOCAL=1'
fi
RELEASE_DATE=`grep '[[0-9]][[0-9]][[0-9]][[0-9]]-[[0-9]][[0-9]]-[[0-9]][[0-9]]' docs/WHATSNEW | head -n 1 | awk '{print $NF}'`
# Sanity-check release date
echo "$RELEASE_DATE" | grep '^....-..-..$' > /dev/null 2>&1
if test "$?" != 0 ; then
echo "*** COULD NOT DETERMINE RELEASE DATE: docs/WHATSNEW is incorrect!"
exit 1
fi
AC_CHECK_FUNCS(setenv unsetenv glob mbstowcs setlocale initgroups)
VERSION=03.04.00
VERSION=04.02.01
AC_SUBST(VERSION)
AC_SUBST(PERL)
AC_OUTPUT(src/Makefile www/Makefile src/version.h rem2html/Makefile rem2pdf/Makefile.PL rem2pdf/Makefile.top rem2pdf/bin/rem2pdf)
AC_SUBST(PERLARTIFACTS)
AC_SUBST(RELEASE_DATE)
AC_OUTPUT(src/Makefile www/Makefile src/version.h rem2html/Makefile rem2pdf/Makefile.PL rem2pdf/Makefile.top rem2pdf/bin/rem2pdf man/rem.1 man/rem2ps.1 man/remind.1 man/tkremind.1)
chmod a+x rem2pdf/bin/rem2pdf

View File

@@ -32,7 +32,7 @@
# version 0.5 2007-03-21
# - Add more help options
# - --project-lead-time option
# - Supress printing of heading if there are no todos to print
# - Suppress printing of heading if there are no todos to print
# version 0.4
# - Version 0.4 changes all written or inspired by, and thanks to Mark Stosberg
# - Change to GetOptions
@@ -84,7 +84,7 @@ How may days in advance to start getting reminders about the events. Defaults to
ical2rem.pl --no-todos
If you don't care about the ToDos the calendar, this will surpress
If you don't care about the ToDos the calendar, this will suppress
printing of the ToDo heading, as well as skipping ToDo processing.
=head2 --heading

View File

@@ -141,7 +141,7 @@ appear with exactly the text and exactly the same duration (including
one VEVENT object, that will have a RFC2445 C<RDATE> property.
B<rem2ics> is not yet smart enough to derive an C<RRULE> based
recurrance. If you really want that feature, either implement it and
recurrence. If you really want that feature, either implement it and
send in a patch, or contact the author and convince him to do it.
=head2 Other iCalendar Properties
@@ -164,7 +164,7 @@ runs.
=head2 Other iCalendar Perl objects
Why does't B<rem2ics> use any of the iCalendar Perl stuff in CPAN?
Why doesn't B<rem2ics> use any of the iCalendar Perl stuff in CPAN?
Because I don't trust them, and they are too big for this app. One
links to a binary library. Another hasn't been maintained since 1991,
and is full of notes as to how buggy and incomplete it is. And so
@@ -218,7 +218,7 @@ Bug fix, error message for non-recurring events
Bug fix,
rem2ics 0.91 chokes on timed reminders with
duration using `remind -s` as it functions in remind-03.01.03.
Remind 3.01 changed how the -s data is formated for events that have a duration
Remind 3.01 changed how the -s data is formatted for events that have a duration
Patch by Paul Hinze E<lt>paul dot t dot hinze at gmail dot comE<gt>
and Michael Schultz E<lt>mjschultz at gmail dot comE<gt>
@@ -376,7 +376,7 @@ foreach $v (@events) {
my(%grovel);
# if the user doesnt want recurrance detection
# if the user doesn't want recurrence detection
unless ($options{norecurr}) {
# then dont put events in the grovel hash
@@ -393,7 +393,7 @@ unless ($options{norecurr}) {
$v = ${$grovel{$k}}[0];
$v->{recurlist} = \@{$grovel{$k}};
foreach my $v0 (@{$grovel{$k}}) {
$v0->{is_recurrance} = $v;
$v0->{is_recurrence} = $v;
}
}
}
@@ -409,12 +409,12 @@ unless ($options{norecurr}) {
# might have a problem if a recurring event has two instances both on
# the first day.
# Every event that is recurring has a "is_recurrance" property.
# Every event that is recurring has a "is_recurrence" property.
# Additionally, (hopefully) the first/earliest event in a set of
# recurrances has a "recurlist" property. The "recurlist" is a
# recurrences has a "recurlist" property. The "recurlist" is a
# reference to a list of references to each of the events. The first
# one on that list will be the same event that has the "recurlist"
# property. The "is_recurrance" property is a reference back to the
# property. The "is_recurrence" property is a reference back to the
# event that has the "recurlist" property.
foreach my $k (keys %grovel) {
@@ -466,8 +466,8 @@ foreach my $k (keys %grovel) {
}
foreach $v (@events) {
# for recurrant events, skip those that arnt the "head"
next if ($v->{is_recurrance} and (not $v->{recurlist}));
# for recurrent events, skip those that arnt the "head"
next if ($v->{is_recurrence} and (not $v->{recurlist}));
if (${$v->{sf}}[4] eq "*") { # no time was given
$v->{i_dtstart} = sprintf("DTSTART:%s", $v->{dts});
@@ -485,7 +485,7 @@ foreach $v (@events) {
}
if (${$v->{sf}}[3] ne "*") { # a duration was given
# It's convienient that RFC2445 defines DURATION, thus we
# It's convenient that RFC2445 defines DURATION, thus we
# don't need to calculate DTEND, with awkward figuring out
# crossing hours, days, months, year, etc. Instead we
# will let the iCalendar consuming application worry about it.
@@ -501,8 +501,8 @@ print "BEGIN:VCALENDAR\015\012"
# output each vevent
foreach $v (@events) {
# for recurrant events, only output the "head", skip the others
next if ($v->{is_recurrance} and (not $v->{recurlist}));
# for recurrent events, only output the "head", skip the others
next if ($v->{is_recurrence} and (not $v->{recurlist}));
print "BEGIN:VEVENT\015\012";
my $tag = ${$v->{sf}}[2];

View File

@@ -5,7 +5,7 @@
;; Author: Shelagh Manton <shelagh.manton@gmail.com> with help from
;; Dianne Skoll
;; Keywords: remind configure convenience
;; Version: 0.14
;; Version: 0.15-dfs2
;; This program is free software; you can redistribute it and/or
;; modify it under the terms of the GNU General Public License
@@ -91,7 +91,6 @@
(define-key remind-conf-mode-map "\C-c\C-x" 'rem-tomorrow)
(define-key remind-conf-mode-map "\C-c\C-a" 'rem-days-away)
(define-key remind-conf-mode-map "\M-j" 'remind-indent-line)
(define-key remind-conf-mode-map (kbd "RET") 'remind-indent-line)
(define-key remind-conf-mode-map "\C-c\C-c" 'rem-save-file)
;; syntax-table
@@ -111,12 +110,18 @@
(defconst remind-keywords
(sort
(list "RUN" "REM" "ONCE" "SATISFY" "BEFORE" "UNSET" "OMIT" "FIRST" "SATISFY"
"OMIT" "DATE" "SKIP" "ONCE" "AFTER" "WARN" "PRIORITY" "AT" "SCHED" "IF" "ELSE" "ENDIF"
"WARN" "UNTIL" "THROUGH" "SCANFROM" "DURATION" "TAG" "MSG" "MSF" "CAL" "SPECIAL" "IFTRIG"
"PS" "PSFILE" "BANNER" "INCLUDE" "PUSH-OMIT-CONTEXT" "DEBUG" "DUMPVARS" "PUSH" "CLEAR" "POP"
"CLEAR-OMIT-CONTEXT" "POP-OMIT-CONTEXT" "SET" "ERRMSG" "FSET" "DUMP" "BAN" "INC" "SCAN"
"EXIT" "FLUSH" "PRESERVE" "MOON" "COLOR" "UNSET")
(list "ADDOMIT" "AFTER" "AT" "BANNER" "BEFORE"
"CAL" "CLEAR-OMIT-CONTEXT" "DEBUG" "DO" "DUMPVARS"
"DURATION" "ELSE" "ENDIF" "ERRMSG" "EXIT" "FIRST"
"FLUSH" "FOURTH" "FROM" "FSET" "IF" "IFTRIG" "IN"
"INCLUDE" "INCLUDECMD" "LAST" "LASTDAY"
"LASTWORKDAY" "MAYBE-UNCOMPUTABLE" "MSF"
"MSG" "OMIT" "OMITFUNC" "ONCE"
"POP-OMIT-CONTEXT" "PRESERVE" "PRIORITY" "PS" "PSFILE"
"PUSH-OMIT-CONTEXT" "REM" "RUN" "SATISFY" "SCANFROM"
"SCHED" "SECOND" "SET" "SKIP" "SPECIAL"
"TAG" "THIRD" "THROUGH" "UNSET" "UNTIL"
"WARN")
#'(lambda (a b) (> (length a) (length b)))))
@@ -127,12 +132,20 @@
(defconst remind-builtin-variables
(sort
(list "$CalcUTC" "$CalMode" "$Daemon" "$DateSep" "$DefaultPrio" "$DontFork" "$DontTrigAts" "$DontQueue"
"$EndSent" "$EndSentIg" "$NumTrig" "$FirstIndent" "$FoldYear" "$FormWidth" "$HushMode"
"$IgnoreOnce" "$InfDelta" "$NextMode" "$NumQueued" "$NumTrig" "$PrefixLineNo" "$PSCal" "$RunOff"
"$SimpleCal" "$SortByDate" "$SortByPrio" "$MinsFromUTC" "$LatDeg" "$LatMin" "$LatSec" "$EndSent"
"$EndSentIg" "$Location" "$LongDeg" "$LongMin" "$LongSec" "$MaxSatIter" "$SubsIndent" "$T" "$Td"
"$Tm" "$Tw" "$Ty" "$TimeSep" "$UntimedFirst" "$U" "$Ud" "$Um" "$Uw" "$Uy")
(list "$Ago" "$Am" "$And" "$April" "$At" "$August" "$CalcUTC" "$CalMode" "$Daemon" "$DateSep"
"$DateTimeSep" "$December" "$DefaultColor" "$DefaultPrio"
"$DefaultTDelta" "$DeltaOffset" "$DontFork" "$DontQueue"
"$DontTrigAts" "$EndSent" "$EndSentIg" "$February" "$FirstIndent"
"$FoldYear" "$FormWidth" "$Friday" "$Fromnow" "$Hour" "$Hplu" "$HushMode" "$IgnoreOnce"
"$InfDelta" "$IntMax" "$IntMin" "$Is" "$January" "$July" "$June" "$LatDeg"
"$Latitude" "$LatMin" "$LatSec" "$Location" "$LongDeg" "$Longitude"
"$LongMin" "$LongSec" "$March" "$MaxSatIter" "$MaxStringLen" "$May"
"$MinsFromUTC" "$Minute" "$Monday" "$Mplu" "$NextMode" "$November" "$Now" "$NumQueued"
"$NumTrig" "$October" "$On" "$Pm" "$PrefixLineNo" "$PSCal" "$RunOff" "$Saturday"
"$September" "$SimpleCal" "$SortByDate" "$SortByPrio" "$SortByTime"
"$SubsIndent" "$Sunday" "$SysInclude" "$T" "$Td" "$Thursday" "$TimeSep" "$Tm"
"$Today" "$Tomorrow" "$Tuesday" "$Tw" "$Ty" "$U" "$Ud" "$Um" "$UntimedFirst" "$Uw" "$Uy"
"$Was" "$Wednesday")
#'(lambda (a b) (> (length a) (length b)))))
@@ -147,15 +160,22 @@
(defconst remind-builtin-functions
(sort
(list "abs" "access" "args" "asc" "baseyr" "char" "choose" "coerce" "current" "date" "datetime" "datepart"
"dawn" "day" "daysinmon" "defined" "dosubst" "dusk" "easter" "easterdate" "evaltrig" "filedate"
"filedatetime" "filedir" "filename" "getenv" "hebdate" "hebday" "hebmon" "hebyear" "hour" "iif" "index" "isdst"
"isleap" "isomitted" "language" "lower" "max" "min" "minute" "minsfromutc" "mon" "monnum" "moondate" "moondatetime"
"moonphase" "moontime" "msgprefix" "msgsuffix" "nonomitted" "now" "ord" "ostype" "plural"
"psmoon" "psshade" "realcurrent" "realnow" "realtoday" "sgn" "shell" "slide" "strlen" "substr" "sunrise" "sunset" "time" "timepart"
"thisyear" "today" "trigdate" "trigdatetime" "trigger" "trigger" "trigtime" "trigvalid" "typeof" "tzconvert" "upper" "value"
"version" "weekno" "wkday" "wkdaynum" "year"
)
(list "abs" "access" "adawn" "adusk" "ampm" "args" "asc" "baseyr" "char"
"choose" "coerce" "current" "date" "datepart" "datetime" "dawn" "day"
"daysinmon" "defined" "dosubst" "dusk" "easterdate" "evaltrig"
"filedate" "filedatetime" "filedir" "filename" "getenv" "hebdate"
"hebday" "hebmon" "hebyear" "hour" "iif" "index" "isany" "isdst"
"isleap" "isomitted" "language" "lower" "max" "min" "minsfromutc"
"minute" "mon" "monnum" "moondate" "moondatetime" "moonphase"
"moontime" "ndawn" "ndusk" "nonomitted" "now" "ord" "ostype" "pad" "plural"
"psmoon" "psshade" "realcurrent" "realnow" "realtoday" "sgn" "shell"
"shellescape" "slide" "strlen" "substr" "sunrise" "sunset" "time"
"timepart" "today" "trig" "trigback" "trigdate" "trigdatetime"
"trigdelta" "trigduration" "trigeventduration" "trigeventstart"
"trigfrom" "trigger" "trigpriority" "trigrep" "trigscanfrom"
"trigtime" "trigtimedelta" "trigtimerep" "triguntil" "trigvalid"
"typeof" "tzconvert" "upper" "value" "version" "weekno" "wkday"
"wkdaynum" "year")
#'(lambda (a b) (> (length a) (length b)))))
;;; faces
@@ -244,12 +264,35 @@
:group 'remind-conf
)
(defconst remind-keywords-regex (regexp-opt remind-keywords 'words))
(defconst remind-type-keywords-regex (regexp-opt remind-type-keywords 'words))
(defconst remind-builtin-variables-regex (regexp-opt remind-builtin-variables 'words))
(defconst remind-builtin-functions-regex (regexp-opt remind-builtin-functions 'words))
(defconst remind-time-words-regex (regexp-opt remind-time-words 'words))
;; Case-insensitive matching functions
(defun remind-keywords-matcher (limit)
(let ((case-fold-search t))
(re-search-forward remind-keywords-regex limit 'no-error)))
(defun remind-type-keywords-matcher (limit)
(let ((case-fold-search t))
(re-search-forward remind-type-keywords-regex limit 'no-error)))
(defun remind-builtin-variables-matcher (limit)
(let ((case-fold-search t))
(re-search-forward remind-builtin-variables-regex limit 'no-error)))
(defun remind-builtin-functions-matcher (limit)
(let ((case-fold-search t))
(re-search-forward remind-builtin-functions-regex limit 'no-error)))
(defun remind-time-words-matcher (limit)
(let ((case-fold-search t))
(re-search-forward remind-time-words-regex limit 'no-error)))
;; keywords
(defconst remind-conf-font-lock-keywords-1
(list
'("^[\;\#]\\s-+.*$" . remind-comment-face)
(cons (regexp-opt remind-keywords 'words) remind-conf-keyword-face)
'(remind-keywords-matcher . remind-conf-keyword-face)
'("%[\"_]" . font-lock-warning-face)
'("\\(%[a-mops-w]\\)" . remind-conf-substitutes-face)
'("\"[^\"]*\"" . remind-string-face))
@@ -258,15 +301,15 @@
(defconst remind-conf-font-lock-keywords-2
(append remind-conf-font-lock-keywords-1
(list
(cons (regexp-opt remind-time-words 'words) remind-time-face)
(cons (regexp-opt remind-builtin-functions 'words) remind-conf-command-face)
'(remind-time-words-matcher . remind-time-face)
'(remind-builtin-functions-matcher . remind-conf-command-face)
'("%$" . remind-conf-endline-face)))
"Additional commands to highlight in `remind-conf-mode'.")
(defconst remind-conf-font-lock-keywords-3
(append remind-conf-font-lock-keywords-2
(list
(cons (regexp-opt remind-type-keywords 'words) remind-conf-type-face)
'(remind-type-keywords-matcher . remind-conf-type-face)
'("\[[a-zA-Z]\\{3,6\\}\]" . remind-conf-color-face)
'("\\s-+\\([12][0-9]\\|3[01]\\|0?[0-9]\\)\\s-+" . remind-conf-substitutes-face);better date regexp
'("\\s-+\\([12][09][0-9][0-9][-/]\\(0[1-9]\\|1[0-2]\\)[-/]\\([12][0-9]\\|0[1-9]\\|3[01]\\)\\)\\s-+" . remind-time-face) ;; pseudo ISO 8601 date format.
@@ -274,7 +317,7 @@
'("\\s-+\\(\\(?:20\\|19\\)[0-9][0-9]\\)\\s-+" . remind-conf-substitutes-face);years
'("\\s-+\\(2[0-4]\\|[01]?[0-9][.:][0-5][0-9]\\)\\s-+" . remind-conf-substitutes-face);24hour clock, more precise
'("\\s-+\\([+-][+-]?[1-9][0-9]*\\)\\s-+" 1 remind-conf-delta-face prepend)
(cons (regexp-opt remind-builtin-variables 'words) remind-conf-variable-face)))
'(remind-builtin-variables-matcher . remind-conf-variable-face)))
"The ultimate in highlighting experiences for `remind-conf-mode'.")
;;YYYY-MM-DD@hh:mm, YYYY-MM-DD@hh.mm, YYYY/MM/DD@hh:mm and YYYY/MM/DD@hh.mm
@@ -462,12 +505,11 @@ Acts on the region or places point where it needs to be."
;; finally the derived mode.
;;;###autoload
(define-derived-mode remind-conf-mode text-mode "REM"
(define-derived-mode remind-conf-mode text-mode "Remind Conf Mode"
"Major mode for editing remind calendar configuration files.
\\{remind-conf-mode-map}"
:syntax-table remind-conf-syntax-table
(set (make-local-variable 'font-lock-keywords-case-fold-search) t) ;this is not working atm 2009-04-13
(set (make-local-variable 'font-lock-defaults) '(remind-conf-font-lock-keywords))
(set (make-local-variable 'comment-start) ";")
(set (make-local-variable 'comment-start) "#")

View File

@@ -1,6 +1,338 @@
CHANGES TO REMIND
* VERSION 3.4 Patch 0 - 2022-??-??
* VERSION 4.2 Patch 1 - 2022-12-15
- MINOR IMPROVEMENT: TkRemind: If "Extra Remind Options" contains -m, make
TkRemind start the calendar with Monday instead of Sunday.
- MINOR IMPROVEMENT: Sample files: Add French holidays courtesy of
Clément Bœsch.
- MINOR IMPROVEMENT: A few performance fixes, likely not even noticeable in
most cases.
- MINOR FIXES: Fix misleading comments in the source code.
- MINOR FIX: Remove a bunch of dead code in the moon-phase routines.
- MINOR FIX: Remove unnecessary %"...%" markers in holidays/us.rem
- MINOR FIX: Don't use the -ffat-lto-objects if we're compiling with Clang.
- MINOR FIX: Remind: Fix a broken printf-format string (need to double up on %
to get a literal % in the output.)
- BUG FIX: Make test suite pass regardless of the date on which it is run.
D'oh!!!
- BUG FIX: Make sure the banner gets printed each time through a "*N"
command-line option loop.
* VERSION 4.2 Patch 0 - 2022-10-14
- NEW FEATURE: remind: Allow weekdays to be globally-omitted. For example:
OMIT Saturday Sunday
globally-omits all Saturdays and Sundays.
- NEW FEATURE: remind: Add ansicolor() built-in function to make it easier
to colorize reminders on the terminal. Suggested by Tim Chase.
- NEW FEATURE: remind: Add several special variables related to the color
mode: $UseVTColors, $UseBGVTColors, $Use256Colors, $UseTrueColors and
$TerminalBackground. Based on a suggestion by Tim Chase.
- NEW FEATURE: remind: Add utctolocal() and localtoutc() built-in functions.
- NEW FEATURE: remind: Add timezone() built-in function.
- NEW FEATURE: remind: Add trigtags() function per suggestion from Tim Chase.
- NEW FEATURE: remind: The $AddBlankLines system variable controls whether or
not a blank line is added after each reminder.
- NEW FEATURE: remind: The built-in functions columns() and rows() return the
width and height of the terminal (in character positions) respectively.
- NEW FEATURE: remind: The built-in function columns("string") returns the
number of columns occupied by "string" on the terminal, taking into account
double-width Unicode characters and zero-width ANSI escape sequences.
- NEW FEATURE: remind: You can add custom substitution sequences of the form
%{name} or %*{name} that end up calling the function subst_name and using
its return value as the replacement for the substitution sequence.
- NEW FEATURE: remind: Add the FUNSET command to undefine a user-defined
function.
- NEW FILES: Add standard include files holidays/jewish.rem and
ansitext.rem (the latter defines standard ANSI escape codes for
changing text attributes such as bold, underline, etc.)
- NEW EXAMPLES: add examples/alignmemt.rem, examples/ansitext and
examples/astro
- BUG FIX: remind: Make MSF correctly format UTF-8 text and text with
embedded ANSI color-changing codes.
- BUG FIX: remind: Make ADDOMIT actually work correctly in a SATISFY-type
REM command. Bug found by Gunther Reißig
- BUG FIX: Convert documentation files and src/lang.h to UTF-8. Patch
from Jochen Sprickerhof.
- BUG FIX: Fix tests in non-UTF-8 locales.
- BUG FIX: Fix a few problems with the include/holidays/us.rem file.
- BUG FIX: remind: Fix an ancient logic error in DBufPutc that hurt
performance.
- MINOR IMPROVEMENT: Clean up code and remove some dead code.
* VERSION 4.1 Patch 0 - 2022-09-25
- NEW FEATURE: remind: "remind -c" now supports the MOON special, printing
the moon phases in the calendar if the locale supports UTF-8 encoding.
- NEW FEATURE: remind: "remind -c" now supports the SHADE special. Works
best with the 256-color extended XTerm palette or 24-bit true-color
terminal escape sequences.
- NEW FEATURE: remind: "remind -c" now supports the WEEK special.
- NEW FEATURE: remind: The new "stdout()" function returns a string describing
where stdout is going. Examples of return values are "TTY" if remind's
output is going to terminal, "FILE" if it's redirected to a plain file,
or "PIPE" if it's going to a pipe. See the man page for all the details.
- NEW FEATURE: Add the "-wt" option to set the calendar width to the terminal
width even if standard output is a pipe. Useful for situations like this:
remind -wt -c .reminders | less -R
- CHANGE: "make install" now no longer strips debugging symbols from the
remind and rem2ps executables. Use "make install-stripped" if you want
them stripped.
- CHANGE: remind: "remind -c" highlights today's date in bold, if
colors are enabled.
- CHANGE: Dump string values with control characters escaped.
- DOCUMENTATION FIX: Document behavior of DO and filedir() with respect
to symbolic links.
- DOCUMENTATION FIX: Add home page link to man pages. Suggested by Ian! D.
Allen.
- DOCUMENTATION FIX: Make date in man pages actually be the release date.
Include Remind version in man pages. Also suggested by Ian! D. Allen.
- DOCUMENTATION FIX: Fix inaccuracy in how string constants were documented.
- BUG FIX: Makefiles: Pass CFLAGS at link-time so link-time optimization
actually happens. Pointed out by Zoltan Puskas.
- BUG FIX: If the first REM command to trigger was a RUN command, the banner
would not print. This has been fixed.
- BUG FIX: replace deprecated 'fgrep' with 'grep -F' (Jochen Sprickerhof)
- BUG FIX: make "make test" depend on "make all" (Jochen Sprickerhof)
- BUG FIX: make "REM ... SATISFY ... MSG foo" respect $DefaultColor. Bug
reported by Gunther Reißig.
- BUG FIX: Don't consider IFTRIG true if we could not compute a trigger date.
Bug noted by Gunther Reißig.
* VERSION 4.0 Patch 3 - 2022-08-16
- IMPROVEMENT: remind: add plain_body and calendar_body JSON keys in -pp...
output.
- BUG FIX: tkremind: Don't create empty files called '&1' when creating
a new reminder.
- BUG FIX: remind: Don't call signal-unsafe functions from signal handler
* VERSION 4.0 Patch 2 - 2022-08-02
- IMPROVEMENT: remind: Allow more forms of OMIT as per Ian! D. Allen's request:
OMIT Month [THROUGH Month]
OMIT Day Month [THROUGH Day Month]
OMIT Day Month Year [THROUGH Day Month Year]
- BUG FIX: Make $T behave as documented, exactly like trigdate(). $T would
return '1989-12-31' rather than 0 if the trigger date was not valid.
- BUG FIX: TkRemind: Fix resizing bug for a calendar with 6 rows.
- DOCUMENTATION IMPROVEMENT: Improve TkRemind documentation; document use
of inotifywait if available.
* VERSION 4.0 Patch 1 - 2022-06-03
- IMPROVEMENT: Add $SuppressLRM system variable to suppress the UTF-8
Left-to-Right mark in "remind -c" output.
- DOCUMENTATION FIX: Document the "q" sub-option to the "-p" option.
* VERSION 4.0 Patch 0 - 2022-04-04
- MAJOR NEW FEATURE: remind: Remind output can effectively be
translated into other languages at run-time. A number of system
variables let you translate English words to another language, and a
mechanism for altering the substitution filter at run-time lets you
translate its output so the results are idiomatic. See the man page
sections "RUN-TIME SUPPORT FOR OTHER LANGUAGES", "RUN-TIME
MODIFICATION OF THE SUBSTITUTION FILTER" and "LANGUAGE PACKS".
- NEW FEATURE: remind: Add the pad() built-in function
- NEW FEATURE: tkremind: Day numbers can be displayed left-aligned,
centered or right-aligned.
- IMPROVEMENT: contrib/remind-conf-mode: The Emacs syntax-highlighter
has been updated with the latest system variables and functions
and has been made case-insensitive.
- IMPROVEMENT: remind, rem2ps: Use link-time optimization with gcc if
possible.
- IMPROVEMENT: remind: Print better diagnostics when errors occur inside
a user-defined function. We now show the stack trace to make it easier
to figure out where the error actually is.
- CHANGE: Add a "q" sub-option to the "-p", "-pp", and "-ppp" options.
This causes Remind *not* to remove the %"...%" marker sequence from
remind bodies.
- BUG FIX: rem2pdf: Make rem2pdf respect the --prefix ./configure flag.
Loosely based on patch by Jonathan Kamens.
- BUG FIX: tkremind: Fix the "-m" flag, which was broken in 03.04.00.
- BUG FIX: Fix the overflow-detection functions so they work with link-time
optimization. The previous versions would be optimized away.
- BUG FIX: Warn if the arguments to the "-@" option are out of range.
Problem noted by Ian! D. Allen.
- BUG FIX: Always interpret $Latitude and $Longitude input values in the
"C" locale. (We do accept localized input, but warn.)
- BUG FIX: Fix many spelling mistakes caught by Jens Schleusener
* VERSION 3.4 Patch 2 - 2022-03-14
- NEW FEATURE: remind: Add syntactic sugar to simplify some common
types of reminders. See "SYNTACTIC SUGAR FOR REM" in the remind
man page. Based on suggestions from Ian! D. Allen.
- CHANGE: examples/defs.rem: The examples file has been updated to use
the newer syntactic sugar.
- CHANGE: remind: Always parse the body of REM statements to catch
expression errors. In the past, something like:
REM 2025-01-02 MSG [1/0]
would not cause a division-by-zero error except on 2025-01-02. Now,
the error is always caught. NOTE POTENTIAL INCOMPATIBILITY: There may
be edge-cases when formerly-valid remind scripts now trigger errors.
However, this is pretty unlikely.
- NEW FEATURE: remind: Add the "trig" function to allow more
expressiveness when creating triggers. See man page for details.
- IMPROVEMENT: tkremind: Tweak the calendar display; improve ability to
customize colors, including supplying two built-in themes. Based on
patch and suggestion from Paulo (last name unknown).
- IMPROVEMENT: tkremind: TkRemind handles errors in reminders scripts
much more unobtrusively. Instead of popping up a modal dialog box
with almost-unreadable error output, it discreetly notifies you of
errors with a button that lets you view the specific error messages
in a more readable format.
- IMPROVEMENT: examples/remind.vim: Update list of keywords in vim syntax
highlighting file.
- IMPROVEMENT: contrib/remind-conf-mode: Update the list of keywords,
functions and variables in the Emacs syntax-highlighting file. Also make
it match them case-insensitively.
- CHANGE: remind: Increase $MaxSatIter default to 1000 instead of 150.
Computers are much faster than when I first wrote remind and they
can handle this higher limit easily. The higher limit also enables
certain reasonable reminders that failed in the past because of the
low SATISFY iteration limit.
- CHANGE: remind: The "||" operator now returns the value of the first
non-zero operand rather than just returning 1 or 0. Similarly, "&&"
returns 0 if either operand is false or the value of the last
operand if both operands are true.
NOTE POTENTIAL INCOMPATIBILITY: Remind scripts that depend on ||
and && always returning exactly one of 1 or 0 may need
adjustment.
- CHANGE: The || and && operators can accept any non-STRING type as long
as both operands have the same type. The "false" values are defined
as follows; true values are any other value:
INT: 0
TIME: 00:00
DATE: '1990-01-01' (the Remind epoch)
DATETIME: '1990-01-01@00:00' (the Remind epoch)
- IMPROVEMENT: remind: Issue diagnostics if an UNTIL or THROUGH date
is earlier than any possible trigger date, as well as an UNTIL date
with a fully-specified date and no repeat ("*N"). Suggestion from
Ian! D. Allen.
- BUG FIX: tkremind: If the same moon phase appeared twice in a month,
TkRemind would not display the first occurrence correctly. This has
been fixed.
- BUG FIX: rem2pdf: Fix typos in the man page.
- BUG FIX: remind: The IF command documentation didn't reflect how it
actually worked; now it does.
- BUG FIX: remind: Use correct UNTIL/THROUGH keyword in error message.
- BUG FIX: rem2pdf: Correct the calculation that warns about an over-full
calendar box. Problem noted by Jonathan Kamens.
- BUG FIX: remind: The "remind -c" output would sometimes be incorrect if
scripts with double-wide characters were used. This has been fixed.
- BUG FIX: remind: The "remind -c" output would sometimes be incorrect
if right-to-left scripts were used in reminders. This has been fixed.
* VERSION 3.4 Patch 1 - 2022-02-23
- MINOR IMPROVEMENT: Support the INSTALL_BASE environment variable for
installing rem2pdf in a non-standard location like your home directory.
This is passed in to rem2pdf's Makefile at build and install time.
- MINOR IMPROVEMENT: ./configure: Add --disable-perl-build-artifacts flag
to avoid installation of perllocal.pod and .packlist files.
- BUG FIX: tkremind: If the system date rolls over, update the display
to correctly highlight the current date. This worked in older versions
of Remind, but was broken by 03.04.00.
- BUG FIX: rem2pdf: The small calendar font would sometimes be scaled
incorrectly so the small calendar overflowed the box. This has been
fixed.
* VERSION 3.4 Patch 0 - 2022-02-10
- MAJOR CHANGE: Remind and its helpers (except for rem2ps) fully support
UTF-8. If your system locale is a UTF-8 locale and your terminal
@@ -42,6 +374,9 @@ CHANGES TO REMIND
- CLEANUP: remind: C source code: Remove various unused or obsolete macros.
- BUG FIXES: Minor fixups to groff source and Makefiles courtesy of
Jochen Sprickerhof.
- BUG FIX: Properly support formatting of double-wide characters in the
terminal mode "remind -c" calendar.
@@ -880,7 +1215,7 @@ CHANGES TO REMIND
- Fixed dates for Yom Hazikaron and Yom Ha'atzmaut if 5 Iyar falls on a
Saturday. (Hebrew calendar fix.)
- Added support for the Icelandic language, courtesy of Björn Davíðsson.
- Added support for the Icelandic language, courtesy of Björn Davíðsson.
+ BUG FIXES
@@ -1027,7 +1362,7 @@ CHANGES TO REMIND
- Made parser _very_ forgiving -- the type of reminder now defaults
to MSG. This lets you have lines in the reminder file like this:
Feb 9, 1998 Meeting with Joe.
Feb 9, 1998 Meeting with Joe.
But I don't recommend abusing it. It's mostly to ease migration from
UNIX calendar(1) files.
@@ -1618,7 +1953,7 @@ CHANGES TO REMIND
- Removed identifiers in the C source beginning with "_" to conform
to ANSI practice.
- Fixed a bug in the -u option which resulted in environment variables
SHELL and USER not being set correctly. Also made -u set the LOGNAME
environment variable.
@@ -1691,7 +2026,7 @@ CHANGES TO REMIND
- Fixed all the source files to include "config.h" first.
- Changed the way triggers are calculated so that trigger dates are
- Changed the way triggers are calculated so that trigger dates are
always valid if year, month and day are specified, and there is no
UNTIL clause. See MAN page section "DETAILS ABOUT TRIGVALID()."
@@ -1833,6 +2168,3 @@ CHANGES TO REMIND
* Version 1.0
- never publicly released.

18
examples/alignment.rem Normal file
View File

@@ -0,0 +1,18 @@
# Demo the columns() function
#
# Run as: remind -@2 alignment.rem
SET $AddBlankLines 0
BANNER %
FSET center(x) pad("", " ", (columns() - columns(x))/2) + x
FSET right(x) pad("", " ", columns() - columns(x)) + x
MSG This is left-aligned.
MSG [ansicolor(0,255,0)]This is also left-aligned.[ansicolor("")]
MSG [center("This is centered.")]
MSG [ansicolor(255,255,0) + center("🌕 🌕 🌕 🌕 This is also centered. ") + ansicolor("")]
msg [right("This is right-aligned.")]
msg [ansicolor(255,0,0) + right("This is also right-aligned. 🌕 🌕 🌕") + ansicolor("")]

35
examples/ansitext Executable file
View File

@@ -0,0 +1,35 @@
#!/bin/sh
#
# A little demo script that displays ANSI text attributes
# Not all attributes work on all terminals... your mileage may vary.
remind -@2 - <<'EOF'
SET $AddBlankLines 0
BANNER %
INCLUDE [$SysInclude]/ansitext.rem
MSG This file shows off some ANSI text attributes and colors.
MSG Not all attributes work on all terminals.%_
MSG This is [ansi_bold]bold.[ansi_normal]
MSG This is [ansi_faint]faint.[ansi_normal]
MSG This is [ansi_italic]italic.[ansi_normal]
MSG This is [ansi_underline]underline.[ansi_normal]
MSG This is [ansi_underline2]underline2.[ansi_normal]%_
MSG This is [ansi_reverse]reverse.[ansi_normal]%_
MSG This is [ansi_strikeout]strikeout.[ansi_normal]%_
MSG This is [ansi_overline]overline.[ansi_normal]%_
MSG This is [ansicolor(255,0,0)]red.[ansicolor("")]
MSG This is [ansicolor(0,255,0)]green.[ansicolor("")]
MSG This is [ansicolor(0,0,255)]blue.[ansicolor("")]
MSG This is [ansicolor(255,255,0)]yellow.[ansicolor("")]
MSG This is [ansicolor(255,0,255)]magenta.[ansicolor("")]
MSG This is [ansicolor(0,255,255)]cyan.[ansicolor("")]%_
# You can combine attributes
MSG This is [ansicolor(0,255,0)][ansicolor(0,0,96,1)][ansi_italic][ansi_bold]Green-Bold-Italic-on-Blue[ansi_normal][ansicolor("")]
EOF
exit 0

36
examples/astro Executable file
View File

@@ -0,0 +1,36 @@
#!/bin/sh
#
# A little demo script that displays astronomical events
#
# Best used in a UTF-8 environment.
remind -g -@2 - <<'EOF'
# Set this variable to 1 if your terminal has a dark background or 0 if
# it is light.
SET bg_dark 1
SET $AddBlankLines 0
BANNER %
MSG Today is [today()].%_
IF bg_dark
SPECIAL COLOR 255 255 0 Sunrise: 🌅 [sunrise()] today and [sunrise(today()+1)] tomorrow
SPECIAL COLOR 255 128 0 Sunset: 🌇 [sunset()] today and [sunset(today()+1)] tomorrow%_
REM [moondate(0)] +60 SPECIAL COLOR 255 255 0 New moon: 🌑 [moondate(0)] (%b)
REM [moondate(1)] +60 SPECIAL COLOR 255 255 128 First Quarter: 🌓 [moondate(1)] (%b)
REM [moondate(2)] +60 SPECIAL COLOR 255 255 255 Full moon: 🌕 [moondate(2)] (%b)
REM [moondate(3)] +60 SPECIAL COLOR 255 255 128 Last Quarter: 🌗 [moondate(3)] (%b)
ELSE
SPECIAL COLOR 128 128 0 Sunrise: 🌅 [sunrise()] today and [sunrise(today()+1)] tomorrow
SPECIAL COLOR 128 32 0 Sunset: 🌇 [sunset()] today and [sunset(today()+1)] tomorrow%_
REM [moondate(0)] +60 SPECIAL COLOR 128 128 0 New moon: 🌑 [moondate(0)] (%b)
REM [moondate(1)] +60 SPECIAL COLOR 128 128 64 First Quarter: 🌓 [moondate(1)] (%b)
REM [moondate(2)] +60 SPECIAL COLOR 0 0 0 Full moon: 🌕 [moondate(2)] (%b)
REM [moondate(3)] +60 SPECIAL COLOR 128 128 64 Last Quarter: 🌗 [moondate(3)] (%b)
ENDIF
EOF

View File

@@ -16,7 +16,7 @@
# "#PSSTUFF" for nifty PostScript examples #
# #
# This file is part of REMIND. #
# Copyright (C) 1992-2018 Dianne Skoll #
# Copyright (C) 1992-2022 Dianne Skoll #
# #
#############################################################################
@@ -25,67 +25,18 @@ RUN OFF
################################################
# Ensure required version of remind is used... #
################################################
IF version() < "03.01.10"
IF version() < "03.04.02"
ERRMSG This file requires at least version 03.01.10 of Remind.%
ERRMSG This version is version [version()].
EXIT
ENDIF
######################################
# Symbolic constants for weekdays... #
######################################
SET Sunday 0
SET Monday 1
SET Tuesday 2
SET Wednesday 3
SET Thursday 4
SET Friday 5
SET Saturday 6
SET Sun 0
SET Mon 1
SET Tue 2
SET Wed 3
SET Thu 4
SET Fri 5
SET Sat 6
#########################################
# Symbolic constants for month names... #
#########################################
SET Jan 1
SET Feb 2
SET Mar 3
SET Apr 4
SET May 5
SET Jun 6
SET Jul 7
SET Aug 8
SET Sep 9
SET Oct 10
SET Nov 11
SET Dec 12
SET January 1
SET February 2
SET March 3
SET April 4
SET May 5
SET June 6
SET July 7
SET August 8
SET September 9
SET October 10
SET November 11
SET December 12
###########################################################
# Other symbolic constants and functions for "pasting"... #
# Symbolic constants and functions for "pasting"... #
###########################################################
SET Quote CHAR(34)
# Handy constants/function for specifing week of month...
# Handy constants/function for specifying week of month...
SET Week_1 1
SET Week_2 8
SET Week_3 15
@@ -119,50 +70,23 @@ REM 1 MSG John's [_mo_num(11, 1984)] 'monthly' anniversary
# Here's a tricky problem: The 4th of July is a holiday in the U.S.
# However, if it falls on a Saturday, the previous Friday is a holiday.
# If it falls on a Sunday, the next Monday is a holiday. Here's how
# to do it. NOTE that the following procedure makes the OMIT context
# dependent upon the current date. SInce it only depends on the current
# year, which is not likely to change while producing a calendar, we
# are fairly safe. However, reminders with huge DELTA or BACK components
# may not operate as expected. In general, any time you make OMIT
# dependent upon the current date, it's tricky and results may not be
# what you expect. You should try to make sure that the OMIT context
# "near" any current reminders will not change during a calendar run.
# The SCANFROM clause will make these OMITs safe.
# to do it.
#
# For those reminders that update the OMIT context with ADDOMIT, we use
# SCANFROM -7 for safety; see the man page about moveable OMITs.
############################################################################
# Calculate the weekday of the holiday.
REM 4 July SCANFROM -7 SATISFY 1
# If it falls on a Saturday, bump to previous Friday
REM 3 JULY SCANFROM -7 ADDOMIT SATISFY [$Tw == 5] MSG Independence day (observed)
SET iday $T
IF WKDAYNUM(iday) == Sat
REM [iday] MSG Independence day (actual)
OMIT [iday-1] MSG Independence day (observed)
ELSE
IF WKDAYNUM(iday) == Sun
REM [iday] MSG Independence day (actual)
OMIT [iday+1] MSG Independence day (observed)
ELSE
OMIT [iday] MSG Independence day
ENDIF
ENDIF
# If it falls on a Sunday, bump to following Monday
REM 5 July SCANFROM -7 ADDOMIT SATISFY [$Tw == 1] MSG Independence day (observed)
############################################################################
# A meeting on the first Monday of every month which is moved to the #
# second Monday in the event of a holiday. #
############################################################################
# If it falls on Sat or Sun, note the actual day
REM 4 July SCANFROM -7 ADDOMIT SATISFY [$Tw == 0 || $Tw == 6] MSG Independence day (actual)
# First, the normal meeting. However, the SKIP keyword means this
# one won't be triggered if the first Monday is a holiday
REM Mon 1 SKIP MSG Meeting
# Now, calculate the "potential" delayed meeting
REM Mon 8 SATISFY 1
# But only actually trigger the delayed meeting if the previous
# Monday was a holiday
IF ISOMITTED($T-7)
REM [$T] MSG Delayed meeting
ENDIF
# Otherwise observed and actual is on the 4th
REM 4 July SCANFROM -7 ADDOMIT SATISFY [$Tw >= 1 && $Tw <= 5] MSG Independence Day
##########################################################################
# #
@@ -216,38 +140,38 @@ REM [easter+49] MSG %"Pentecost%"
# which ones are omitted - use the general forms shown below. You'll
# need the Week_n variables defined way up in the file.
OMIT Jan 1 MSG %"New Year's%" Day
REM Mon Jan [Week_3] MSG Martin Luther King - %"MLK Day%"
OMIT Jan 1 MSG %"New Year's Day%"
REM Third Monday in Jan MSG Martin Luther King - %"MLK Day%"
REM Feb 2 MSG %"Ground Hog Day%"
REM Feb 14 MSG %"Valentine's%" Day
REM Mon Feb [Week_3] SCANFROM -7 ADDOMIT MSG %"President's Day%"
REM Mar 17 MSG %"St. Patrick's%" Day
REM Feb 14 MSG %"Valentine's Day%"
REM Third Monday in Feb SCANFROM -7 ADDOMIT MSG %"President's Day%"
REM Mar 17 MSG %"St. Patrick's Day%"
# The DST rules are accurate for most locations in
# North America
REM Sun Apr 1 ++2 UNTIL 1 Jan 2007 MSG Daylight Saving Time - %"DST starts%" %b
REM Sun Mar 8 ++2 FROM 1 Jan 2007 MSG Daylight Saving Time - %"DST starts%" %b
REM Sun [_last(Oct)] ++2 UNTIL 1 Jan 2007 MSG Daylight Saving Time - %"DST ends%" %b
REM Sun 1 Nov ++2 FROM 1 Jan 2007 MSG Daylight Saving Time - %"DST ends%" %b
REM Last Sunday in October ++2 UNTIL 1 Jan 2007 MSG Daylight Saving Time - %"DST ends%" %b
REM First Sunday in November ++2 FROM 1 Jan 2007 MSG Daylight Saving Time - %"DST ends%" %b
REM Apr 1 MSG %"April Fool's%" Day
REM Mon Tue Wed Thu Fri Sat 15 Apr MSG %"Income tax%" due
REM May 5 MSG %"Cinco de Mayo%"
REM Sat May [Week_1] MSG %"Kentucky Derby%"
REM Sun May [Week_2] MSG %"Mother's Day%"
REM Sat May [Week_3] MSG %"Armed Forces Day%"
REM Mon [_last(May)] SCANFROM -7 ADDOMIT MSG %"Memorial Day%"
REM First Sat in May MSG %"Kentucky Derby%"
REM Second Sun in May MSG %"Mother's Day%"
REM Third Sat in May MSG %"Armed Forces Day%"
REM Last Monday in May SCANFROM -7 ADDOMIT MSG %"Memorial Day%"
REM Jun 14 MSG %"Flag Day%"
REM Sun Jun [Week_3] MSG %"Father's Day%"
REM Mon Sep [Week_1] SCANFROM -7 ADDOMIT MSG %"Labor Day%"
REM Mon Oct [Week_2] MSG %"Columbus Day%"
REM Third Sun in June MSG %"Father's Day%"
REM First Mon in Sep SCANFROM -7 ADDOMIT MSG %"Labor Day%"
REM Second Mon in Oct MSG %"Columbus Day%"
REM Nov 11 MSG %"Veterans Day%"
REM Oct 30 MSG %"Mischief Night%"
REM Oct 31 MSG %"Halloween%"
REM Tue Nov 2 SCANFROM -7 SATISFY [($Ty % 4) == 0] MSG %"Election Day%"
REM Thu Nov [Week_4] SCANFROM -7 ADDOMIT MSG %"Thanksgiving Day%"
REM Last Thu in Nov SCANFROM -7 ADDOMIT MSG %"Thanksgiving Day%"
REM Fri Nov [Week_4+1] SCANFROM -7 ADDOMIT MSG %"Thanksgiving (cont.)%"
OMIT Dec 24 MSG %"Christmas Eve%"
OMIT Dec 25 MSG %"Christmas%" Day
@@ -262,6 +186,24 @@ if $NumTrig > SaveTrig
REM SPECIAL SHADE 220
endif
############################################################################
# A meeting on the first Monday of every month which is moved to the #
# second Monday in the event of a holiday. #
############################################################################
# First, the normal meeting. However, the SKIP keyword means this
# one won't be triggered if the first Monday is a holiday
REM First Monday SKIP MSG Meeting
# Now, calculate the "potential" delayed meeting
REM Second Monday SATISFY 1
# But only actually trigger the delayed meeting if the previous
# Monday was a holiday
IF ISOMITTED($T-7)
REM [$T] MSG Delayed meeting
ENDIF
#PSSTUFF2
##########################################################################
# #
@@ -278,10 +220,10 @@ REM PS Border Border moveto \
([hebday($U)] [hebmon($U)]) show
# Fill in the phases of the moon on the PostScript calendar
[moondate(0)] SPECIAL MOON 0
[moondate(1)] SPECIAL MOON 1
[moondate(2)] SPECIAL MOON 2
[moondate(3)] SPECIAL MOON 3
REM [moondate(0)] SPECIAL MOON 0
REM [moondate(1)] SPECIAL MOON 1
REM [moondate(2)] SPECIAL MOON 2
REM [moondate(3)] SPECIAL MOON 3
# The following example puts sunrise and sunset times in PostScript in the
# calendar - the sizes are hard-coded, however, and work best in landscape.

View File

@@ -1,9 +1,9 @@
" Vim syntax file
" Language: Remind
" Maintainer: Davide Alberani <alberanid@libero.it>
" Last Change: 18 Sep 2009
" Version: 0.5
" URL: http://erlug.linux.it/~da/vim/syntax/remind.vim
" Maintainer: Davide Alberani <da@erlug.linux.it>
" Last Change: 02 Nov 2015 + 13 Mar 2022 by Dianne Skoll <dianne@skoll.ca>
" Version: 0.7+dianne1
" URL: http://ismito.it/vim/syntax/remind.vim
"
" remind is a sophisticated reminder service
" you can download remind from:
@@ -23,7 +23,7 @@ syn keyword remindExpiry UNTIL FROM SCANFROM SCAN WARN SCHED THROUGH
syn keyword remindTag PRIORITY TAG
syn keyword remindTimed AT DURATION
syn keyword remindMove ONCE SKIP BEFORE AFTER
syn keyword remindSpecial INCLUDE INC BANNER PUSH-OMIT-CONTEXT PUSH CLEAR-OMIT-CONTEXT CLEAR POP-OMIT-CONTEXT POP COLOR COLOUR
syn keyword remindSpecial INCLUDE INC BANNER PUSH-OMIT-CONTEXT PUSH CLEAR-OMIT-CONTEXT CLEAR POP-OMIT-CONTEXT POP COLOR COLOUR DO
syn keyword remindRun MSG MSF RUN CAL SATISFY SPECIAL PS PSFILE SHADE MOON
syn keyword remindConditional IF ELSE ENDIF IFTRIG
syn keyword remindDebug DEBUG DUMPVARS DUMP ERRMSG FLUSH PRESERVE

34
include/ansitext.rem Normal file
View File

@@ -0,0 +1,34 @@
# Global variables for various ANSI escape-code sequences
# Not all sequences are supported by all terminals.
# This file is part of REMIND
# REMIND is Copyright (C) 1992-2022 by Dianne Skoll
if !defined("ansi_bold")
# Disable ANSI attributes in calandar mode
if $CalMode
set ansi_normal ""
set ansi_bold ""
set ansi_faint ""
set ansi_italic ""
set ansi_underline ""
set ansi_reverse ""
set ansi_strikeout ""
set ansi_underline2 ""
set ansi_overline ""
else
set ansi_normal char(27) + "[0m"
set ansi_bold char(27) + "[1m"
set ansi_faint char(27) + "[2m"
set ansi_italic char(27) + "[3m"
set ansi_underline char(27) + "[4m"
set ansi_reverse char(27) + "[7m"
set ansi_strikeout char(27) + "[9m"
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
endif
# Example: REM MSG I must [ansi_bold]emphasize[ansi_normal] \
# the [ansi_italic]severity[ansi_normal] of the situation!

29
include/holidays/ca.rem Normal file
View File

@@ -0,0 +1,29 @@
# Canadian holidays
OMIT 1 Jan MSG New Year's Day
# This varies by province
REM Third Monday in Feb SCANFROM -7 ADDOMIT MSG Family Day
# This varies by province
OMIT [easterdate($Uy) - 2] MSG Good Friday
# This varies by province
OMIT [easterdate($Uy) + 1] MSG Easter Monday
REM Mon 18 May SCANFROM -7 ADDOMIT MSG Victoria Day
OMIT 1 July MSG Canada Day
# This varies by province
REM First Monday in Aug SCANFROM -7 ADDOMIT MSG Civic Holiday
REM First Monday in Sep SCANFROM -7 ADDOMIT MSG Labour Day
REM Second Monday in Oct SCANFROM -7 ADDOMIT MSG Thanksgiving Day
REM 11 November MSG Remembrance Day
OMIT 25 Dec MSG Christmas
OMIT 26 Dec MSG Boxing Day

20
include/holidays/fr.rem Normal file
View File

@@ -0,0 +1,20 @@
#
# France Holidays
#
# Source: Article L3133-1
# https://www.legifrance.gouv.fr/codes/section_lc/LEGITEXT000006072050/LEGISCTA000006178007/2016-08-10/
#
SET easter EASTERDATE($Uy)
REM Jan 1 MSG %"Jour de l'an%"
REM [easter+1] MSG %"Lundi de Pâques%"
REM May 1 MSG %"Fête du Travail%"
REM May 8 MSG %"Victoire des alliés%"
REM [easter+39] MSG %"Jeudi de l'Ascension%"
REM [easter+50] MSG %"Lundi de Pentecôte%"
REM Jul 14 MSG %"Fête nationale%"
REM Aug 15 MSG %"Assomption%"
REM Nov 1 MSG %"La Toussaint%"
REM Nov 11 MSG %"Armistice%"
REM Dec 25 MSG %"Noël%"

111
include/holidays/jewish.rem Normal file
View File

@@ -0,0 +1,111 @@
# Major Jewish Holidays
# Set the variable InIsrael to 1 if you live in Israel. Otherwise,
# you get the Diaspora versions of Jewish holidays
SET InIsrael value("InIsrael", 0)
# Set the variable Reform to 1 if you want the Reform version of the
# Jewish calendar. Otherwise, you get the traditional version
SET Reform value("Reform", 0)
# Convenient function definition to save typing
FSET _h(x, y) HEBDATE(x,y)
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)
[_h(1, "Tishrey")] ++4 MSG %"Rosh Hashana 1%" is %b.
# No RH-2 or Tzom Gedalia in Reform
IF !Reform
[_h(2, "Tishrey")] ++4 MSG %"Rosh Hashana 2%" is %b.
[_PastSat(3, "Tishrey")] ++4 MSG %"Tzom Gedalia%" is %b.
ENDIF
[_h(10, "Tishrey")] ++4 MSG %"Yom Kippur%" is %b.
[_h(15, "Tishrey")] ++4 MSG %"Sukkot 1%" is %b.
IF !InIsrael
[_h(16, "Tishrey")] MSG %"Sukkot 2%"
ENDIF
[_h(21, "Tishrey")] ++4 MSG %"Hoshana Rabba%" is %b.
[_h(22, "Tishrey")] ++4 MSG %"Shemini Atzeret%" is %b.
IF InIsrael
[_h(22, "Tishrey")] ++4 MSG %"Simchat Torah%" is %b.
ELSE
[_h(23, "Tishrey")] ++4 MSG %"Simchat Torah%" is %b.
ENDIF
# Because Kislev can change length, we must be more careful about Chanukah
FSET _chan(x) HEBDATE(24, "Kislev", $U-9)+x
[_chan(1)] ++4 MSG %"Chanukah 1%" is %b.
[_chan(2)] MSG %"Chanukah 2%"
[_chan(3)] MSG %"Chanukah 3%"
[_chan(4)] MSG %"Chanukah 4%"
[_chan(5)] MSG %"Chanukah 5%"
[_chan(6)] MSG %"Chanukah 6%"
[_chan(7)] MSG %"Chanukah 7%"
[_chan(8)] MSG %"Chanukah 8%"
# Not sure about Reform's position on the next one.
IF !Reform
# 10 Tevet will never be a Saturday, so whether or not to
# move it is moot. (Thanks to Art Werschulz.)
[_h(10, "Tevet")] MSG %"Tzom Tevet%" is %b.
ENDIF
[_h(15, "Shvat")] ++4 MSG %"Tu B'Shvat%" is %b.
[_h(14, "Adar A")] ++4 MSG %"Purim Katan%" is %b.
# If Purim is on Sunday, then Fast of Esther is 11 Adar.
IF WKDAYNUM(_h2(13, "Adar")) != 6
REM [_h2(13, "Adar")] ++4 MSG %"Fast of Esther%" is %b.
ELSE
REM [_h2(11, "Adar")] ++4 MSG %"Fast of Esther%" is %b.
ENDIF
[_h(14, "Adar")] ++4 MSG %"Purim%" is %b.
[_h(15, "Nisan")] ++4 MSG %"Pesach%" is %b.
IF !InIsrael
[_h(16, "Nisan")] MSG %"Pesach 2%"
ENDIF
[_h(21, "Nisan")] MSG %"Pesach 7%"
IF !InIsrael && !Reform
[_h(22, "Nisan")] MSG %"Pesach 8%"
ENDIF
[_h(27, "Nisan")] ++4 MSG %"Yom HaShoah%" is %b.
[_BackTwoFri(4, "Iyar")] ++4 MSG %"Yom HaZikaron%" is %b.
[_BackTwoSat(5, "Iyar")] ++4 MSG %"Yom Ha'atzmaut%" is %b.
# Not sure about Reform's position on Lag B'Omer
IF !Reform
[_h(18, "Iyar")] ++4 MSG %"Lag B'Omer%" is %b.
ENDIF
[_h(28, "Iyar")] ++4 MSG %"Yom Yerushalayim%" is %b.
[_h(6, "Sivan")] ++4 MSG %"Shavuot%" is %b.
IF !InIsrael && !Reform
[_h(7, "Sivan")] MSG %"Shavuot 2%"
ENDIF
# Fairly sure Reform Jews don't observe the next two
IF !Reform
# Tzom Tamuz and Tish'a B'Av are moved to Sunday if they normally
# fall on a Saturday
[_PastSat(17, "Tamuz")] ++4 MSG %"Tzom Tammuz%" is %b.
[_PastSat(9, "Av")] ++4 MSG %"Tish'a B'Av%" is %b.
ENDIF
# Clean up
FUNSET _h _h2 _PastSat _BackTwoFri _BackTwoSat _chan

54
include/holidays/us.rem Normal file
View File

@@ -0,0 +1,54 @@
# US holidays
# This file is part of REMIND.
# Copyright (C) 1992-2022 Dianne Skoll
REM [easterdate($Uy)-46] MSG Ash Wednesday
REM [easterdate($Uy)-7] MSG Palm Sunday
OMIT [easterdate($Uy)-2] MSG Good Friday
OMIT [easterdate($Uy)] MSG %"Easter%" Sunday
REM [easterdate($Uy)+39] MSG Ascension Day
REM [easterdate($Uy)+49] MSG Pentecost
# Some holidays are omitted, some are not. You may want to change
# which ones are omitted.
OMIT Jan 1 MSG New Year's Day
REM Third Monday in Jan MSG Martin Luther King - %"MLK Day%"
REM Feb 2 MSG Ground Hog Day
REM Feb 14 MSG Valentine's Day
REM Third Monday in Feb SCANFROM -7 ADDOMIT MSG President's Day
REM Mar 17 MSG St. Patrick's Day
# These are accurate for most places in North America
REM MAYBE-UNCOMPUTABLE Sun November SATISFY [isdst($T) != isdst($T+1)] MSG Daylight Saving Time Ends
REM MAYBE-UNCOMPUTABLE Sun March SATISFY [isdst($T) != isdst($T+1)] MSG Daylight Saving Time Starts
REM Apr 1 MSG %"April Fool's%" Day
REM Mon Tue Wed Thu Fri Sat 15 Apr MSG %"Income tax%" due
REM May 5 MSG Cinco de Mayo
REM First Sat in May MSG Kentucky Derby
REM Second Sun in May MSG Mother's Day
REM Third Sat in May MSG Armed Forces Day
REM Last Monday in May SCANFROM -7 ADDOMIT MSG Memorial Day
REM Jun 14 MSG Flag Day
REM July 4 SCANFROM -7 ADDOMIT MSG Independence Day
REM July 3 SCANFROM -7 ADDOMIT SATISFY [$Tw == 5] MSG Independence Day (observed)
REM July 5 SCANFROM -7 ADDOMIT SATISFY [$Tw == 1] MSG Independence Day (observed)
REM Third Sun in June MSG Father's Day
REM First Mon in Sep SCANFROM -7 ADDOMIT MSG Labor Day
REM Second Mon in Oct MSG Columbus Day / Indigenous Peoples' Day
REM Nov 11 MSG Veterans Day
REM Oct 30 MSG Mischief Night
REM Oct 31 MSG Halloween
REM Tue Nov 2 SCANFROM -7 SATISFY [($Ty % 4) == 0] MSG Election Day
REM Thu 22 Nov SCANFROM -7 ADDOMIT MSG Thanksgiving Day
REM Fri 23 Nov SCANFROM -7 ADDOMIT MSG Thanksgiving (cont.)
REM Dec 24 MSG Christmas Eve
OMIT Dec 25 MSG %"Christmas%" Day

19
include/lang/auto.rem Normal file
View File

@@ -0,0 +1,19 @@
SET autolang getenv("LC_ALL")
IF autolang == ""
SET autolang getenv("LANGUAGE")
ENDIF
IF autolang == ""
SET autolang getenv("LANG")
ENDIF
IF autolang != ""
IF access($SysInclude + "/lang/" + lower(substr(autolang, 1, 5)) + ".rem", "r") == 0
INCLUDE [$SysInclude]/lang/[lower(substr(autolang, 1, 5))].rem
ELSE
IF access($SysInclude + "/lang/" + lower(substr(autolang, 1, 2)) + ".rem", "r") == 0
INCLUDE [$SysInclude]/lang/[lower(substr(autolang, 1, 2))].rem
ENDIF
ENDIF
ENDIF
UNSET autolang

69
include/lang/da.rem Normal file
View File

@@ -0,0 +1,69 @@
# Support for the Danish language.
# This file is part of REMIND.
# REMIND is Copyright (C) 1992-2022 by Dianne Skoll
# This file is derived from a translation by Mogens Lynnerup.
SET $Sunday "Søndag"
SET $Monday "Mandag"
SET $Tuesday "Tirsdag"
SET $Wednesday "Onsdag"
SET $Thursday "Torsdag"
SET $Friday "Fredag"
SET $Saturday "Lørdag"
SET $January "Januar"
SET $February "Februar"
SET $March "Marts"
SET $April "April"
SET $May "Maj"
SET $June "Juni"
SET $July "Juli"
SET $August "August"
SET $September "September"
SET $October "Oktober"
SET $November "November"
SET $December "December"
SET $Today "i dag"
SET $Tomorrow "i morgen"
BANNER Påmindelse for %w, %d. %m, %y%o:
SET $Am "am"
SET $Pm "pm"
SET $Ago "siden"
SET $Fromnow "fra nu"
SET $On "på"
SET $Now "nu"
SET $At "kl."
SET $Minute "minut"
SET $Hour "time"
SET $Is "er"
SET $Was "var"
SET $And "og"
SET $Hplu "r"
SET $Mplu "ter"
FSET subst_ampm(h) iif(h<5, " om natten", h < 12, " om formiddagen", h < 18, " om eftermiddagen", " om aftenen")
FSET subst_ordinal(d) "."
FSET subst_p(alt, d, t) iif(d==today()+1, "", "e")
FSET zeropad(s, len) pad(s, "0", len)
FSET subst_a_alt(d) wkday(d) + ", den " + day(d) + ". " + mon(d) + " " + year(d)
FSET subst_ax(alt, d, t) iif(alt, subst_a_alt(d), $On + " " + subst_a_alt(d))
FSET subst_bx(a, d, t) "om " + (d-today()) + " dage"
FSET subst_ex(alt, d, t) "den " + zeropad(day(d), 2) + $DateSep + zeropad(monnum(d), 2) + $DateSep + zeropad(year(d), 4)
FSET subst_fx(alt, d, t) "den " + zeropad(monnum(d), 2) + $DateSep + zeropad(day(d), 2) + $DateSep + zeropad(year(d), 4)
FSET subst_g_alt(d) wkday(d) + ", den " + day(d) + ". " + mon(d)
FSET subst_gx(alt, d, t) iif(alt, subst_g_alt(d), $On + " " + subst_g_alt(d))
FSET subst_hx(alt, d, t) "den " + zeropad(day(d), 2) + $DateSep + zeropad(monnum(d), 2)
FSET subst_ix(alt, d, t) "den " + zeropad(monnum(d), 2) + $DateSep + zeropad(day(d), 2)
FSET subst_ux(alt, d, t) subst_ax(alt, d, t)
FSET subst_vx(alt, d, t) subst_gx(alt, d, t)

89
include/lang/de.rem Normal file
View File

@@ -0,0 +1,89 @@
# Support for the German language.
# This file is part of REMIND.
# REMIND is Copyright (C) 1992-2022 by Dianne Skoll
# This file is derived from a translation by Wolfgang Thronicke
# Day names
SET $Sunday "Sonntag"
SET $Monday "Montag"
SET $Tuesday "Dienstag"
SET $Wednesday "Mittwoch"
SET $Thursday "Donnerstag"
SET $Friday "Freitag"
SET $Saturday "Samstag"
# Month names
SET $January "Januar"
SET $February "Februar"
SET $March "März"
SET $April "April"
SET $May "Mai"
SET $June "Juni"
SET $July "Juli"
SET $August "August"
SET $September "September"
SET $October "Oktober"
SET $November "November"
SET $December "Dezember"
SET $Today "heute"
SET $Tomorrow "morgen"
# Banner
BANNER Termine für %w, den %d. %m %y%o:
SET $Am "am"
SET $Pm "pm"
SET $On "am"
SET $Hplu "n"
SET $Mplu "n"
SET $Now "jetzt"
SET $At "um"
SET $Minute "Minute"
SET $Hour "Stunde"
SET $Is "ist"
SET $Was "war"
SET $And "und"
SET $Ago "vorher"
SET $Fromnow "von heute"
FSET subst_ampm(h) iif(h<5, " nachts", h<12, " vormittags", h<=17, " nachmittags", " abends")
FSET subst_ordinal(d) "."
FSET subst_a_alt(d) wkday(d) + ", den " + day(d) + ". " + mon(d) + " " + year(d)
FSET subst_ax(alt, d, t) iif(alt, subst_a_alt(d), $On + " " + subst_a_alt(d))
FSET subst_bx(a, d, t) "in " + (d-today()) + " Tagen"
FSET subst_g_alt(d) wkday(d) + ", den " + day(d) + ". " + mon(d)
FSET subst_gx(alt, d, t) iif(alt, subst_g_alt(d), $On + " " + subst_g_alt(d))
FSET subst_ux(alt, d, t) subst_ax(alt, d, t)
FSET subst_vx(alt, d, t) subst_gx(alt, d, t)
FSET subst_p(alt, d, t) iif(d == today()+1, "", "en")
# Localization of various astronomical events
# Perihelion
SET earthseasons_Perihelion_str "Perihel"
# Vernal equinox
SET earthseasons_EquinoxMar_str "Frühlingsanfang"
# Summer solstice
SET earthseasons_SolsticeJun_str "Sommeranfang"
# Aphelion
SET earthseasons_Aphelion_str "Aphel"
# Autumnal Equinox
SET earthseasons_EquinoxSep_str "Herbstanfang"
# Winter Solstice
SET earthseasons_SolsticeDec_str "Winteranfang"
# Daylight saving time starts
SET daylightST_starts_str "Beginn Sommerzeit"
# Daylight saving time ends
SET daylightST_ends_str "Ende Sommerzeit"

4
include/lang/en.rem Normal file
View File

@@ -0,0 +1,4 @@
# Support for the English language.
# This file is part of REMIND.
# REMIND is Copyright (C) 1992-2022 by Dianne Skoll
# Nothing to do for English since it is the default.

48
include/lang/es.rem Normal file
View File

@@ -0,0 +1,48 @@
# Support for the Spanish language.
# This file is part of REMIND.
# REMIND is Copyright (C) 1992-2022 by Dianne Skoll
# This file is derived from a translation by Rafa Couto <rafacouto@biogate.com>
SET $Sunday "Domingo"
SET $Monday "Lunes"
SET $Tuesday "Martes"
SET $Wednesday "Miércoles"
SET $Thursday "Jueves"
SET $Friday "Viernes"
SET $Saturday "Sábado"
SET $January "Enero"
SET $February "Febrero"
SET $March "Marzo"
SET $April "Abril"
SET $May "Mayo"
SET $June "Junio"
SET $July "Julio"
SET $August "Agosto"
SET $September "Septiembre"
SET $October "Octubre"
SET $November "Noviembre"
SET $December "Diciembre"
SET $Today "hoy"
SET $Tomorrow "mañana"
BANNER Agenda para el %w, %d%s %m, %y%o:
SET $Am "am"
SET $Pm "pm"
SET $Ago "hace"
SET $Fromnow "desde hoy"
SET $On "el día"
SET $Now "ahora"
SET $At "a las"
SET $Minute "minuto"
SET $Hour "hora"
SET $Is "es"
SET $Was "fue"
SET $And "y"
SET $Hplu "s"
SET $Mplu "s"
FSET subst_bx(a, d, t) "dentro de " + (d-today()) + " días"

94
include/lang/fi.rem Normal file
View File

@@ -0,0 +1,94 @@
# Support for the Finnish language.
# This file is part of REMIND.
# REMIND is Copyright (C) 1992-2022 by Dianne Skoll
# This file is derived from a translation by Mikko Silvonen
SET $Sunday "sunnuntai"
SET $Monday "maanantai"
SET $Tuesday "tiistai"
SET $Wednesday "keskiviikko"
SET $Thursday "torstai"
SET $Friday "perjantai"
SET $Saturday "lauantai"
SET $January "tammikuu"
SET $February "helmikuu"
SET $March "maaliskuu"
SET $April "huhtikuu"
SET $May "toukokuu"
SET $June "kesäkuu"
SET $July "heinäkuu"
SET $August "elokuu"
SET $September "syyskuu"
SET $October "lokakuu"
SET $November "marraskuu"
SET $December "joulukuu"
SET $Today "tänään"
SET $Tomorrow "huomenna"
BANNER Viestit %wna %d. %mta %y%o:
SET $Am " ap."
SET $Pm " ip."
SET $ago "sitten"
SET $Fromnow "kuluttua"
SET $On "na"
SET $Now "nyt"
SET $At "klo"
SET $Minute "minuutti"
SET $Hour "tunti"
SET $Is "on"
SET $Was "oli"
SET $And "ja"
SET $Hplu "a"
SET $Mplu "a"
FSET zeropad(s, len) pad(s, "0", len)
FSET subst_ordinal(d) iif(d==1, ":senä", d==2, ":sena", (d%10)==2||(d%10)==3||(d%10)==6||(d%10)==8, ":ntena", ":ntenä")
FSET subst_a_alt(d, o, p) wkday(d) + o + " " + day(d) + ". " + mon(d) + p + " " + year(d)
FSET subst_ax(a, d, t) iif(a, subst_a_alt(d, "", ""), subst_a_alt(d, $On, "ta"))
FSET subst_bx(a, d, t) (d-today()) + " päivän kuluttua"
FSET subst_cx(a, d, t) iif(a, wkday(d), wkday(d) + $On)
FSET subst_ex(a, d, t) zeropad(day(d), 2) + $DateSep + zeropad(monnum(d), 2) + $DateSep + zeropad(year(d), 4)
FSET subst_fx(a, d, t) zeropad(monnum(d), 2) + $DateSep + zeropad(day(d), 2) + $DateSep + zeropad(year(d), 4)
FSET subst_g_alt(d, o, p) wkday(d) + o + " " + day(d) + ". " + mon(d) + p
FSET subst_gx(a, d, t) iif(a, subst_g_alt(d, "", ""), subst_g_alt(d, $On, "ta"))
FSET subst_hx(a, d, t) zeropad(day(d), 2) + $DateSep + zeropad(monnum(d), 2)
FSET subst_ix(a, d, t) zeropad(monnum(d), 2) + $DateSep + zeropad(day(d), 2)
FSET subst_j_alt(d, o) wkday(d) + o + " " + mon(d) + "n " + day(d) + subst_ordinal(day(d)) + " " + year(d)
FSET subst_jx(a, d, t) iif(a, subst_j_alt(d, ""), subst_j_alt(d, $On))
FSET subst_k_alt(d, o) wkday(d) + o + " " + mon(d) + "n " + day(d) + subst_ordinal(day(d))
FSET subst_kx(a, d, t) iif(a, subst_k_alt(d, ""), subst_k_alt(d, $On))
FSET subst_lx(a, d, t) zeropad(year(d), 4) + $DateSep + zeropad(monnum(d), 2) + $DateSep + zeropad(day(d), 2)
FSET subst_p(a, d, t) iif(d==today()+1, "", "ä")
FSET subst_qx(a, d, t) "n"
FSET subst_u_alt(d, o, p) wkday(d) + o + " " + day(d) + subst_ordinal(day(d)) + " " + mon(d) + p + " " + year(d)
FSET subst_ux(a, d, t) iif(a, subst_u_alt(d, "", ""), subst_u_alt(d, $On, "ta"))
FSET subst_v_alt(d, o, p) wkday(d) + o + " " + day(d) + subst_ordinal(day(d)) + " " + mon(d) + p
FSET subst_vx(a, d, t) iif(a, subst_v_alt(d, "", ""), subst_v_alt(d, $On, "ta"))
FSET subst_1(a, d, t) iif(t==now(), $Now, t<now(), subst1_past(now()-t), subst1_future(t-now()))
FSET subst1_past(mins) subst_hour_past(mins/60) + subst_min_past(mins%60) + $Ago
FSET subst1_future(mins) subst_hour_future(mins/60) + subst_min_future(mins%60) + $Fromnow
FSET subst_hour_past(h) iif(h==0, "", h + " " + $Hour + iif(h==1, " ", $Hplu + " "))
FSET subst_min_past(m) iif(m==0, "", m + " " + $Minute + iif(m==1, " ", $Mplu + " "))
FSET subst_hour_future(h) iif(h==0, "", h + " tunnin ")
FSET subst_min_future(m) iif(m==0, "", m + " minuutin ")

62
include/lang/fr.rem Normal file
View File

@@ -0,0 +1,62 @@
# Support for the French language.
# This file is part of REMIND.
# REMIND is Copyright (C) 1992-2022 by Dianne Skoll
# This file is derived from a translation by Laurent Duperval
SET $Sunday "dimanche"
SET $Monday "lundi"
SET $Tuesday "mardi"
SET $Wednesday "mercredi"
SET $Thursday "jeudi"
SET $Friday "vendredi"
SET $Saturday "samedi"
SET $January "janvier"
SET $February "février"
SET $March "mars"
SET $April "avril"
SET $May "mai"
SET $June "juin"
SET $July "juillet"
SET $August "août"
SET $September "septembre"
SET $October "octobre"
SET $November "novembre"
SET $December "décembre"
SET $Today "aujourd'hui"
SET $Tomorrow "demain"
SET $On "le"
SET $At "à"
SET $Now "maintenant"
SET $Minute "minute"
SET $Hour "heure"
SET $Is "est"
SET $Was "était"
SET $And "et"
SET $Hplu "s"
SET $Mplu "s"
SET $Ago "il y a"
SET $Fromnow "dans"
# Banner
BANNER Rappels pour %w, %d%s %m, %y%o:
# Ordinal for a day (English would be "st", "nd", "rd", "th")
FSET subst_ordinal(d) iif(d == 1, "er", "")
# "%d hours", "%d minutes", or "%d hours and %d minutes"
FSET subst_tdiff(hdiff, mdiff) iif(hdiff==0&&mdiff==0, $Now, \
hdiff==0, mdiff + plural(mdiff, " minute"), \
mdiff==0, hdiff + plural(hdiff, " heure"), \
hdiff + plural(hdiff, " heure") + " et " + mdiff + plural(mdiff, " minute"))
FSET subst_1(alt, date, time) iif(time == now(), "maintenant", \
time > now(), "dans " + subst_tdiff((time-now())/60, (time-now())%60), \
"il y a " + subst_tdiff ((now()-time)/60, (now()-time)%60))
FSET subst_bx(alt, date, time) "dans " + (date-today()) + " jours"
FSET subst_j_alt(date) wkday(date) + ", " + day(date) + subst_ordinal(day(date)) + " " + mon(date) + ", " + year(date)
FSET subst_jx(alt, date, time) iif(alt, subst_j_alt(date), $On + " " + subst_j_alt(date))
FSET subst_k_alt(date) wkday(date) + ", " + day(date) + subst_ordinal(day(date)) + " " + mon(date)
FSET subst_kx(alt, date, time) iif(alt, subst_k_alt(date), $On + " " + subst_k_alt(date))

51
include/lang/is.rem Normal file
View File

@@ -0,0 +1,51 @@
# Support for the Icelanding language.
# This file is part of REMIND.
# REMIND is Copyright (C) 1992-2022 by Dianne Skoll
# This file is derived from a translation by Björn Davíðsson (bjossi@snerpa.is)
SET $Sunday "sunnudagur"
SET $Monday "mánudagur"
SET $Tuesday "þriðjudagur"
SET $Wednesday "miðvikudagur"
SET $Thursday "fimmtudagur"
SET $Friday "föstudagur"
SET $Saturday "laugardagur"
SET $January "janúar"
SET $February "febrúar"
SET $March "mars"
SET $April "apríl"
SET $May "maí"
SET $June "júní"
SET $July "júlí"
SET $August "ágúst"
SET $September "september"
SET $October "október"
SET $November "nóvember"
SET $December "desember"
SET $Today "í dag"
SET $Tomorrow "á morgun"
BANNER Minnisatriði: %w, %d%s %m, %y%o:
SET $Am "fh"
SET $Pm "eh"
SET $Ago "síðan"
SET $Fromnow "frá því nú"
SET $On "þann"
SET $Now "núna"
SET $At "kl."
SET $Minute "mínútu"
SET $Hour "klukkustund"
SET $Is "er"
SET $Was "var"
SET $And "og"
SET $Hplu "ir"
SET $Mplu "r"
FSET subst_bx(a, d, t) "eftir " + (d - today()) + " daga"
fset subst_p(a, d, t) iif(d == today()+1, "", "a")

67
include/lang/it.rem Normal file
View File

@@ -0,0 +1,67 @@
# Support for the Italian language.
# This file is part of REMIND.
# REMIND is Copyright (C) 1992-2022 by Dianne Skoll
# This file is derived from a translation by Valerio Aimale
SET $Sunday "Domenica"
SET $Monday "Lunedí"
SET $Tuesday "Martedí"
SET $Wednesday "Mercoledí"
SET $Thursday "Giovedí"
SET $Friday "Venerdí"
SET $Saturday "Sabato"
SET $January "Gennaio"
SET $February "Febbraio"
SET $March "Marzo"
SET $April "Aprile"
SET $May "Maggio"
SET $June "Giugno"
SET $July "Luglio"
SET $August "Agosto"
SET $September "Settembre"
SET $October "Ottobre"
SET $November "Novembre"
SET $December "Dicembre"
SET $Today "oggi"
SET $Tomorrow "domani"
BANNER Promemoria per %w, %d %m %y%o:
SET $Am "am"
SET $Pm "pm"
SET $Ago "fa"
SET $Fromnow "da oggi"
SET $On ""
SET $Now "ora"
SET $At "alle"
SET $Minute "minuto"
SET $Hour "ora"
SET $Is "é"
SET $Was "era"
SET $And "e"
SET $Hplu "a"
SET $Mplu "i"
FSET subst_bx(a, d, t) "fra " + (d-today()) + " giorni"
FSET subst_p(a, d, t) iif(d==today()+1, "o", "i")
FSET subst_q(a, d, t) iif(d==today()+1, "a", "e")
FSET subst_ax(a, d, t) wkday(d) + ", " + day(d) + " " + mon(d) + " " + year(d)
FSET subst_jx(a, d, t) subst_ax(a, d, t)
FSET subst_kx(a, d, t) wkday(d) + ", " + day(d) + " " + mon(d)
FSET subst_ux(a, d, t) subst_ax(a, d, t)
FSET subst_vx(a, d, t) subst_kx(a, d, t)
FSET subst_1(a, d, t) iif(t==now(), $Now, t<now(), subst_1a(now()-t, $Ago), subst_1a(t-now(), $Fromnow))
FSET subst_1a(diff, when) subst_1b(diff/60, diff%60) + " " + when
FSET subst_1b(hdiff, mdiff) iif(hdiff==0, subst_minutes(mdiff), mdiff==0, subst_hours(hdiff), subst_hours(hdiff) + " " + $And + " " + subst_minutes(mdiff))
FSET subst_minutes(m) iif(m==1, "1 minuto", m + " minuti")
FSET subst_hours(h) iif(h==1, "1 ora", h + " ore")
FSET subst_0(a, d, t) iif(abs(now()-t)/60==1, "a", "e")
FSET subst_9(a, d, t) iif(abs(now()-t)%60==1, "o", "i")

56
include/lang/nl.rem Normal file
View File

@@ -0,0 +1,56 @@
# Support for the Dutch language.
# This file is part of REMIND.
# REMIND is Copyright (C) 1992-2022 by Dianne Skoll
# This file is derived from a translation by Willem Kasdorp and Erik-Jan Vens
SET $Sunday "zondag"
SET $Monday "maandag"
SET $Tuesday "dinsdag"
SET $Wednesday "woensdag"
SET $Thursday "donderdag"
SET $Friday "vrijdag"
SET $Saturday "zaterdag"
SET $January "januari"
SET $February "februari"
SET $March "maart"
SET $April "april"
SET $May "mei"
SET $June "juni"
SET $July "juli"
SET $August "augustus"
SET $September "september"
SET $October "oktober"
SET $November "november"
SET $December "december"
SET $Today "vandaag"
SET $Tomorrow "morgen"
BANNER Herinneringen voor %w, %d%s %m, %y%o:
SET $Am "am"
SET $Pm "pm"
SET $Ago "geleden"
SET $Fromnow "vanaf nu"
SET $On "op"
SET $Now "nu"
SET $At "op"
SET $Minute "minuut"
SET $Hour "uur"
SET $Is "is"
SET $Was "was"
SET $And "en"
SET $Hplu "en"
SET $Mplu "en"
FSET subst_1(a, d, t) iif(t==now(), $Now, t<now(), subst_1a(now()-t, $Ago), subst_1a(t-now(), $Fromnow))
FSET subst_1a(diff, when) subst_1b(diff/60, diff%60) + " " + when
FSET subst_1b(hdiff, mdiff) iif(hdiff==0, subst_minutes(mdiff), mdiff==0, subst_hours(hdiff), subst_hours(hdiff) + " " + $And + " " + subst_minutes(mdiff))
FSET subst_minutes(m) iif(m==1, "1 minuut", m + " minuten")
FSET subst_hours(h) iif(h==1, "1 uur", h + " uren")
FSET subst_bx(a, d, t) "over " + (d-today()) + " dagen"

58
include/lang/no.rem Normal file
View File

@@ -0,0 +1,58 @@
# Support for the Norwegian language.
# This file is part of REMIND.
# REMIND is Copyright (C) 1992-2022 by Dianne Skoll
# This file is derived from a translation by Trygve Randen
SET $Sunday "Søndag"
SET $Monday "Mandag"
SET $Tuesday "Tirsdag"
SET $Wednesday "Onsdag"
SET $Thursday "Torsdag"
SET $Friday "Fredag"
SET $Saturday "Lørdag"
SET $January "Januar"
SET $February "Februar"
SET $March "Mars"
SET $April "April"
SET $May "Mai"
SET $June "Juni"
SET $July "Juli"
SET $August "August"
SET $September "September"
SET $October "Oktober"
SET $November "November"
SET $December "Desember"
SET $Today "i dag"
SET $Tomorrow "i morgen"
BANNER Påminnelse for %w, %d. %m, %y%o:
SET $Am "am"
SET $Pm "pm"
SET $Ago "siden"
SET $Fromnow "fra nå"
SET $On "den"
SET $Now "nå"
SET $At "kl."
SET $Minute "minutt"
SET $Hour "time"
SET $Is "er"
SET $Was "var"
SET $And "og"
SET $Hplu "r"
SET $Mplu "er"
FSET subst_bx(a, d, t) "om " + (d-today()) + " dager"
FSET subst_ordinal(d) "."
FSET subst_ax(a, d, t) iif(a, subst_a_alt(d), $On + " " + subst_a_alt(d))
FSET subst_a_alt(d) wkday(d) + ", den " + day(d) + ". " + mon(d) + " " + year(d)
FSET subst_gx(a, d, t) iif(a, subst_g_alt(d), $On + " " + subst_g_alt(d))
FSET subst_g_alt(d) wkday(d) + ", den " + day(d) + ". " + mon(d)
FSET subst_ux(a, d, t) subst_ax(a, d, t)
FSET subst_vx(a, d, t) subst_gx(a, d, t)
FSET subst_p(a, d, t) iif(d==today()+1, "", "er")

69
include/lang/pl.rem Normal file
View File

@@ -0,0 +1,69 @@
# Support for the Polish language.
# This file is part of REMIND.
# REMIND is Copyright (C) 1992-2022 by Dianne Skoll
# This file is derived from a translation by Jerzy Sobczyk
SET $Sunday "Niedziela"
SET $Monday "Poniedziałek"
SET $Tuesday "Wtorek"
SET $Wednesday "Środa"
SET $Thursday "Czwartek"
SET $Friday "Piątek"
SET $Saturday "Sobota"
SET $January "Styczeń"
SET $February "Luty"
SET $March "Marzec"
SET $April "Kwiecień"
SET $May "Maj"
SET $June "Czerwiec"
SET $July "Lipiec"
SET $August "Sierpień"
SET $September "Wrzesień"
SET $October "Październik"
SET $November "Listopad"
SET $December "Grudzień"
SET $Today "dzisiaj"
SET $Tomorrow "jutro"
BANNER Terminarz na %w, %d. %m %y%o:
SET $Am "am"
SET $Pm "pm"
SET $Ago "temu"
SET $Fromnow "od teraz"
SET $On "-"
SET $Now "teraz"
SET $At "o"
SET $Minute "minut"
SET $Hour "godzin"
SET $Is "będzie"
SET $Was "było"
SET $And "i"
SET $Hplu ""
SET $Mplu ""
FSET subst_pl_plu(n) iif(n==1, "ę", (n==12||n==13||n==14), "", (n%10==2||n%10==3||n%10==4), "y", "")
FSET subst_ampm(h) iif(h<5, " w nocy", h<10, " rano", h<12, " przed południem", h<18, " po południu", h<22, " wieczorem", " w nocy")
FSET subst_ordinal(d) ""
FSET subst_a_alt(d) wkday(d) + ", " + day(d) + ". " + mon(d) + " " + year(d)
FSET subst_ax(a, d, t) iif(a, subst_a_alt(d), $On + " " + subst_a_alt(d))
FSET subst_bx(a, d, t) "za " + (d-today()) + " dni"
FSET subst_g_alt(d) wkday(d) + ", " + day(d) + ". " + mon(d)
FSET subst_gx(a, d, t) iif(a, subst_g_alt(d), $On + " " + subst_g_alt(d))
FSET subst_ux(a, d, t) subst_ax(a, d, t)
FSET subst_vx(a, d, t) subst_gx(a, d, t)
FSET subst_p(a, d, t) ""
FSET subst_0(a, d, t) subst_pl_plu(abs(t-now())/60)
FSET subst_9(a, d, t) subst_pl_plu(abs(t-now())%60)
FSET subst_1(a, d, t) iif(t==now(), $Now, t<now(), subst_1past(now()-t), subst_1future(t-now()))
FSET subst_1future(diff) "za " + iif(diff/60==0, subst_1min(diff%60), diff%60==0, subst_1h(diff/60), subst_1h(diff/60) + " " + $And + " " + subst_1min(diff%60))
FSET subst_1past(diff) iif(diff/60==0, subst_1min(diff%60), diff%60==0, subst_1h(diff/60), subst_1h(diff/60) + " " + $And + " " + subst_1min(diff%60)) + " temu"
FSET subst_1min(m) m + " " + $Minute + subst_pl_plu(m)
FSET subst_1h(h) h + " " + $Hour + subst_pl_plu(h)

69
include/lang/pt.rem Normal file
View File

@@ -0,0 +1,69 @@
# Support for the (Brazilian) Portuguese language.
# This file is part of REMIND.
# REMIND is Copyright (C) 1992-2022 by Dianne Skoll
# This file is derived from a translation by Marco Paganini
SET $Sunday "domingo"
SET $Monday "segunda"
SET $Tuesday "terça"
SET $Wednesday "quarta"
SET $Thursday "quinta"
SET $Friday "sexta"
SET $Saturday "sábado"
SET $January "janeiro"
SET $February "fevereiro"
SET $March "março"
SET $April "abril"
SET $May "maio"
SET $June "junho"
SET $July "julho"
SET $August "agosto"
SET $September "setembro"
SET $October "outubro"
SET $November "novembro"
SET $December "dezembro"
SET $Today "hoje"
SET $Tomorrow "amanhã"
BANNER Avisos para %w, %d de %m de %y%o:
SET $Am "am"
SET $Pm "pm"
SET $Ago "atrás"
SET $Fromnow "adiante"
SET $On "em"
SET $Now "agora"
SET $At "as"
SET $Minute "minuto"
SET $Hour "hora"
SET $Is "é"
SET $Was "foi"
SET $And "e"
SET $Hplu "s"
SET $Mplu "s"
FSET subst_ordinal(d) ""
FSET subst_on_wd(d) iif(wkdaynum(d) == 1 || wkdaynum(d) == 2, "no", "na")
FSET subst_a_alt(d) wkday(d) + ", " + day(d) + " de " + mon(d) + " de " + year(d)
FSET subst_bx(a, d, t) "em " + (d-today()) + " dias"
FSET subst_c_alt(d) wkday(d)
FSET subst_g_alt(d) wkday(d) + ", " + day(d) + " " + mon(d)
FSET subst_ax(a, d, t) iif(a, subst_a_alt(d), subst_on_wd(d) + " " + subst_a_alt(d))
FSET subst_cx(a, d, t) iif(a, subst_c_alt(d), subst_on_wd(d) + " " + subst_c_alt(d))
FSET subst_gx(a, d, t) iif(a, subst_g_alt(d), subst_on_wd(d) + " " + subst_g_alt(d))
FSET subst_jx(a, d, t) subst_ax(a, d, t)
FSET subst_k_alt(d) wkday(d) + ", " + day(d) + " de " + mon(d)
FSET subst_kx(a, d, t) iif(a, subst_k_alt(d), subst_on_wd(d) + " " + subst_k_alt(d))
FSET subst_ux(a, d, t) subst_ax(a, d, t)
FSET subst_vx(a, d, t) subst_kx(a, d, t)
FSET subst_1(a, d, t) iif(t==now(), $Now, t>now(), "em " + subst_1help(t-now()), subst_1help(now()-t) + " " + $Ago)
FSET subst_1help(diff) iif(diff/60==0, subst_mplu(diff%60), diff%60==0, subst_hplu(diff/60), subst_hplu(diff/60) + " " + $And + " " + subst_mplu(diff%60))
FSET subst_mplu(m) iif(m==1, "1 " + $Minute, m + " " + $Minute + $Mplu)
FSET subst_hplu(h) iif(h==1, "1 " + $Hour, h + " " + $Hour + $Hplu)

68
include/lang/ro.rem Normal file
View File

@@ -0,0 +1,68 @@
# Support for the Romanian language.
# This file is part of REMIND.
# REMIND is Copyright (C) 1992-2022 by Dianne Skoll
# This file is derived from a translation by Liviu Daia
SET $Sunday "Duminică"
SET $Monday "Luni"
SET $Tuesday "Marți"
SET $Wednesday "Miercuri"
SET $Thursday "Joi"
SET $Friday "Vineri"
SET $Saturday "Sâmbătă"
SET $January "Ianuarie"
SET $February "Februarie"
SET $March "Martie"
SET $April "Aprilie"
SET $May "Mai"
SET $June "Iunie"
SET $July "Iulie"
SET $August "August"
SET $September "Septembrie"
SET $October "Octombrie"
SET $November "Noiembrie"
SET $December "Decembrie"
SET $Today "astăzi"
SET $Tomorrow "mâine"
BANNER Reamintiri pentru %w, %d %m %y%o:
SET $Am "am"
SET $Pm "pm"
SET $Ago "acum"
SET $Fromnow "peste"
SET $On "pe"
SET $Now "acum"
SET $At "la ora"
SET $Minute "minut"
SET $Hour "or"
SET $Is "este"
SET $Was "a fost"
SET $Mplu "e"
SET $Hplu "e"
SET $And "şi"
FSET subst_bx(a, d, t) "peste " + (d-today()) + " zile"
FSET subst_ampm(h) iif(h<4, " noaptea", h<12, " dimineaţa", h<18, " după-amiaza", " seara")
FSET subst_ordinal(d) ""
FSET subst_ax(a, d, t) wkday(d) + ", " + day(d) + " " + mon(d) + " " + year(d)
FSET subst_cx(a, d, t) wkday(d)
FSET subst_gx(a, d, t) wkday(d) + ", " + day(d) + " " + mon(d)
FSET subst_jx(a, d, t) wkday(d) + ", " + mon(d) + " " + day(d) + ", " + year(d)
FSET subst_kx(a, d, t) wkday(d) + ", " + mon(d) + " " + day(d)
FSET subst_ux(a, d, t) subst_ax(a, d, t)
FSET subst_vx(a, d, t) subst_gx(a, d, t)
FSET subst_p(a, d, t) iif(d==today()+1, "", "le")
FSET subst_1(a, d, t) iif(t==now(), $Now, t<now(), subst_1helper(now()-t, "acum "), subst_1helper(t-now(), "peste "))
FSET subst_1helper(diff, when) when + iif(diff%60==0, subst_1h(diff/60), diff/60==0, subst_1m(diff%60), subst_1h(diff/60) + " " + $And + " " + subst_1m(diff%60))
FSET subst_1h(h) iif(h==1, "1 oră", h + " ore")
FSET subst_1m(m) iif(m==1, "1 minut", m + " minute")
FSET subst_0(a, d, t) iif(abs(t-now())/60==1, "ă", "e")

2
include/site/README Normal file
View File

@@ -0,0 +1,2 @@
This directory is for system administrators to install site-wide
Remind scripts that are useful to their user-base.

View File

@@ -1,4 +1,4 @@
.TH REM 1 "1 January 2021"
.TH REM 1 "@RELEASE_DATE@" "User Commands" "VERSION @VERSION@"
.UC 4
.SH NAME
rem \- Invoke Remind with a default filename
@@ -16,5 +16,7 @@ the filename $HOME/.reminders
.PP
.SH AUTHOR
Remind was written by Dianne Skoll <dianne@skoll.ca>
.SH HOME PAGE
https://dianne.skoll.ca/projects/remind/
.SH SEE ALSO
\fBremind\fR

View File

@@ -1,4 +1,4 @@
.TH REM2PS 1 "5 January 2021"
.TH REM2PS 1 "@RELEASE_DATE@" "User Commands" "VERSION @VERSION@"
.UC 4
.SH NAME
rem2ps \- draw a PostScript calendar from Remind output
@@ -586,6 +586,18 @@ For a SHADE or COLOR special, the blue color component.
.B body \fIbody\fR
The body of the reminder to issue. Always present.
.TP
.B calendar_body \fIbody\fR
The text appropriate to include in a calendar. Only present if the
original body contains %"...%" sequences and the "q" modifier was used
with Remind's "-pp..." flag.
.TP
.B plain_body \fIbody\fR
The "plain" body of the reminder with any %"...%" sequences removed.
If your back-end is designed to draw a calendar, then it should
use the \fBcalendar_body\fR if present. If not, then it
should use the \fBplain_body\fR if present, and if not, then it
should fall back on the \fBbody\fR.
.TP
.B rawbody \fIraw\fR
The "raw" body of the reminder, before any expression-pasting or
substitution-sequence processing. If the raw body would be the same
@@ -674,6 +686,8 @@ resulting PostScript output will probably not work.
You should ensure that the values you supply for margin widths are sensible.
If they are too big for the media size, \fBRem2ps\fR will not complain,
but again, the PostScript output will probably not work.
.SH HOME PAGE
https://dianne.skoll.ca/projects/remind/
.SH SEE ALSO
\fBremind\fR, \fBrem2pdf\fR, \fBrem2html\fR, \fBtkremind\fR.

File diff suppressed because it is too large Load Diff

View File

@@ -1,4 +1,4 @@
.TH TKREMIND 1 "15 January 2021"
.TH TKREMIND 1 "@RELEASE_DATE@" "User Commands" "VERSION @VERSION@"
.UC 4
.SH NAME
tkremind \- graphical front-end to Remind calendar program
@@ -18,13 +18,13 @@ as well as the tcllib extension. It also requires a \fBwish\fR
binary. If you are using Tcl/Tk 8.5, you may also need either the Img
or the tkpng extension to handle PNG images.
.SH OPTIONS
\fBTkRemind\fR itself has no options. However, it passes certain options
on to \fBRemind\fR. The options it passes are
\fB\-b\fR, \fB\-g\fR, \fB\-x\fR, \fB\-i\fR and \fB\-m\fR.
See the \fBRemind\fR man page for details about the options.
Note that \fBTkRemind\fR will respect the \fB\-m\fR and
\fB\-b1\fR options and adjust its appearance accordingly.
.SH COMMAND-LINE OPTIONS
\fBTkRemind\fR itself has no command-line options. However, it passes
certain options on to \fBRemind\fR. The options it passes are
\fB\-b\fR, \fB\-g\fR, \fB\-x\fR, \fB\-i\fR and \fB\-m\fR. See the
\fBRemind\fR man page for details about the options. Note that
\fBTkRemind\fR will respect the \fB\-m\fR and \fB\-b1\fR options and
adjust its appearance accordingly.
\fIRead_file\fR is the file from which \fBTkRemind\fR reads reminders.
It is in standard \fBRemind\fR format. \fIWrite_file\fR is the file
@@ -44,8 +44,14 @@ include the line:
.PP
\fIConfig_file\fR is the file in which \fBTkRemind\fR stores
its options. If it is omitted, it defaults to \fI$HOME/.tkremindrt\fR.
its options. If it is omitted, it defaults to \fI$HOME/.config/tkremindrc\fR.
.PP
If \fB$HOME/.reminders\fR is a \fIdirectory\fR, then \fBTkRemind\fR defaults to
reading \fB$HOME/.reminders\fR and writing new reminders to
\fB$HOME/.reminders/100-tkremind.rem\fR. If you want to keep your
reminders in a directory \fB$HOME/.reminders\fR, you should create that
directory before starting \fBTkRemind\fR.
.SH THE CALENDAR WINDOW
When you start \fBTkRemind\fR, it displays a calendar for the current
month, with today's date highlighted. Reminders are filled into each
@@ -173,6 +179,13 @@ it will be underlined when you move the cursor over it, and
you can edit it in a text editor by either left- or right-clicking
on the reminder.
.SH ERRORS
If there are any errors in your reminder file, the "Queue..." button
changes to "Errors...". Click on "Errors..." to see the Remind error
output. Click "OK" to close the error window; this makes the button
in the main TkRemind window to revert to "Queue..."
.SH BACKGROUND REMINDERS
If you create "timed" reminders, \fBTkRemind\fR will queue them in
@@ -267,7 +280,7 @@ Similar to Change entry font, but applies to calendar heading
.PP
Once you've configured the options the way you like them,
press \fBApply Options\fR to put them into effect, \fBSave Options\fR
to put them into effect and save them in $HOME/.tkremindrc, or
to put them into effect and save them in $HOME/.config/tkremindrc, or
\fBCancel\fR to cancel any changes you made.
.SH KEYBOARD SHORTCUTS
@@ -286,6 +299,19 @@ Next Month
.B Home
Today
.SH IMMEDIATE UPDATES
If you are running \fBTkRemind\fR on Linux and have the
\fBinotifywait\fR program installed (part of the \fBinotify-tools\fR
or similar package), then \fBTkRemind\fR redraws the calendar window
\fIimmediately\fR if \fB$HOME/.reminders\fR changes (or, if it is a
directory, any files in that directory change.)
.PP
This lets \fBTkRemind\fR react immediately to hand-edited reminders or
to reminder files that are imported from another calendar system (for example,
you may have a cron job that periodically imports your Google Calendar
entries into Remind format.)
.SH ODDS AND ENDS
\fBTkRemind\fR performs some basic consistency checks when you add or
preview a reminder. However, if you edit a reminder in the previewer,
@@ -316,8 +342,7 @@ You can use this to activate certain reminders in different ways
for \fBTkRemind\fR (for example).
.PP
\fBTkRemind\fR uses tags to keep track of reminders in the
script file. It also places special comments in the reminder
file to store additional state. You can certainly mix
script file. You can certainly mix
"hand-crafted" reminders with reminders created by \fBTkRemind\fR
if you are aware of the following rules and limitations:
.TP
@@ -327,15 +352,16 @@ where \fInnn\fR is a number. You should not use such \fBTAG\fRs
in hand-crafted reminders.
.TP
o
Do not edit lines starting with "# TKTAGnnn", "# TKEND", or any
lines in between. You can move such lines, but be careful to move
them as a single block.
.TP
o
Hand-crafted reminders cannot be edited with \fBTkRemind\fR, and
for hand-crafted timed reminders, you will not be presented with
the "Don't remind me again" option when they pop up.
.PP
However, rather than mixing hand-edited files with \fBTkRemind\fR-generated
ones, it is better to make \fB$HOME/.reminders\fR a directory and keep
your hand-edited files in a separate \fB*.rem\fR file than \fBTkRemind\fR's
\fB100-tkremind.rem\fR file.
.SH SERVER MODE
\fBRemind\fR has a special mode for interacting with programs like
@@ -393,14 +419,16 @@ This line is emitted in response to a \fBSTATUS\fR command. The number
.SH AUTHOR
TkRemind was written by Dianne Skoll <dianne@skoll.ca>
\fBTkRemind\fR is Copyright 1996-2020 by Dianne Skoll.
\fBTkRemind\fR is Copyright 1996-2022 by Dianne Skoll.
.SH FILES
$HOME/.reminders -- default reminder file.
$HOME/.reminders -- default reminder file or directory.
$HOME/.tkremindrc -- \fBTkRemind\fR saved options.
$HOME/.config/tkremindrc -- \fBTkRemind\fR saved options.
.SH HOME PAGE
https://dianne.skoll.ca/projects/remind/
.SH SEE ALSO
\fBremind\fR, \fBrem2ps\fR, \fBrem2pdf\fR, \fBrem2html\fR

View File

@@ -19,7 +19,7 @@ install:
$(PERL) -M$$m -e 1 > /dev/null 2>&1; \
if test $$? != 0 ; then echo "Not installing rem2html; missing $$m"; exit 0; fi; \
done; \
pod2man rem2html > rem2html.1 && mkdir -p $(DESTDIR)$(mandir)/man1 && cp rem2html.1 $(DESTDIR)$(mandir)/man1/rem2html.1 || true; \
pod2man --center "VERSION @VERSION@" --date "@RELEASE_DATE@" rem2html > rem2html.1 && mkdir -p $(DESTDIR)$(mandir)/man1 && cp rem2html.1 $(DESTDIR)$(mandir)/man1/rem2html.1 || true; \
echo "Installing rem2html in $(DESTDIR)$(bindir)"; \
mkdir -p $(DESTDIR)$(bindir) && sed -e 's|^#!perl|#!$(PERL)|' < rem2html > $(DESTDIR)$(bindir)/rem2html && chmod 755 $(DESTDIR)$(bindir)/rem2html && exit 0; \
exit 1;

View File

@@ -68,7 +68,7 @@ and newmoon.png, which are expected to live in C<--imgbase>.
=item --stylesheet I<url.css>
Use I<url.css> as the stylesheet. If this option is used,
I<url.css> is interpreted relative to B<imgbase> I<unless> it start
I<url.css> is interpreted relative to B<imgbase> I<unless> it starts
with a "/".
=item --nostyle
@@ -130,6 +130,10 @@ today's date, add the following reminder to your reminders file:
rem2html was written by Dianne Skoll with much inspiration from an
earlier version by Don Schwarz.
=head1 HOME PAGE
L<https://dianne.skoll.ca/projects/remind/>
=head1 SEE ALSO
B<remind>, B<rem2ps>, B<rem2pdf>, B<tkremind>

View File

@@ -1,4 +1,15 @@
use ExtUtils::MakeMaker;
{
# Override pod2man options
package MY;
sub manifypods {
my ($self,%attribs) = @_;
my $result = $self->SUPER::manifypods(%attribs);
$result =~ s/^(POD2MAN_EXE\s*=\s*)(.+)$/$1$2 --center 'VERSION @VERSION@' --date '@RELEASE_DATE@'/m;
return $result;
}
}
WriteMakefile(
NAME => 'Remind::PDF',
AUTHOR => q{Dianne Skoll <dianne@skoll.ca>},

View File

@@ -29,12 +29,20 @@ install:
if test $$? != 0 ; then echo "Not installing rem2pdf; missing $$m"; exit 0; fi; \
done; \
echo "Installing rem2pdf"; \
if test "$(prefix)" = "/usr" ; then \
if test "$(INSTALL_BASE)" != "" ; then \
$(MAKE) install DESTDIR=$(DESTDIR) "INSTALL_BASE=$(INSTALL_BASE)" && exit 0; \
elif test "$(prefix)" = "/usr" ; then \
$(MAKE) install DESTDIR=$(DESTDIR) INSTALLDIRS=vendor && exit 0; \
else \
elif test "$(prefix)" = "/usr/local" ; then \
$(MAKE) install DESTDIR=$(DESTDIR) && exit 0; \
else \
$(MAKE) install DESTDIR=$(DESTDIR) "INSTALL_BASE=$(prefix)" && exit 0; \
fi; \
exit 1;
Makefile: Makefile.PL
$(PERL) Makefile.PL || true
if test "$(prefix)" != "/usr" -a "$(prefix)" != "/usr/local" -a "$(INSTALL_BASE)" = "" ; then \
$(PERL) Makefile.PL @PERLARTIFACTS@ INSTALL_BASE=$(prefix) || true;\
else \
$(PERL) Makefile.PL @PERLARTIFACTS@ INSTALL_BASE=$(INSTALL_BASE) || true;\
fi

View File

@@ -1,6 +1,7 @@
#!@PERL@
use strict;
use warnings;
use lib '@prefix@/lib/perl5';
use Encode;
use Cairo;
@@ -442,14 +443,14 @@ B<-p>, B<-pp> or B<-ppp> options into B<rem2pdf>. The PDF output
will be sent to standard output. So for example, to print a 12-month
calendar for the year 2030, use:
remind -pp12 /dev/null Jan 2030 | rem2pdf -e -l -c=3 | lpr
remind -pp12 /dev/null Jan 2030 | rem2pdf -e -l -c3 | lpr
You can concatenate multiple B<remind> runs. For example, the following
will produce a PDF calendar for January through March of 2023, and
June of 2023 (for a total of four pages);
(remind -pp3 Jan 2023 /dev/null ; \
remind -p June 2023 /dev/null) | rem2pdf -e -l -c=3 > cal.pdf
(remind -pp3 /dev/null Jan 2023 ; \
remind -pp /dev/null June 2023) | rem2pdf -e -l -c3 > cal.pdf
=head1 FORMATTED TEXT
@@ -478,14 +479,14 @@ positioned absolutely with respect to the day's box (and is not
counted when calculating the box's height.)
A positive I<x> value positions the left edge of the text I<x> points
to the right of the left side of the calender box, while a negative
to the right of the left side of the calendar box, while a negative
I<x> value positions the right edge of the text I<x> points to the left
of the right side of the calender box.
of the right side of the calendar box.
A positive I<y> value positions the top edge of the text I<y> points
below the top of the calender box, while a negative I<y> value
below the top of the calendar box, while a negative I<y> value
positions the bottom edge of the text I<y> points above the bottom of
the calender box.
the calendar box.
If you use absolutely-positioned text, it's up to you to make sure it
doesn't overlap other text; B<rem2pdf> takes no special precautions to
@@ -503,6 +504,10 @@ of each calendar box:
B<Rem2PDF> was written by Dianne Skoll <dianne@skoll.ca>
=head1 HOME PAGE
L<https://dianne.skoll.ca/projects/remind/>
=head1 SEE ALSO
B<remind>, B<rem2ps>, B<rem2html>, B<tkremind>

View File

@@ -227,14 +227,16 @@ sub parse_oldstyle_line
if ($hash->{passthru}) {
if ($hash->{passthru} =~ /^(shade|color|colour)$/i) {
if ($hash->{body} =~ /^\s*(\d+)\s+(\d+)\s+(\d+)/) {
if ($hash->{body} =~ /^\s*(\d+)\s+(\d+)\s+(\d+)\s*(.*)/) {
$hash->{r} = $1;
$hash->{g} = $2;
$hash->{b} = $3;
} elsif ($hash->{body} =~ /^\s*(\d+)/) {
$hash->{body} = $4;
} elsif ($hash->{body} =~ /^\s*(\d+)\s*(.*)/) {
$hash->{r} = $1;
$hash->{g} = $1;
$hash->{b} = $1;
$hash->{body} = $2;
}
}
}
@@ -285,7 +287,7 @@ sub read_one_month_pp
Given a hashref C<$hash> consisting of one entry parsed
from the "remind -p" stream and a C<$specials_accepted> hash,
return 1 if we should include this entry in the calendar or
0 if mot.
0 if not.
=cut
sub accept_special
@@ -637,7 +639,7 @@ sub draw_day
$so_far += $h2;
}
if ($height) {
if ($entry_height > $height) {
if ($h + $entry_height + 2 * $settings->{border_size} > $height) {
print STDERR "WARNING: overfull box at $day " . $self->{monthname} . ' ' . $self->{year} . "\n";
$entry_height = $height;
}
@@ -753,24 +755,13 @@ sub draw_small_calendar
$last_day_on_row += 7;
$rows++;
}
my $layout = Pango::Cairo::create_layout($cr);
my $desc = Pango::FontDescription->from_string($settings->{small_cal_font} . ' ' . '10px');
$layout->set_font_description($desc);
$layout->set_text('88 88 88 88 88 88 88');
my ($wid, $h) = $layout->get_pixel_size();
$h += 1;
$h *= ($rows + 2); # row for month name; row for day names
my $font_size = $self->calculate_small_calendar_font_size($cr, $width, $height, $settings, $rows);
my $scale = $width / $wid;
if (($height / $h) < $scale) {
$scale = $height / $h;
}
my $font_size = int($scale * 10);
$layout = Pango::Cairo::create_layout($cr);
$desc = Pango::FontDescription->from_string($settings->{small_cal_font} . ' ' . $font_size . 'px');
my $layout = Pango::Cairo::create_layout($cr);
my $desc = Pango::FontDescription->from_string($settings->{small_cal_font} . ' ' . $font_size . 'px');
$layout->set_font_description($desc);
$layout->set_text('88 ');
($wid, $h) = $layout->get_pixel_size();
my ($wid, $h) = $layout->get_pixel_size();
$h += 1;
# Month name
@@ -824,6 +815,43 @@ sub draw_small_calendar
}
}
sub calculate_small_calendar_font_size
{
my ($self, $cr, $width, $height, $settings, $rows) = @_;
my $layout = Pango::Cairo::create_layout($cr);
my $desc = Pango::FontDescription->from_string($settings->{small_cal_font} . ' ' . '10px');
$layout->set_font_description($desc);
$layout->set_text('88 88 88 88 88 88 88');
my ($wid, $h) = $layout->get_pixel_size();
$h += 1;
$h *= ($rows + 2); # row for month name; row for day names
my $scale = $width / $wid;
if (($height / $h) < $scale) {
$scale = $height / $h;
}
my $font_size = int($scale * 10);
# Check
$desc = Pango::FontDescription->from_string($settings->{small_cal_font} . ' ' . $font_size . 'px');
$layout->set_font_description($desc);
$layout->set_text('88 88 88 88 88 88 88');
($wid, $h) = $layout->get_pixel_size();
$h += 1;
$h *= ($rows + 2); # row for month name; row for day names
$scale = $width / $wid;
if (($height / $h) < $scale) {
$scale = $height / $h;
}
if ($scale < 1) { # Font size is too big
$font_size--;
}
return $font_size;
}
package Remind::PDF::Multi;
=head1 NAME

View File

@@ -76,7 +76,15 @@ sub render
$layout->set_width(1024 * ($x2 - $x1 - 2 * $settings->{border_size}));
$layout->set_wrap('word-char');
$layout->set_text(Encode::decode('UTF-8', $self->{body}));
my $body;
if (exists($self->{calendar_body})) {
$body = $self->{calendar_body};
} elsif (exists($self->{plain_body})) {
$body = $self->{plain_body};
} else {
$body = $self->{body};
}
$layout->set_text(Encode::decode('UTF-8', $body));
my $desc = Pango::FontDescription->from_string($settings->{entry_font} . ' ' . $settings->{entry_size} . 'px');
$layout->set_font_description($desc);
my ($wid, $h) = $layout->get_pixel_size();
@@ -233,11 +241,9 @@ sub _adjust
package Remind::PDF::Entry::color;
use base 'Remind::PDF::Entry';
# Strip the RGB prefix from body
# Nothing to do for COLOR-type reminder
sub _adjust
{
my ($self) = @_;
$self->{body} =~ s/^\d+\s+\d+\s+\d+\s+//;
}
package Remind::PDF::Entry::postscript;

View File

@@ -7,7 +7,7 @@
# A cheesy graphical front/back end for Remind using Tcl/Tk
#
# This file is part of REMIND.
# Copyright (C) 1992-2021 Dianne Skoll
# Copyright (C) 1992-2022 Dianne Skoll
#
#--------------------------------------------------------------
@@ -103,6 +103,9 @@ set OptDescr(RunCmd) "(String) If non-blank, run specified command when a pop-up
set Option(FeedReminder) 0
set OptDescr(FeedReminder) "(0/1) If 1, feed the reminder to RunCmd on standard input (see RunCmd option)"
set Option(DayAnchor) "center"
set OptDescr(DayAnchor) "(w/center/e) Anchor the day number to the left (w), center or right (e) of its container"
set Option(Editor) "emacs +%d %s"
set OptDescr(Editor) "(String) Specify command to edit a file. %d is replaced with line number and %s with filename"
@@ -127,6 +130,12 @@ set OptDescr(BackgroundColor) "Default background color of calendar boxes"
set Option(TextColor) "#000000"
set OptDescr(TextColor) "Default text color in calendar boxes"
set Option(TodayColor) "#00C0C0"
set OptDescr(TodayColor) "Background color for today heading"
set Option(LineColor) "#000000"
set OptDescr(LineColor) "Color of gridlines on calendar"
set Option(LabelColor) "#000000"
set OptDescr(LabelColor) "Default label color for headings"
@@ -165,6 +174,9 @@ set EditorPid -1
# Inotify file
set InotifyFP ""
# Errors from last remind run
set RemindErrors ""
# Reminder file to append to -- default
set AppendFile {NOSUCHFILE}
catch {set AppendFile $ReminderFile}
@@ -282,7 +294,17 @@ proc is_warning_header { line } {
proc Initialize {} {
global DayNames argc argv CommandLine ReminderFile AppendFile Remind PSCmd
global MondayFirst TwentyFourHourMode ReminderFileModTime
global TodayDay TodayMonth TodayYear
global Option ConfigFile
# In case date has rolled over, recalculate Today* values
set now [clock seconds]
set TodayMonth [expr [string trim [clock format $now -format %N]] - 1]
set TodayYear [clock format $now -format %Y]
set TodayDay [string trim [clock format $now -format %e]]
set CommandLine "|$Remind -itkremind=1 -pp -y -l EXTRA"
set PSCmd "$Remind -itkremind=1 -itkprint=1 -pp -l EXTRA"
set i 0
@@ -435,6 +457,7 @@ proc CreateCalFrame { w dayNames } {
# Figure out reasonable height for text frames
global SetFontsWorked
global Option
global MondayFirst
set h [winfo screenheight .]
if {$h <= 480} {
if {$SetFontsWorked} {
@@ -448,8 +471,7 @@ proc CreateCalFrame { w dayNames } {
set h 5
}
global MondayFirst
frame $w -background $Option(WinBackground)
frame $w -background $Option(LineColor)
for {set i 0} {$i < 7} {incr i} {
if {$MondayFirst} {
set index [expr ($i+1)%7]
@@ -457,28 +479,31 @@ proc CreateCalFrame { w dayNames } {
set index $i
}
label $w.day$i -border 1 -text [lindex $dayNames $index] -justify center -font HeadingFont -foreground $Option(LabelColor) -background $Option(WinBackground)
grid configure $w.day$i -row 0 -column $i -sticky ew
label $w.day$i -bd 0 -text [lindex $dayNames $index] -justify center -font HeadingFont -foreground $Option(LabelColor) -background $Option(WinBackground) -highlightthickness 0
grid configure $w.day$i -row 0 -column $i -sticky ew -padx 1 -pady 1
}
for {set i 0} {$i < 6} {incr i} {
set n [expr $i*7]
for {set j 0} {$j < 7} {incr j} {
set f [expr $n+$j]
button $w.l$f -text "" -justify center -command "" \
-state disabled -relief flat -border 0 -padx 0 -pady 0 -font HeadingFont
text $w.t$f -width 12 -height $h -border 1 -spacing3 3 -wrap word -relief flat \
-state disabled -takefocus 0 -cursor {} -font CalboxFont -foreground $Option(TextColor) -background $Option(BackgroundColor)
button $w.l$f -text "" -justify center -command "" -anchor $Option(DayAnchor) \
-state disabled -relief flat -bd 0 -padx 0 -pady 0 -font HeadingFont -highlightthickness 1
text $w.t$f -width 12 -height $h -bd 0 -spacing3 3 -wrap word -relief flat \
-state disabled -takefocus 0 -cursor {} -font CalboxFont -foreground $Option(TextColor) -background $Option(BackgroundColor) \
-highlightthickness 0
frame $w.f$f -padx 0 -pady 0 -highlightthickness 0 -relief flat -bd 0
$w.t$f tag bind TAGGED <ButtonPress-1> "EditTaggedReminder $w.t$f"
$w.t$f tag bind REM <ButtonPress-3> "FireEditor $w.t$f"
grid configure $w.l$f -row [expr $i*2+1] -column $j -sticky ew
grid configure $w.t$f -row [expr $i*2+2] -column $j -sticky nsew
pack $w.l$f -in $w.f$f -side top -expand 0 -fill x
pack $w.t$f -in $w.f$f -side top -expand 1 -fill both
grid configure $w.f$f -row [expr $i+1] -column $j -sticky nsew -padx 1 -pady 1
}
}
for {set i 0} {$i < 7} {incr i} {
grid columnconfigure $w $i -weight 1
}
for {set i 2} {$i < 14} {incr i 2} {
for {set i 1} {$i < 7} {incr i} {
grid rowconfigure $w $i -weight 1
}
}
@@ -504,8 +529,12 @@ proc ConfigureCalFrame { w firstDay numDays } {
set last [expr $offset+$numDays]
for {set i 0} {$i < $first} {incr i} {
grid $w.l$i $w.t$i
$w.l$i configure -text "" -command "" -state normal -relief flat -foreground $Option(LabelColor) -background $Option(WinBackground)
grid $w.f$i
pack $w.l$i -in $w.f$i -side top -expand 0 -fill x
pack $w.t$i -in $w.f$i -side top -expand 1 -fill both
raise $w.l$i
raise $w.t$i
$w.l$i configure -text "" -command "" -state normal -relief flat -foreground $Option(LabelColor) -background $Option(WinBackground) -highlightcolor $Option(LineColor) -highlightbackground $Option(WinBackground)
$w.l$i configure -state disabled
balloon_add_help $w.l$i ""
$w.t$i configure -relief flat -takefocus 0 -state normal -background $Option(WinBackground)
@@ -515,13 +544,19 @@ proc ConfigureCalFrame { w firstDay numDays } {
}
$w.t$i tag bind TAGGED <ButtonPress-1> "EditTaggedReminder $w.t$i"
$w.t$i tag bind REM <ButtonPress-3> "FireEditor $w.t$i"
$w.t$i configure -state disabled
$w.t$i configure -state disabled -takefocus 0
}
for {set i $first} {$i <= $last} {incr i} {
grid $w.l$i $w.t$i
set row [expr ($i/7)+1]
grid $w.f$i
grid rowconfigure $w $row -weight 1
pack $w.l$i -in $w.f$i -side top -expand 0 -fill x
pack $w.t$i -in $w.f$i -side top -expand 1 -fill both
raise $w.l$i
raise $w.t$i
set d [expr $i-$first+1]
$w.l$i configure -text $d -state normal -relief flat \
-command "ModifyDay $d $firstDay" -foreground $Option(LabelColor) -background $Option(WinBackground)
-command "ModifyDay $d $firstDay" -foreground $Option(LabelColor) -background $Option(WinBackground) -highlightcolor $Option(LineColor) -highlightbackground $Option(WinBackground)
balloon_add_help $w.l$i "Add a reminder..."
$w.t$i configure -relief sunken -takefocus 1 -state normal -foreground $Option(TextColor) -background $Option(BackgroundColor)
$w.t$i delete 1.0 end
@@ -530,23 +565,27 @@ proc ConfigureCalFrame { w firstDay numDays } {
}
$w.t$i tag bind TAGGED <ButtonPress-1> "EditTaggedReminder $w.t$i"
$w.t$i tag bind REM <ButtonPress-3> "FireEditor $w.t$i"
$w.t$i configure -state disabled
$w.t$i configure -state disabled -takefocus 0
}
set forgetIt 0
for {set i [expr $last+1]} {$i < 42} {incr i} {
if {$i%7 == 0} {
set forgetIt 1
}
set row [expr ($i/7)*2+1]
set row [expr ($i/7)+1]
if {$forgetIt} {
grid remove $w.l$i $w.t$i
grid remove $w.f$i
grid rowconfigure $w $row -weight 0
grid rowconfigure $w [expr $row+1] -weight 0
} else {
grid $w.l$i $w.t$i
grid rowconfigure $w [expr $row+1] -weight 1
grid $w.f$i
pack $w.l$i -in $w.f$i -side top -expand 0 -fill x
pack $w.t$i -in $w.f$i -side top -expand 1 -fill both
raise $w.l$i
raise $w.t$i
grid rowconfigure $w $row -weight 1
}
$w.l$i configure -text "" -command "" -state normal -relief flat -foreground $Option(LabelColor) -background $Option(WinBackground)
$w.l$i configure -text "" -command "" -state normal -relief flat -foreground $Option(LabelColor) -background $Option(WinBackground) -highlightcolor $Option(LineColor) -highlightbackground $Option(WinBackground)
$w.l$i configure -state disabled
balloon_add_help $w.l$i ""
$w.t$i configure -relief flat -takefocus 0 -state normal -background $Option(WinBackground)
@@ -556,11 +595,11 @@ proc ConfigureCalFrame { w firstDay numDays } {
}
$w.t$i tag bind TAGGED <ButtonPress-1> "EditTaggedReminder $w.t$i"
$w.t$i tag bind REM <ButtonPress-3> "FireEditor $w.t$i"
$w.t$i configure -state disabled
$w.t$i configure -state disabled -takefocus 0
}
if { $CurMonth == $TodayMonth && $CurYear == $TodayYear } {
set n [expr $TodayDay + $offset]
$w.l$n configure -background "#00c0c0"
$w.l$n configure -background $Option(TodayColor)
}
}
@@ -577,36 +616,36 @@ proc DoQueue {} {
#---------------------------------------------------------------------------
proc CreateCalWindow { dayNames } {
global Option
frame .h -background $Option(WinBackground);
label .h.title -text "" -justify center -pady 1 -border 1 -relief raised -font HeadingFont -background $Option(WinBackground) -foreground $Option(LabelColor)
pack .h.title -side top -fill x
frame .h -background $Option(LineColor)
label .h.title -text "" -justify center -pady 2 -bd 0 -relief flat -font HeadingFont -background $Option(WinBackground) -foreground $Option(LabelColor)
pack .h.title -side top -fill x -pady 1 -padx 1
pack .h -side top -expand 0 -fill x
. configure -background $Option(LineColor)
CreateCalFrame .cal $dayNames
frame .b -background $Option(WinBackground);
button .b.prev -text "\u2b9c" -command {MoveMonth -1} -border 1 -foreground $Option(LabelColor) -background $Option(WinBackground)
frame .b -background $Option(LineColor)
button .b.prev -text "\u2b9c" -command {MoveMonth -1} -bd 0 -foreground $Option(LabelColor) -background $Option(WinBackground) -highlightthickness 1 -highlightcolor $Option(LineColor) -highlightbackground $Option(WinBackground)
balloon_add_help .b.prev "Go to previous month"
button .b.this -text {Today} -command {ThisMonth} -border 1 -foreground $Option(LabelColor) -background $Option(WinBackground)
button .b.this -text {Today} -command {ThisMonth} -bd 0 -foreground $Option(LabelColor) -background $Option(WinBackground) -highlightthickness 1 -highlightcolor $Option(LineColor) -highlightbackground $Option(WinBackground)
balloon_add_help .b.this "Go to this month"
button .b.next -text "\u2b9e" -command {MoveMonth 1} -border 1 -foreground $Option(LabelColor) -background $Option(WinBackground)
button .b.next -text "\u2b9e" -command {MoveMonth 1} -bd 0 -foreground $Option(LabelColor) -background $Option(WinBackground) -highlightthickness 1 -highlightcolor $Option(LineColor) -highlightbackground $Option(WinBackground)
balloon_add_help .b.next "Go to next month"
button .b.goto -text {Go To Date...} -command {GotoDialog} -border 1 -foreground $Option(LabelColor) -background $Option(WinBackground)
button .b.goto -text {Go To Date...} -command {GotoDialog} -bd 0 -foreground $Option(LabelColor) -background $Option(WinBackground) -highlightthickness 1 -highlightcolor $Option(LineColor) -highlightbackground $Option(WinBackground)
balloon_add_help .b.goto "Go to a specific date"
button .b.print -text {Print...} -command {DoPrint} -border 1 -foreground $Option(LabelColor) -background $Option(WinBackground)
balloon_add_help .b.print "Print a PostScript calendar"
button .b.queue -text {Queue...} -command {DoQueue} -border 1 -foreground $Option(LabelColor) -background $Option(WinBackground)
balloon_add_help .b.queue "See the queue of pending reminders (debugging purposes only)"
button .b.quit -text {Quit} -command {Quit} -border 1 -foreground $Option(LabelColor) -background $Option(WinBackground)
balloon_add_help .b.quit "Quit TkRemind"
button .b.options -text {Options...} -command EditOptions -border 1 -foreground $Option(LabelColor) -background $Option(WinBackground)
button .b.print -text {Print...} -command {DoPrint} -bd 0 -foreground $Option(LabelColor) -background $Option(WinBackground) -highlightthickness 1 -highlightcolor $Option(LineColor) -highlightbackground $Option(WinBackground)
balloon_add_help .b.print "Print a PostScript or PDF calendar"
button .b.options -text {Options...} -command EditOptions -bd 0 -foreground $Option(LabelColor) -background $Option(WinBackground) -highlightthickness 1 -highlightcolor $Option(LineColor) -highlightbackground $Option(WinBackground)
balloon_add_help .b.options "Set TkRemind options"
label .b.status -text "" -width 25 -relief sunken -border 1 -foreground $Option(LabelColor) -background $Option(WinBackground)
label .b.nqueued -text "" -width 20 -relief sunken -border 1 -foreground $Option(LabelColor) -background $Option(WinBackground)
pack .b.prev .b.this .b.next .b.goto .b.print .b.options .b.queue .b.quit -side left -fill both
pack .b.status -side left -fill both -expand 1
pack .b.nqueued -side left -fill both
pack .b -side bottom -fill x -expand 0
button .b.queue -text {Queue...} -command {DoQueue} -bd 0 -foreground $Option(LabelColor) -background $Option(WinBackground) -highlightthickness 1 -highlightcolor $Option(LineColor) -highlightbackground $Option(WinBackground)
balloon_add_help .b.queue "See the queue of pending reminders (debugging purposes only)"
button .b.quit -text {Quit} -command {Quit} -bd 0 -foreground $Option(LabelColor) -background $Option(WinBackground) -highlightthickness 1 -highlightcolor $Option(LineColor) -highlightbackground $Option(WinBackground)
balloon_add_help .b.quit "Quit TkRemind"
label .b.status -text "" -width 25 -relief flat -bd 0 -foreground $Option(LabelColor) -background $Option(WinBackground) -highlightthickness 0
label .b.nqueued -text "" -width 20 -relief flat -bd 0 -foreground $Option(LabelColor) -background $Option(WinBackground) -highlightthickness 0
pack .b.prev .b.this .b.next .b.goto .b.print .b.options .b.queue .b.quit -side left -fill both -padx 1
pack .b.status -side left -fill both -expand 1 -padx 1
pack .b.nqueued -side left -fill both -padx 1
pack .b -side bottom -fill x -expand 0 -pady 1
pack .cal -side top -fill both -expand 1
wm title . "TkRemind"
wm iconname . ""
@@ -689,7 +728,7 @@ proc EditOptions {} {
pack $w.cmd -in $w.rf -side left -expand 1 -fill x
$w.cmd insert 0 $tmpOpt(RunCmd)
frame $w.sep3 -border 1 -relief sunken
frame $w.sep3 -bd 1 -relief sunken
# E-mail reminder if popup not dismissed
frame $w.eml
label $w.lab_email_address -text "E-mail reminders here if popup not dismissed:" -anchor w -justify left
@@ -734,6 +773,12 @@ proc EditOptions {} {
label $w.bgcolor -text " Background color:"
button $w.bbgcolor -background $Option(BackgroundColor) -command [list PickColor BackgroundColor $w.bbgcolor] -text ...
label $w.tbgcolor -text "Color for highlighting \"today\":"
button $w.tbbgcolor -background $Option(TodayColor) -command [list PickColor TodayColor $w.tbbgcolor] -text ...
label $w.gridcolor -text " Gridline color:"
button $w.gridbcolor -background $Option(LineColor) -command [list PickColor LineColor $w.gridbcolor] -text ...
grid $w.textcolor $w.btextcolor $w.bgcolor $w.bbgcolor -in $w.colors1
grid $w.bgcolor $w.bbgcolor -in $w.colors1
@@ -742,22 +787,37 @@ proc EditOptions {} {
label $w.wincolor -text " Window color:"
button $w.bwincolor -background $Option(WinBackground) -command [list PickColor WinBackground $w.bwincolor] -text ...
grid $w.headcolor $w.bheadcolor $w.wincolor $w.bwincolor -in $w.colors1
grid $w.tbgcolor $w.tbbgcolor $w.gridcolor $w.gridbcolor -in $w.colors1
grid columnconfigure $w.colors1 0 -weight 1
grid columnconfigure $w.colors1 2 -weight 1
frame $w.sep1 -border 1 -relief sunken
frame $w.sep2 -border 1 -relief sunken
frame $w.sep1 -bd 1 -relief sunken
frame $w.sep2 -bd 1 -relief sunken
checkbutton $w.feed \
-text "Feed popped-up reminder to command's standard input" \
-variable tmpOpt(FeedReminder) -anchor w -justify left
frame $w.ancFrame
label $w.ancLabel -text "Anchor day numbers to:"
radiobutton $w.ancLeft \
-text "Left" \
-variable tmpOpt(DayAnchor) -value "w" -anchor w -justify left
radiobutton $w.ancCenter \
-text "Center" \
-variable tmpOpt(DayAnchor) -value "center" -anchor w -justify left
radiobutton $w.ancRight \
-text "Right" \
-variable tmpOpt(DayAnchor) -value "e" -anchor w -justify left
pack $w.ancLabel $w.ancLeft $w.ancCenter $w.ancRight -in $w.ancFrame -side left
pack $w.startIconified -in $w.f -side top -expand 0 -fill x
pack $w.showTodays -in $w.f -side top -expand 0 -fill x
pack $w.confirmQuit -in $w.f -side top -expand 0 -fill x
pack $w.bringDown -in $w.f -side top -expand 0 -fill x
pack $w.ring -in $w.f -side top -expand 0 -fill x
pack $w.deic -in $w.f -side top -expand 0 -fill x
pack $w.ancFrame -in $w.f -side top -expand 0 -fill x
pack $w.sep1 -in $w.f -side top -expand 0 -fill x -ipady 1
pack $w.rf -in $w.f -side top -expand 0 -fill x
pack $w.feed -in $w.f -side top -expand 0 -fill x
@@ -770,10 +830,12 @@ proc EditOptions {} {
pack $w.colors1 -in $w.f -side top -expand 0 -fill x
pack $w.sep2 -in $w.f -side top -expand 0 -fill x -ipady 1
button $w.default -text "Light Theme" -command [list set_default_colors $w]
button $w.dark -text "Dark Theme" -command [list set_dark_colors $w]
button $w.save -text "Save Options" -command "SaveOptions $w; destroy $w"
button $w.cancel -text "Cancel" -command "CancelOptions; destroy $w"
wm protocol $w WM_DELETE_WINDOW "CancelOptions; destroy $w"
pack $w.save $w.cancel -in $w.b -side left -expand 0 -fill x
pack $w.default $w.dark $w.save $w.cancel -in $w.b -side left -expand 0 -fill x
CenterWindow $w .
}
@@ -834,6 +896,13 @@ proc SaveOptions { w } {
for {set i 0} {$i < 7} {incr i} {
.cal.day$i configure -foreground $Option(LabelColor) -background $Option(WinBackground)
}
for {set i 0} {$i < 6} {incr i} {
set n [expr $i*7]
for {set j 0} {$j < 7} {incr j} {
set f [expr $n+$j]
.cal.l$f configure -anchor $Option(DayAnchor);
}
}
.b.status configure -foreground $Option(LabelColor) -background $Option(WinBackground)
.b.nqueued configure -foreground $Option(LabelColor) -background $Option(WinBackground)
.b configure -background $Option(WinBackground)
@@ -845,6 +914,10 @@ proc SaveOptions { w } {
.b.queue configure -foreground $Option(LabelColor) -background $Option(WinBackground)
.b.quit configure -foreground $Option(LabelColor) -background $Option(WinBackground)
.b.options configure -foreground $Option(LabelColor) -background $Option(WinBackground)
. configure -background $Option(LineColor);
.h configure -background $Option(LineColor);
.cal configure -background $Option(LineColor)
.b configure -background $Option(LineColor)
}
proc WriteOptionsToFile {} {
@@ -882,6 +955,7 @@ proc WriteOptionsToFile {} {
#***********************************************************************
proc LoadOptions {} {
global Option ConfigFile
global MondayFirst
set problem [catch {set f [open "$ConfigFile" "r"]}]
if {$problem} {
return
@@ -901,6 +975,9 @@ proc LoadOptions {} {
set Option($key) $val
}
close $f
if {[regexp -- {-m.*} $Option(ExtraRemindArgs)]} {
set MondayFirst 1
}
font configure CalboxFont {*}$Option(CalboxFont)
font configure HeadingFont {*}$Option(HeadingFont)
}
@@ -939,11 +1016,12 @@ proc ConfigureCalWindow { month year firstDay numDays } {
proc FillCalWindow {} {
set FileName ""
set LineNo 0
global DayNames CurYear CurMonth MonthNames CommandLine Option TagToObj
global DayNames CurYear CurMonth MonthNames CommandLine Option TagToObj RemindErrors MondayFirst
array unset TagToObj
Status "Firing off Remind..."
set_button_to_queue
set month [lindex $MonthNames $CurMonth]
set cmd [regsub EXTRA $CommandLine $Option(ExtraRemindArgs)]
@@ -977,7 +1055,12 @@ proc FillCalWindow {} {
# Update the day names in the calendar window
for {set i 0} {$i < 7} {incr i} {
.cal.day$i configure -text [lindex $DayNames $i]
if {$MondayFirst} {
set index [expr ($i+1)%7]
} else {
set index $i
}
.cal.day$i configure -text [lindex $DayNames $index]
}
set offset [CalEntryOffset $firstWkday]
@@ -1012,8 +1095,13 @@ proc FillCalWindow {} {
} else {
set tag "*"
}
set stuff [dict get $obj body]
if {[dict exists $obj calendar_body]} {
set stuff [dict get $obj calendar_body]
} elseif {[dict exists $obj plain_body]} {
set stuff [dict get $obj plain_body]
} else {
set stuff [dict get $obj body]
}
set day [string trimleft $day 0]
set n [expr $day+$offset]
set month [string trimleft $month 0]
@@ -1032,35 +1120,36 @@ proc FillCalWindow {} {
continue
}
"MOON" {
DoMoonSpecial $n $stuff $fntag
DoMoonSpecial $n $stuff $fntag $day
continue
}
"COLOUR" -
"COLOR" {
if {[regexp {^ *([0-9]+) +([0-9]+) +([0-9]+) +(.*)$} $stuff all r g b rest]} {
if {$r > 255} {
set r 255
} elseif {$r < 0} {
set r 0
}
if {$g > 255} {
set g 255
} elseif {$g < 0} {
set g 0
}
if {$b > 255} {
set b 255
} elseif {$b < 0} {
set b 0
}
set color [format "%02X%02X%02X" $r $g $b]
set extratags "clr$color"
.cal.t$n configure -state normal
.cal.t$n tag configure $extratags -foreground "#$color"
.cal.t$n configure -state disabled
set stuff $rest
set type "COLOR"
}
set r [dict get $obj r]
set g [dict get $obj g]
set b [dict get $obj b]
if {$r > 255} {
set r 255
} elseif {$r < 0} {
set r 0
}
if {$g > 255} {
set g 255
} elseif {$g < 0} {
set g 0
}
if {$b > 255} {
set b 255
} elseif {$b < 0} {
set b 0
}
set color [format "%02X%02X%02X" $r $g $b]
set extratags "clr$color"
.cal.t$n configure -state normal
.cal.t$n tag configure $extratags -foreground "#$color"
.cal.t$n configure -state disabled -takefocus 0
set stuff $stuff
set type "COLOR"
}
}
if { $type != "*" && $type != "COLOR" && $type != "COLOUR"} {
@@ -1083,16 +1172,27 @@ proc FillCalWindow {} {
}
}
.cal.t$n insert end "\n"
.cal.t$n configure -state disabled
.cal.t$n configure -state disabled -takefocus 0
}
set problem [catch { close $file } errmsg]
if {$problem} {
tk_dialog .error Error "There was a problem running Remind: $errmsg" error 0 OK
set RemindErrors [unique_lines $errmsg]
set_button_to_errors
}
DisplayTime
}
proc unique_lines { s } {
set l [split $s "\n"]
foreach line $l {
if {"$line" != ""} {
dict set d $line 1
}
}
return [join [dict keys $d] "\n"]
}
#---------------------------------------------------------------------------
# MoveMonth -- move by +1 or -1 months
# Arguments:
@@ -1152,13 +1252,13 @@ proc DoPrint {} {
toplevel .p
wm title .p "TkRemind Print..."
wm iconname .p "Print..."
frame .p.f1 -relief sunken -border 2
frame .p.f1 -relief sunken -bd 2
frame .p.f11
frame .p.f12
frame .p.f2 -relief sunken -border 2
frame .p.f2a -relief sunken -border 2
frame .p.f3 -relief sunken -border 2
frame .p.f3a -relief sunken -border 2
frame .p.f2 -relief sunken -bd 2
frame .p.f2a -relief sunken -bd 2
frame .p.f3 -relief sunken -bd 2
frame .p.f3a -relief sunken -bd 2
frame .p.f4
radiobutton .p.tofile -text "To file: " -variable Option(PrintDest) -value file
@@ -1169,7 +1269,7 @@ proc DoPrint {} {
.p.command insert end "lpr"
if { $HaveRem2PDF } {
frame .p.ff -relief sunken -border 2
frame .p.ff -relief sunken -bd 2
label .p.format -text "Output Format:"
radiobutton .p.pdf -text "PDF" -variable Option(PrintFormat) -value pdf
radiobutton .p.ps -text "PostScript" -variable Option(PrintFormat) -value ps
@@ -1451,16 +1551,16 @@ proc CreateModifyDialog {w day firstDay args} {
set month [lindex $MonthNames $CurMonth]
set wkday [lindex $EnglishDayNames [expr ($day+$firstDay-1) % 7]]
frame $w.o -border 4 -relief ridge
frame $w.o1 -border 4
frame $w.o2 -border 4
frame $w.o3 -border 4
frame $w.exp -border 4
frame $w.adv -border 4
frame $w.weekend -border 4
frame $w.durationbox -border 4
frame $w.time -border 4
frame $w.hol -border 4
frame $w.o -bd 4 -relief ridge
frame $w.o1 -bd 4
frame $w.o2 -bd 4
frame $w.o3 -bd 4
frame $w.exp -bd 4
frame $w.adv -bd 4
frame $w.weekend -bd 4
frame $w.durationbox -bd 4
frame $w.time -bd 4
frame $w.hol -bd 4
frame $w.msg
frame $w.buttons
pack $w.o1 $w.o2 $w.o3 -side top -anchor w -in $w.o
@@ -2016,7 +2116,7 @@ proc CreateReminder {w} {
# Check it out!
global Remind
set f [open "|$Remind -arq -e - 2>&1" r+]
set f [open "|$Remind -arq -e - 2>@1" r+]
puts $f "BANNER %"
puts $f "$rem MSG %"
puts $f "MSG %_%_%_%_"
@@ -3530,7 +3630,7 @@ proc DoShadeSpecial { n r g b } {
# %DESCRIPTION:
# Handles the "MOON" special -- draws a moon symbol
#***********************************************************************
proc DoMoonSpecial { n stuff fntag } {
proc DoMoonSpecial { n stuff fntag day } {
set msg ""
set num [scan $stuff "%d %d %d %s" phase junk1 junk2 msg]
if {$num < 1} {
@@ -3539,12 +3639,24 @@ proc DoMoonSpecial { n stuff fntag } {
if {$phase < 0 || $phase > 3} {
return
}
switch -exact -- $phase {
0 { set win .moon_new }
1 { set win .moon_first }
2 { set win .moon_full }
3 { set win .moon_last }
0 { set win .moon_new }
1 { set win .moon_first }
2 { set win .moon_full }
3 { set win .moon_last }
}
# We need two sets of moon phase windows. There can be
# two of a given phase in the same month, but Tk does
# not allow the same embedded window in two separate
# text boxes. So we use this hack to make sure
# we use a different window if the same moon phase
# happens twice in a month.
if {$day > 16} {
append win "2"
}
.cal.t$n configure -state normal
.cal.t$n window create 1.0 -window $win
@@ -3569,7 +3681,7 @@ proc DoMoonSpecial { n stuff fntag } {
.cal.t$n tag bind $fntag <ButtonPress-1> "FireEditor .cal.t$n $fntag"
}
}
.cal.t$n configure -state disabled
.cal.t$n configure -state disabled -takefocus 0
}
#***********************************************************************
# %PROCEDURE: DisplayTime
@@ -3607,8 +3719,12 @@ proc CreateMoonWindows {} {
catch { destroy .moon_full }
catch { destroy .moon_last }
catch { destroy .moon_new2 }
catch { destroy .moon_first2}
catch { destroy .moon_full2 }
catch { destroy .moon_last2 }
set extra 1
#set wid [font measure CalboxFont 0]
set wid [font metrics CalboxFont -ascent]
set orig_wid $wid
incr wid $extra
@@ -3619,24 +3735,32 @@ proc CreateMoonWindows {} {
incr orig_wid $extra
set w [expr $extra+$orig_wid]
canvas .moon_new -background $Option(BackgroundColor) -width $wid -height $wid -borderwidth 0 -highlightthickness 0
.moon_new create oval $extra $extra $w $w -outline $Option(TextColor) -width 1
canvas .moon_first -background $Option(BackgroundColor) -width $wid -height $wid -borderwidth 0 -highlightthickness 0
.moon_first create oval $extra $extra $w $w -outline $Option(TextColor) -width 1
.moon_first create arc $extra $extra $w $w -outline $Option(TextColor) -fill $Option(TextColor) -start 90 -extent 180 -outline {}
foreach win {.moon_new .moon_new2 } {
canvas $win -background $Option(BackgroundColor) -width $wid -height $wid -borderwidth 0 -highlightthickness 0
$win create oval $extra $extra $w $w -outline $Option(TextColor) -width 1
balloon_add_help $win "New Moon"
}
canvas .moon_full -background $Option(BackgroundColor) -width $wid -height $wid -borderwidth 0 -highlightthickness 0
.moon_full create oval $extra $extra $w $w -outline $Option(TextColor) -fill $Option(TextColor) -width 1
foreach win {.moon_first .moon_first2 } {
canvas $win -background $Option(BackgroundColor) -width $wid -height $wid -borderwidth 0 -highlightthickness 0
$win create oval $extra $extra $w $w -outline $Option(TextColor) -width 1
$win create arc $extra $extra $w $w -outline $Option(TextColor) -fill $Option(TextColor) -start 90 -extent 180 -outline {}
balloon_add_help $win "First Quarter"
}
canvas .moon_last -background $Option(BackgroundColor) -width $wid -height $wid -borderwidth 0 -highlightthickness 0
.moon_last create oval $extra $extra $w $w -outline $Option(TextColor) -width 1
.moon_last create arc $extra $extra $w $w -outline $Option(TextColor) -fill $Option(TextColor) -start 270 -extent 180 -outline {}
foreach win {.moon_full .moon_full2 } {
canvas $win -background $Option(BackgroundColor) -width $wid -height $wid -borderwidth 0 -highlightthickness 0
$win create oval $extra $extra $w $w -outline $Option(TextColor) -fill $Option(TextColor) -width 1
balloon_add_help $win "Full Moon"
}
balloon_add_help .moon_new "New Moon"
balloon_add_help .moon_first "First Quarter"
balloon_add_help .moon_full "Full Moon"
balloon_add_help .moon_last "Last Quarter"
foreach win {.moon_last .moon_last2 } {
canvas $win -background $Option(BackgroundColor) -width $wid -height $wid -borderwidth 0 -highlightthickness 0
$win create oval $extra $extra $w $w -outline $Option(TextColor) -width 1
$win create arc $extra $extra $w $w -outline $Option(TextColor) -fill $Option(TextColor) -start 270 -extent 180 -outline {}
balloon_add_help $win "Last Quarter"
}
}
#***********************************************************************
@@ -3996,4 +4120,72 @@ proc FindConfigFile {} {
set ConfigFile "~/.tkremindrc"
}
proc set_default_colors { w } {
global tmpOpt
set tmpOpt(BackgroundColor) "#d9d9d9"
set tmpOpt(LabelColor) "#000000"
set tmpOpt(LineColor) "#000000"
set tmpOpt(TextColor) "#000000"
set tmpOpt(TodayColor) "#00C0C0"
set tmpOpt(WinBackground) "#d9d9d9"
update_color_buttons $w
}
proc set_dark_colors { w } {
global tmpOpt
set tmpOpt(BackgroundColor) "#000000"
set tmpOpt(LabelColor) "#00ffff"
set tmpOpt(LineColor) "#0080fc"
set tmpOpt(TextColor) "#ffffff"
set tmpOpt(TodayColor) "#b000b6"
set tmpOpt(WinBackground) "#000000"
update_color_buttons $w
}
proc update_color_buttons { w } {
global tmpOpt
$w.bbgcolor configure -background $tmpOpt(BackgroundColor)
$w.bheadcolor configure -background $tmpOpt(LabelColor)
$w.gridbcolor configure -background $tmpOpt(LineColor)
$w.btextcolor configure -background $tmpOpt(TextColor)
$w.tbbgcolor configure -background $tmpOpt(TodayColor)
$w.bwincolor configure -background $tmpOpt(WinBackground)
}
proc set_button_to_queue {} {
.b.queue configure -text {Queue...} -command {DoQueue}
}
proc set_button_to_errors {} {
.b.queue configure -text {Errors...} -command {ShowErrors}
}
proc ShowErrors {} {
global RemindErrors
set w ".errors"
catch { destroy $w }
toplevel $w
text $w.t -width 80 -height 30 -wrap word -yscrollcommand "$w.sb set"
scrollbar $w.sb -orient vertical -command "$w.t yview"
button $w.ok -text OK -command DoneShowingErrors
grid $w.t -row 0 -column 0 -sticky nsew
grid $w.sb -row 0 -column 1 -sticky ns
grid $w.ok -row 1 -column 0 -stick w
grid columnconfigure $w 0 -weight 1
grid columnconfigure $w 1 -weight 0
grid rowconfigure $w 0 -weight 1
grid rowconfigure $w 1 -weight 0
$w.t insert end $RemindErrors
$w.t configure -state disabled
CenterWindow $w .
}
proc DoneShowingErrors {} {
global RemindErrors
set RemindErrors {}
set_button_to_queue
destroy .errors
}
# Rem2PS program to execute -- supply full path if you want
main

View File

@@ -36,21 +36,21 @@ REMINDOBJS= $(REMINDSRCS:.c=.o)
all: remind rem2ps
test: remind
test: all
@sh ../tests/test-rem
.c.o:
@CC@ -c @CPPFLAGS@ @CFLAGS@ @DEFS@ $(CEXTRA) $(LANGDEF) -I. -I$(srcdir) $<
@CC@ -c @CPPFLAGS@ @CFLAGS@ @DEFS@ $(CEXTRA) $(LANGDEF) -DSYSDIR=$(datarootdir)/remind -I. -I$(srcdir) $<
$(REMINDOBJS): $(REMINDHDRS)
rem2ps: rem2ps.o dynbuf.o json.o
@CC@ @LDFLAGS@ $(LDEXTRA) -o rem2ps rem2ps.o dynbuf.o json.o -lm
@CC@ @CFLAGS@ @LDFLAGS@ $(LDEXTRA) -o rem2ps rem2ps.o dynbuf.o json.o -lm
remind: $(REMINDOBJS)
@CC@ @LDFLAGS@ $(LDEXTRA) -o remind $(REMINDOBJS) @LIBS@
@CC@ @CFLAGS@ @LDFLAGS@ $(LDEXTRA) -o remind $(REMINDOBJS) @LIBS@
install-nostripped: all
install: all
-mkdir -p $(DESTDIR)$(bindir) || true
for prog in $(PROGS) $(SCRIPTS) ; do \
$(INSTALL_PROGRAM) $$prog $(DESTDIR)$(bindir) || exit 1; \
@@ -61,8 +61,10 @@ install-nostripped: all
for man in $(MANS) ; do \
$(INSTALL_DATA) $$man $(DESTDIR)$(mandir)/man1 || exit 1; \
done
-mkdir -p $(DESTDIR)$(datarootdir)/remind || true
cp -R ../include/* $(DESTDIR)$(datarootdir)/remind
install: install-nostripped
install-stripped: install
strip $(DESTDIR)$(bindir)/remind || true
strip $(DESTDIR)$(bindir)/rem2ps || true

View File

@@ -5,16 +5,17 @@
/* The code for generating a calendar. */
/* */
/* This file is part of REMIND. */
/* Copyright (C) 1992-2021 by Dianne Skoll */
/* Copyright (C) 1992-2022 by Dianne Skoll */
/* */
/***************************************************************/
#define _XOPEN_SOURCE
#define _XOPEN_SOURCE 600
#include "config.h"
#include "custom.h"
#include <stdio.h>
#include <string.h>
#include <strings.h>
#include <ctype.h>
#include <stdlib.h>
@@ -26,6 +27,11 @@
#include <wchar.h>
#endif
#ifdef HAVE_LANGINFO_H
#include <langinfo.h>
#endif
#include "lang.h"
#include "types.h"
#include "protos.h"
#include "expr.h"
@@ -75,6 +81,8 @@ static struct line_drawing VT100Drawing = {
"\x6c", "\x74", "\x6a", "\x71"
};
static int encoding_is_utf8 = 0;
static struct line_drawing UTF8Drawing = {
"", "",
"\xe2\x94\xb4",
@@ -139,6 +147,47 @@ static char *VT100Colors[2][2][2][2] /* [Br][R][G][B] */ = {
}
};
static char *VT100BGColors[2][2][2] /* [R][G][B] */ = {
{
{
/* 0, 0, 0 = Black */ "\x1B[0;40m",
/* 0, 0, 1 = Blue */ "\x1B[0;44m"
},
{
/* 0, 1, 0 = Green */ "\x1B[0;42m",
/* 0, 1, 1 = Cyan */ "\x1B[0;46m"
}
},
{
{
/* 1, 0, 0 = Red */ "\x1B[0;41m",
/* 1, 0, 1 = Magenta */ "\x1B[0;45m"
},
{
/* 1, 1, 0 = Yellow */ "\x1B[0;43m",
/* 1, 1, 1 = White */ "\x1B[0;47m"
}
}
};
/* Moon phase icons in UTF-8 */
static char const *moonphase_emojis[] = {
"\xF0\x9F\x8C\x91",
"\xF0\x9F\x8C\x93",
"\xF0\x9F\x8C\x95",
"\xF0\x9F\x8C\x97"
};
/* Moon phases for each day 1-31, up to 32 chars per moon-phase string
including termination \0 */
static char moons[32][32];
/* Week indicators */
static char weeks[32][32];
/* Background colors of each day 1-31, rgb */
static int bgcolor[32][3];
static struct line_drawing *linestruct;
#define DRAW(x) fputs(linestruct->x, stdout)
@@ -221,13 +270,14 @@ static struct xterm256_colors XTerm256Colors[] =
/* Global variables */
static CalEntry *CalColumn[7];
static int ColToDay[7];
static int ColSpaces;
static int DidAMonth;
static int DidADay;
static void ColorizeEntry(CalEntry const *e);
static void ColorizeEntry(CalEntry const *e, int clamp);
static void SortCol (CalEntry **col);
static void DoCalendarOneWeek (int nleft);
static void DoCalendarOneMonth (void);
@@ -236,7 +286,7 @@ 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 int WriteOneCalLine (void);
static int WriteOneCalLine (int jul, int wd);
static int WriteOneColLine (int col);
static void GenerateCalEntries (int col);
static void WriteCalHeader (void);
@@ -248,6 +298,61 @@ static void WriteBottomCalLine (void);
static void WriteIntermediateCalLine (void);
static void WriteCalDays (void);
static int
DayOf(int jul)
{
int d;
FromJulian(jul, NULL, NULL, &d);
return d;
}
static void
Backgroundize(int d)
{
if (d < 1 || d > 31) {
return;
}
if (!UseBGVTColors) {
return;
}
if (bgcolor[d][0] < 0) {
return;
}
printf("%s", Colorize(bgcolor[d][0], bgcolor[d][1], bgcolor[d][2], 1, 0));
}
static void
UnBackgroundize(int d)
{
if (d < 1 || d > 31) {
return;
}
if (!UseBGVTColors) {
return;
}
if (bgcolor[d][0] < 0) {
return;
}
printf("%s", Decolorize());
}
static void
send_lrm(void)
{
/* Don't send LRM if SuppressLRM is set */
if (SuppressLRM) {
return;
}
/* Send a lrm control sequence if UseUTF8Chars is enabled
or char encoding is UTF-8
*/
if (UseUTF8Chars || encoding_is_utf8) {
printf("\xE2\x80\x8E");
}
}
static char const *
despace(char const *s)
{
@@ -270,6 +375,19 @@ despace(char const *s)
return buf;
}
void PrintJSONChar(char c) {
switch(c) {
case '\b': printf("\\b"); break;
case '\f': printf("\\f"); break;
case '\n': printf("\\n"); break;
case '\r': printf("\\r"); break;
case '\t': printf("\\t"); break;
case '"': printf("\\\""); break;
case '\\': printf("\\\\"); break;
default: printf("%c", c);
}
}
void PrintJSONString(char const *s)
{
while (*s) {
@@ -356,7 +474,7 @@ void PrintJSONKeyPairTime(char const *name, int t)
}
#ifdef REM_USE_WCHAR
static void PutWideChar(wchar_t const wc)
void PutWideChar(wchar_t const wc)
{
char buf[MB_CUR_MAX+1];
int len;
@@ -474,16 +592,13 @@ ClampColor(int *r, int *g, int *b)
}
char const *
Decolorize(int r, int g, int b)
Decolorize(void)
{
if (!strcmp(Colorize(r, g, b), "")) {
return "";
}
return "\x1B[0m";
}
static char const *
Colorize256(int r, int g, int b)
Colorize256(int r, int g, int b, int bg, int clamp)
{
static char buf[40];
int best = -1;
@@ -492,7 +607,9 @@ Colorize256(int r, int g, int b)
struct xterm256_colors *cur;
size_t i;
ClampColor(&r, &g, &b);
if (clamp) {
ClampColor(&r, &g, &b);
}
for (i=0; i<(sizeof(XTerm256Colors) / sizeof(XTerm256Colors[0])); i++) {
cur = &XTerm256Colors[i];
dist = ((r - cur->r) * (r - cur->r)) +
@@ -504,31 +621,42 @@ Colorize256(int r, int g, int b)
}
}
cur = &XTerm256Colors[best];
sprintf(buf, "\x1B[38;5;%dm", best);
if (bg) {
sprintf(buf, "\x1B[48;5;%dm", best);
} else {
sprintf(buf, "\x1B[38;5;%dm", best);
}
return buf;
}
static char const *
ColorizeTrue(int r, int g, int b)
ColorizeTrue(int r, int g, int b, int bg, int clamp)
{
static char buf[40];
ClampColor(&r, &g, &b);
sprintf(buf, "\x1B[38;2;%d;%d;%dm", r, g, b);
if (clamp) {
ClampColor(&r, &g, &b);
}
if (bg) {
sprintf(buf, "\x1B[48;2;%d;%d;%dm", r, g, b);
} else {
sprintf(buf, "\x1B[38;2;%d;%d;%dm", r, g, b);
}
return buf;
}
char const *
Colorize(int r, int g, int b)
Colorize(int r, int g, int b, int bg, int clamp)
{
int bright = 0;
if (UseTrueColors) {
return ColorizeTrue(r, g, b);
return ColorizeTrue(r, g, b, bg, clamp);
}
if (Use256Colors) {
return Colorize256(r, g, b);
return Colorize256(r, g, b, bg, clamp);
}
if (r > 128 || g > 128 || b > 128) {
bright = 1;
}
@@ -539,43 +667,112 @@ Colorize(int r, int g, int b)
if (b > 64) b = 1;
else b = 0;
if (TerminalBackground == TERMINAL_BACKGROUND_DARK) {
if (clamp && TerminalBackground == TERMINAL_BACKGROUND_DARK && !bg) {
/* Convert black-on-black to grey */
if (!r && !g && !b) return VT100Colors[1][0][0][0];
}
if (TerminalBackground == TERMINAL_BACKGROUND_LIGHT) {
if (clamp && TerminalBackground == TERMINAL_BACKGROUND_LIGHT && !bg) {
/* Convert white-on-white to grey */
if (r && g && b) return VT100Colors[1][0][0][0];
}
return VT100Colors[bright][r][g][b];
if (bg) {
return VT100BGColors[r][g][b];
} else {
return VT100Colors[bright][r][g][b];
}
}
static void ColorizeEntry(CalEntry const *e)
static void ColorizeEntry(CalEntry const *e, int clamp)
{
printf("%s", Colorize(e->r, e->g, e->b));
printf("%s", Colorize(e->r, e->g, e->b, 0, clamp));
}
static int
ComputeCalWidth(int x)
static void
InitMoonsAndShades(void)
{
struct winsize w;
if (x >= 71) {
/* Has been set with -w option */
return x;
int i;
/* Initialize the moon array */
if (encoding_is_utf8) {
for (i=0; i<=31; i++) {
moons[i][0] = 0;
}
}
if (!isatty(STDOUT_FILENO)) {
/* Output is not a TTY... assume 80 */
return 80;
/* Clear SHADEs */
if (UseBGVTColors) {
for (i=0; i<=31; i++) {
bgcolor[i][0] = -1;
bgcolor[i][1] = -1;
bgcolor[i][2] = -1;
}
}
if (ioctl(STDOUT_FILENO, TIOCGWINSZ, &w) < 0) {
return 80;
/* Clear weeks */
for(i=0; i<=31; i++) {
weeks[i][0] = 0;
}
if (w.ws_col < 71) {
return 71;
}
return w.ws_col;
}
static void
SetShadeEntry(int jul, char const *shade)
{
int y, m, d;
int r, g, b;
/* Don't bother if we're not doing SHADE specials */
if (!UseBGVTColors) {
return;
}
if (sscanf(shade, "%d %d %d", &r, &g, &b) != 3) {
if (sscanf(shade, "%d", &r) != 1) {
return;
}
g = r;
b = r;
}
if (r < 0 || g < 0 || b < 0 || r > 255 || g > 255 || b > 255) {
return;
}
FromJulian(jul, &y, &m, &d);
bgcolor[d][0] = r;
bgcolor[d][1] = g;
bgcolor[d][2] = b;
}
static void
SetMoonEntry(int jul, char const *moon)
{
int phase;
int y, m, d;
char msg[28];
/* Don't bother unless it's utf-8 */
if (!encoding_is_utf8) {
return;
}
msg[0] = 0;
if (sscanf(moon, "%d %*d %*d %27[^\x01]", &phase, msg) < 4) {
if (sscanf(moon, "%d", &phase) != 1) {
/* Malformed MOON special; ignore */
fprintf(stderr, "Oops 1\n");
return;
}
}
if (phase < 0 || phase > 3) {
/* Bad phase */
fprintf(stderr, "Oops 2\n");
return;
}
FromJulian(jul, &y, &m, &d);
if (msg[0]) {
snprintf(moons[d], sizeof(moons[d]), "%s %s", moonphase_emojis[phase], msg);
} else {
snprintf(moons[d], sizeof(moons[d]), "%s", moonphase_emojis[phase]);
}
}
/***************************************************************/
/* */
/* ProduceCalendar */
@@ -587,6 +784,14 @@ void ProduceCalendar(void)
{
int y, m, d;
/* Check if current locale is UTF-8, if we have langinfo.h */
#ifdef HAVE_LANGINFO_H
char const *encoding = nl_langinfo(CODESET);
if (!strcasecmp(encoding, "utf-8")) {
encoding_is_utf8 = 1;
}
#endif
if (UseUTF8Chars) {
linestruct = &UTF8Drawing;
} else if (UseVTChars) {
@@ -596,8 +801,6 @@ void ProduceCalendar(void)
}
ShouldCache = 1;
CalWidth = ComputeCalWidth(CalWidth);
ColSpaces = (CalWidth - 9) / 7;
CalWidth = 7*ColSpaces + 8;
@@ -650,18 +853,22 @@ static void DoCalendarOneWeek(int nleft)
int LinesWritten = 0;
int OrigJul = JulianToday;
InitMoonsAndShades();
/* Fill in the column entries */
for (i=0; i<7; i++) {
ColToDay[i] = DayOf(JulianToday);
GenerateCalEntries(i);
JulianToday++;
}
/* Output the entries */
/* Figure out weekday of first column */
if (MondayFirst) wd = JulianToday % 7;
else wd = (JulianToday + 1) % 7;
/* Output the entries */
/* If it's "Simple Calendar" format, do it simply... */
if (DoSimpleCalendar) {
if (MondayFirst) wd = JulianToday % 7;
else wd = (JulianToday + 1) % 7;
for (i=0; i<7; i++) {
WriteSimpleEntries(i, OrigJul+i-wd);
}
@@ -673,13 +880,33 @@ static void DoCalendarOneWeek(int nleft)
DRAW(tb);
goff();
for (i=0; i<7; i++) {
FromJulian(OrigJul+i, &y, &m, &d);
FromJulian(OrigJul+i, &y, &m, &d);
char const *mon = get_month_name(m);
snprintf(buf, sizeof(buf), "%d %s ", d, get_month_abbrev(mon));
if (OrigJul+i == RealToday)
PrintLeft(buf, ColSpaces, '*');
else
if (moons[d][0]) {
if (weeks[d][0]) {
snprintf(buf, sizeof(buf), "%d %s %s %s ", d, get_month_abbrev(mon), weeks[d], moons[d]);
} else {
snprintf(buf, sizeof(buf), "%d %s %s ", d, get_month_abbrev(mon), moons[d]);
}
} else {
if (weeks[d][0]) {
snprintf(buf, sizeof(buf), "%d %s %s ", d, get_month_abbrev(mon), weeks[d]);
} else {
snprintf(buf, sizeof(buf), "%d %s ", d, get_month_abbrev(mon));
}
}
if (OrigJul+i == RealToday) {
if (UseVTColors) {
printf("\x1B[1m"); /* Bold */
}
PrintLeft(buf, ColSpaces-1, '*');
if (UseVTColors) {
printf("\x1B[0m"); /* Normal */
}
putchar(' ');
} else {
PrintLeft(buf, ColSpaces, ' ');
}
gon();
DRAW(tb);
goff();
@@ -690,7 +917,10 @@ static void DoCalendarOneWeek(int nleft)
DRAW(tb);
goff();
for (i=0; i<7; i++) {
d = ColToDay[i];
Backgroundize(d);
PrintLeft("", ColSpaces, ' ');
UnBackgroundize(d);
gon();
DRAW(tb);
goff();
@@ -701,7 +931,7 @@ static void DoCalendarOneWeek(int nleft)
/* Write the body lines */
done = 0;
while (!done) {
done = WriteOneCalLine();
done = WriteOneCalLine(OrigJul, wd);
LinesWritten++;
}
@@ -711,7 +941,10 @@ static void DoCalendarOneWeek(int nleft)
DRAW(tb);
goff();
for (i=0; i<7; i++) {
d = ColToDay[i];
Backgroundize(d);
PrintLeft("", ColSpaces, ' ');
UnBackgroundize(d);
gon();
DRAW(tb);
goff();
@@ -738,6 +971,8 @@ static void DoCalendarOneMonth(void)
{
int y, m, d, mm, yy, i, j;
InitMoonsAndShades();
if (!DoSimpleCalendar) WriteCalHeader();
DidADay = 0;
@@ -838,10 +1073,15 @@ static int WriteCalendarRow(void)
if (!MondayFirst) wd = (JulianToday + 1) % 7;
else wd = JulianToday % 7;
for (i=0; i<7; i++) {
ColToDay[i] = 0;
}
/* Fill in the column entries */
for (i=wd; i<7; i++) {
if (d+i-wd > DaysInMonth(m, y)) break;
GenerateCalEntries(i);
ColToDay[i] = DayOf(JulianToday);
JulianToday++;
}
@@ -864,9 +1104,27 @@ static int WriteCalendarRow(void)
if (i < wd || d+i-wd>DaysInMonth(m, y))
PrintLeft("", ColSpaces, ' ');
else {
sprintf(buf, "%d ", d+i-wd);
if (moons[d+i-wd][0]) {
if (weeks[d+i-wd][0]) {
snprintf(buf, sizeof(buf), "%d %s %s ", d+i-wd, weeks[d+i-wd], moons[d+i-wd]);
} else {
snprintf(buf, sizeof(buf), "%d %s ", d+i-wd, moons[d+i-wd]);
}
} else {
if (weeks[d+i-wd][0]) {
snprintf(buf, sizeof(buf), "%d %s ", d+i-wd, weeks[d+i-wd]);
} else {
snprintf(buf, sizeof(buf), "%d ", d+i-wd);
}
}
if (Julian(y, m, d+i-wd) == RealToday) {
if (UseVTColors) {
printf("\x1B[1m"); /* Bold */
}
PrintLeft(buf, ColSpaces-1, '*');
if (UseVTColors) {
printf("\x1B[0m"); /* Normal */
}
putchar(' ');
} else {
PrintLeft(buf, ColSpaces, ' ');
@@ -882,7 +1140,9 @@ static int WriteCalendarRow(void)
DRAW(tb);
goff();
for (i=0; i<7; i++) {
Backgroundize(ColToDay[i]);
PrintLeft("", ColSpaces, ' ');
UnBackgroundize(ColToDay[i]);
gon();
DRAW(tb);
goff();
@@ -893,7 +1153,7 @@ static int WriteCalendarRow(void)
/* Write the body lines */
done = 0;
while (!done) {
done = WriteOneCalLine();
done = WriteOneCalLine(OrigJul, wd);
LinesWritten++;
}
@@ -903,7 +1163,9 @@ static int WriteCalendarRow(void)
DRAW(tb);
goff();
for (i=0; i<7; i++) {
Backgroundize(ColToDay[i]);
PrintLeft("", ColSpaces, ' ');
UnBackgroundize(ColToDay[i]);
gon();
DRAW(tb);
goff();
@@ -975,6 +1237,10 @@ static void PrintLeft(char const *s, int width, char pad)
while (*ws && wcwidth(*ws) == 0) {
PutWideChar(*ws++);
}
/* Possibly send lrm control sequence */
send_lrm();
for (i=display_len; i<width; i++) fputc(pad, stdout);
if (buf != static_buf) free(buf);
#endif
@@ -1055,6 +1321,9 @@ static void PrintCentered(char const *s, int width, char *pad)
while (*ws && wcwidth(*ws) == 0) {
PutWideChar(*ws++);
}
/* Possibly send lrm control sequence */
send_lrm();
for (i=d+display_len; i<width; i++) fputs(pad, stdout);
if (buf != static_buf) free(buf);
#endif
@@ -1067,19 +1336,25 @@ static void PrintCentered(char const *s, int width, char *pad)
/* Write a single line. */
/* */
/***************************************************************/
static int WriteOneCalLine(void)
static int WriteOneCalLine(int start_jul, int wd)
{
int done = 1, i;
int y, m, d;
gon();
DRAW(tb);
goff();
for (i=0; i<7; i++) {
FromJulian(start_jul+i, &y, &m, &d);
d -= wd;
if (CalColumn[i]) {
Backgroundize(ColToDay[i]);
if (WriteOneColLine(i)) done = 0;
} else {
Backgroundize(ColToDay[i]);
PrintCentered("", ColSpaces, " ");
}
UnBackgroundize(ColToDay[i]);
gon();
DRAW(tb);
goff();
@@ -1089,7 +1364,6 @@ static int WriteOneCalLine(void)
return done;
}
/***************************************************************/
/* */
/* WriteOneColLine */
@@ -1109,9 +1383,12 @@ static int WriteOneColLine(int col)
wchar_t const *wspace;
int width;
#endif
int clamp = 1;
int numwritten = 0;
int d = ColToDay[col];
if (d && UseBGVTColors && bgcolor[d][0] != -1) {
clamp = 0;
}
/* Print as many characters as possible within the column */
#ifdef REM_USE_WCHAR
if (e->wc_text) {
@@ -1140,27 +1417,35 @@ static int WriteOneColLine(int col)
}
if (iswspace(*ws)) {
wspace = ws;
}
if (wcwidth(*ws)) {
width++;
} else {
if (wcwidth(*ws)) {
width += wcwidth(*ws);
if (width > ColSpaces) {
break;
}
}
}
ws++;
}
/* Colorize reminder if necessary */
if (UseVTColors && e->is_color) {
ColorizeEntry(e);
ColorizeEntry(e, clamp);
}
/* If we couldn't find a space char, print what we have. */
if (!wspace) {
for (ws = e->wc_pos; ws - e->wc_pos < ColSpaces; ws++) {
for (ws = e->wc_pos; numwritten < ColSpaces; ws++) {
if (!*ws) break;
if (iswspace(*ws)) {
putchar(' ');
numwritten++;
} else {
if (wcwidth(*ws) > 0) {
if (numwritten + wcwidth(*ws) > ColSpaces) {
break;
}
numwritten += wcwidth(*ws);
}
PutWideChar(*ws);
@@ -1183,11 +1468,15 @@ static int WriteOneColLine(int col)
}
}
/* Decolorize reminder if necessary */
/* Decolorize reminder if necessary, but keep any SHADE */
if (UseVTColors && e->is_color) {
printf("%s", Decolorize(e->r, e->g, e->b));
printf("%s", Decolorize());
Backgroundize(d);
}
/* Possibly send lrm control sequence */
send_lrm();
/* Flesh out the rest of the column */
while(numwritten++ < ColSpaces) putchar(' ');
@@ -1235,7 +1524,7 @@ static int WriteOneColLine(int col)
/* Colorize reminder if necessary */
if (UseVTColors && e->is_color) {
ColorizeEntry(e);
ColorizeEntry(e, clamp);
}
/* If we couldn't find a space char, print what we have. */
@@ -1263,9 +1552,10 @@ static int WriteOneColLine(int col)
}
}
/* Decolorize reminder if necessary */
/* Decolorize reminder if necessary, but keep SHADE */
if (UseVTColors && e->is_color) {
printf("%s", Decolorize(e->r, e->g, e->b));
printf("%s", Decolorize());
Backgroundize(d);
}
/* Flesh out the rest of the column */
@@ -1359,6 +1649,7 @@ static void GenerateCalEntries(int col)
case T_Exit: DoExit(&p); break;
case T_Set: r=DoSet(&p); break;
case T_Fset: r=DoFset(&p); break;
case T_Funset: r=DoFunset(&p); break;
case T_UnSet: r=DoUnset(&p); break;
case T_Clr: r=DoClear(&p); break;
case T_Flush: r=DoFlush(&p); break;
@@ -1539,6 +1830,19 @@ static int DoCalRem(ParsePtr p, int col)
DBufFree(&buf);
}
trig.typ = tok.val;
if (trig.typ == MSG_TYPE ||
trig.typ == CAL_TYPE ||
trig.typ == MSF_TYPE) {
is_color = (
DefaultColorR != -1
&& DefaultColorG != -1
&& DefaultColorB != -1);
if (is_color) {
col_r = DefaultColorR;
col_g = DefaultColorG;
col_b = DefaultColorB;
}
}
jul = LastTriggerDate;
if (!LastTrigValid) {
FreeTrig(&trig);
@@ -1602,10 +1906,49 @@ static int DoCalRem(ParsePtr p, int col)
}
}
if (trig.typ == PASSTHRU_TYPE) {
if (!PsCal && StrCmpi(trig.passthru, "COLOR") && StrCmpi(trig.passthru, "COLOUR")) {
if (!PsCal && !StrCmpi(trig.passthru, "SHADE")) {
if (jul == JulianToday) {
DBufInit(&obuf);
r = DoSubst(p, &obuf, &trig, &tim, jul, CAL_MODE);
if (r) {
DBufFree(&obuf);
FreeTrig(&trig);
return r;
}
SetShadeEntry(jul, DBufValue(&obuf));
DBufFree(&obuf);
}
}
if (!PsCal && !StrCmpi(trig.passthru, "WEEK")) {
if (jul == JulianToday) {
DBufInit(&obuf);
r = DoSubst(p, &obuf, &trig, &tim, jul, CAL_MODE);
if (r) {
DBufFree(&obuf);
FreeTrig(&trig);
return r;
}
sscanf(DBufValue(&obuf), "%31[^\x01]", weeks[DayOf(jul)]);
DBufFree(&obuf);
}
}
if (!PsCal && StrCmpi(trig.passthru, "COLOR") && StrCmpi(trig.passthru, "COLOUR") && StrCmpi(trig.passthru, "MOON")) {
FreeTrig(&trig);
return OK;
}
if (!PsCal && !StrCmpi(trig.passthru, "MOON")) {
if (jul == JulianToday) {
DBufInit(&obuf);
r = DoSubst(p, &obuf, &trig, &tim, jul, CAL_MODE);
if (r) {
DBufFree(&obuf);
FreeTrig(&trig);
return r;
}
SetMoonEntry(jul, DBufValue(&obuf));
DBufFree(&obuf);
}
}
if (!StrCmpi(trig.passthru, "COLOR") ||
!StrCmpi(trig.passthru, "COLOUR")) {
is_color = 1;
@@ -1824,6 +2167,13 @@ static int DoCalRem(ParsePtr p, int col)
e->next = CurCol;
CalColumn[col] = e;
SortCol(&CalColumn[col]);
} else {
/* Parse the rest of the line to catch expression-pasting errors */
while (ParseChar(p, &r, 0)) {
if (r != 0) {
return r;
}
}
}
return OK;
}
@@ -1857,6 +2207,7 @@ static void WriteSimpleEntryProtocol1(CalEntry *e)
static void WriteSimpleEntryProtocol2(CalEntry *e, int today)
{
int done = 0;
char const *s;
if (DoPrefixLineNo) {
PrintJSONKeyPairString("filename", e->filename);
PrintJSONKeyPairInt("lineno", e->lineno);
@@ -1983,6 +2334,45 @@ static void WriteSimpleEntryProtocol2(CalEntry *e, int today)
if (strcmp(e->raw_text, e->text)) {
PrintJSONKeyPairString("rawbody", e->raw_text);
}
/* Figure out calendar_body and plain_body */
if (DontSuppressQuoteMarkers) {
s = strstr(e->text, "%\"");
if (s) {
s += 2;
printf("\"calendar_body\":\"");
while (*s) {
if (*s == '%' && *(s+1) == '"') {
break;
}
PrintJSONChar(*s);
s++;
}
printf("\",");
}
}
s = strstr(e->text, "%\"");
if (s || e->is_color) {
printf("\"plain_body\":\"");
s = e->text;
if (e->is_color) {
while(*s && !isspace(*s)) s++;
while(*s && isspace(*s)) s++;
while(*s && !isspace(*s)) s++;
while(*s && isspace(*s)) s++;
while(*s && !isspace(*s)) s++;
while(*s && isspace(*s)) s++;
}
while(*s) {
if (*s == '%' && *(s+1) == '"') {
s += 2;
continue;
}
PrintJSONChar(*s);
s++;
}
printf("\",");
}
printf("\"body\":\"");
PrintJSONString(e->text);
printf("\"");
@@ -2195,14 +2585,14 @@ CalendarTime(int tim, int duration)
}
if (h >= 12) {
ampm1 = L_PM;
ampm1 = DynamicPm;
} else {
ampm1 = L_AM;
ampm1 = DynamicAm;
}
if (h2 >= 12) {
ampm2 = L_PM;
ampm2 = DynamicPm;
} else {
ampm2 = L_AM;
ampm2 = DynamicAm;
}
if (!days) {
if (!strcmp(ampm1, ampm2)) {
@@ -2249,7 +2639,7 @@ char const *SimpleTime(int tim)
if (h == 0) hh=12;
else if (h > 12) hh=h-12;
else hh=h;
sprintf(buf, "%d%c%02d%s ", hh, TimeSep, min, (h>=12) ? L_PM : L_AM);
sprintf(buf, "%d%c%02d%s ", hh, TimeSep, min, (h>=12) ? DynamicPm : DynamicAm);
}
break;

54
src/compare-language-mods.pl Executable file
View File

@@ -0,0 +1,54 @@
#!/usr/bin/perl
use strict;
use warnings;
my $language_map = {
en => 'ENGLISH',
de => 'GERMAN',
nl => 'DUTCH',
fi => 'FINNISH',
fr => 'FRENCH',
'no' => 'NORWEGIAN',
da => 'DANISH',
pl => 'POLISH',
is => 'ICELANDIC',
pt => 'BRAZPORT',
it => 'ITALIAN',
ro => 'ROMANIAN',
es => 'SPANISH',
};
if (!$ARGV[0]) {
print STDERR "Usage: $0 lang_code\n";
exit(1);
}
my $lang = $ARGV[0];
if (!exists($language_map->{$lang})) {
print STDERR "$lang is not a valid language.\n";
exit(1);
}
my $flag = $language_map->{$lang};
print STDERR "Testing for: $lang - $flag.\n";
my_sys("make clean > /dev/null 2>&1") && die("make clean failed");
my_sys("make -j6 all LANGDEF=-DLANG=$flag > /dev/null 2>&1") && die("make all failed");
my_sys("./remind -q -r ../tests/tstlang.rem 2022-03-23 11:44 > test-$lang-compiled.out 2>&1");
my_sys("make clean > /dev/null 2>&1") && die("make clean failed");
my_sys("make -j6 all > /dev/null 2>&1") && die("make all failed");
my_sys("./remind -q -r -ii=\\\"../include/lang/$lang.rem\\\" ../tests/tstlang.rem 2022-03-23 11:44 > test-$lang-runtime.out 2>&1");
my $rc = my_sys("cmp test-$lang-compiled.out test-$lang-runtime.out > /dev/null 2>&1");
if ($rc == 0) {
print STDERR "Congrats! Compiled and runtime language output matches for $lang.\n";
} else {
print STDERR "Whoops. Compiled and runtime language output differs for $lang.\n"
}
exit(0);
sub my_sys
{
#print STDERR "Running: " . join(' ', @_) . "\n";
return system(@_);
}

View File

@@ -20,6 +20,8 @@
#undef HAVE_LOCALE_H
#undef HAVE_LANGINFO_H
#undef HAVE_GLOB
#undef HAVE_SETENV

View File

@@ -6,7 +6,7 @@
/* which you can customize. */
/* */
/* This file is part of REMIND. */
/* Copyright (C) 1992-2021 by Dianne Skoll */
/* Copyright (C) 1992-2022 by Dianne Skoll */
/* */
/***************************************************************/
@@ -21,8 +21,8 @@
/* The default values are initially set to the city hall in Ottawa, */
/* Ontario, Canada. */
/*---------------------------------------------------------------------*/
#define DEFAULT_LATITUDE 45.42055555555555
#define DEFAULT_LONGITUDE -75.68972222222223
#define DEFAULT_LATITUDE 45.420556
#define DEFAULT_LONGITUDE -75.689722
#define LOCATION "Ottawa"
/*---------------------------------------------------------------------*/
@@ -116,7 +116,7 @@
/*---------------------------------------------------------------------*/
/* VAL_STACK_SIZE: The size of the operand stack for expr. parsing */
/*---------------------------------------------------------------------*/
#define VAL_STACK_SIZE 500
#define VAL_STACK_SIZE 1000
/*---------------------------------------------------------------------*/
/* INCLUDE_NEST: How many nested INCLUDES do we handle? */

View File

@@ -6,7 +6,7 @@
/* which you can customize. */
/* */
/* This file is part of REMIND. */
/* Copyright (C) 1992-2021 by Dianne Skoll */
/* Copyright (C) 1992-2022 by Dianne Skoll */
/* */
/***************************************************************/
@@ -21,8 +21,8 @@
/* The default values are initially set to the city hall in Ottawa, */
/* Ontario, Canada. */
/*---------------------------------------------------------------------*/
#define DEFAULT_LATITUDE 45.42055555555555
#define DEFAULT_LONGITUDE -75.68972222222223
#define DEFAULT_LATITUDE 45.420556
#define DEFAULT_LONGITUDE -75.689722
#define LOCATION "Ottawa"
/*---------------------------------------------------------------------*/
@@ -116,7 +116,7 @@
/*---------------------------------------------------------------------*/
/* VAL_STACK_SIZE: The size of the operand stack for expr. parsing */
/*---------------------------------------------------------------------*/
#define VAL_STACK_SIZE 500
#define VAL_STACK_SIZE 1000
/*---------------------------------------------------------------------*/
/* INCLUDE_NEST: How many nested INCLUDES do we handle? */

View File

@@ -7,7 +7,7 @@
/* commands. */
/* */
/* This file is part of REMIND. */
/* Copyright (C) 1992-2021 by Dianne Skoll */
/* Copyright (C) 1992-2022 by Dianne Skoll */
/* */
/***************************************************************/
@@ -28,7 +28,7 @@ static int ParseTimeTrig (ParsePtr s, TimeTrig *tim, int save_in_globals);
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);
static int ParseUntil (ParsePtr s, Trigger *t, int type);
static int ShouldTriggerBasedOnWarn (Trigger *t, int jul, int *err);
static int ComputeTrigDuration(TimeTrig *t);
@@ -96,9 +96,13 @@ int DoRem(ParsePtr p)
FindToken(DBufValue(&buf), &tok);
DBufFree(&buf);
if (tok.type == T_Empty || tok.type == T_Comment) {
r = OK;
if (trig.addomit) {
r = AddGlobalOmit(LastTriggerDate);
}
DBufFree(&buf);
FreeTrig(&trig);
return OK;
return r;
}
if (tok.type != T_RemType || tok.val == SAT_TYPE) {
DBufFree(&buf);
@@ -168,27 +172,37 @@ int DoRem(ParsePtr p)
FreeTrig(&trig);
return OK;
}
/* Queue the reminder, if necessary */
/* Queue the reminder, if necessary */
if (jul == JulianToday &&
!(!IgnoreOnce &&
trig.once != NO_ONCE &&
FileAccessDate == JulianToday))
QueueReminder(p, &trig, &tim, trig.sched);
/* If we're in daemon mode, do nothing over here */
/* If we're in daemon mode, do nothing over here */
if (Daemon) {
FreeTrig(&trig);
return OK;
}
r = OK;
if (ShouldTriggerReminder(&trig, &tim, jul, &err)) {
if ( (r=TriggerReminder(p, &trig, &tim, jul)) ) {
FreeTrig(&trig);
return r;
}
} else {
/* Parse the rest of the line to catch any potential
expression-pasting errors */
while (ParseChar(p, &r, 0)) {
if (r != 0) {
break;
}
}
}
FreeTrig(&trig);
return OK;
return r;
}
/***************************************************************/
@@ -237,11 +251,15 @@ int ParseRem(ParsePtr s, Trigger *trig, TimeTrig *tim, int save_in_globals)
tim->delta = DefaultTDelta;
tim->rep = NO_REP;
tim->duration = NO_TIME;
trig->need_wkday = 0;
trig->adj_for_last = 0;
if (save_in_globals) {
LastTriggerTime = NO_TIME;
}
while(1) {
int parsing = 1;
while(parsing) {
/* Read space-delimited string */
r = ParseToken(s, &buf);
if (r) return r;
@@ -249,6 +267,25 @@ int ParseRem(ParsePtr s, Trigger *trig, TimeTrig *tim, int save_in_globals)
/* Figure out what we've got */
FindToken(DBufValue(&buf), &tok);
switch(tok.type) {
case T_In:
/* Completely ignored */
DBufFree(&buf);
break;
case T_Ordinal:
DBufFree(&buf);
if (trig->d != NO_DAY) return E_DAY_TWICE;
if (tok.val < 0) {
if (trig->back != NO_BACK) return E_BACK_TWICE;
trig->back = -7;
trig->d = 1;
trig->adj_for_last = 1;
} else {
trig->d = 1 + 7 * tok.val;
}
trig->need_wkday = 1;
break;
case T_Date:
DBufFree(&buf);
if (trig->d != NO_DAY) return E_DAY_TWICE;
@@ -322,7 +359,6 @@ int ParseRem(ParsePtr s, Trigger *trig, TimeTrig *tim, int save_in_globals)
DBufFree(&buf);
trig->typ = tok.val;
if (s->isnested) return E_CANT_NEST_RTYPE;
if (trig->scanfrom == NO_DATE) trig->scanfrom = JulianToday;
if (trig->typ == PASSTHRU_TYPE) {
r = ParseToken(s, &buf);
if (r) return r;
@@ -332,19 +368,20 @@ int ParseRem(ParsePtr s, Trigger *trig, TimeTrig *tim, int save_in_globals)
}
StrnCpy(trig->passthru, DBufValue(&buf), PASSTHRU_LEN);
}
return OK;
parsing = 0;
break;
case T_Through:
DBufFree(&buf);
if (trig->rep != NO_REP) return E_REP_TWICE;
trig->rep = 1;
r = ParseUntil(s, trig);
r = ParseUntil(s, trig, tok.type);
if (r) return r;
break;
case T_Until:
DBufFree(&buf);
r=ParseUntil(s, trig);
r=ParseUntil(s, trig, tok.type);
if (r) return r;
break;
@@ -378,6 +415,15 @@ int ParseRem(ParsePtr s, Trigger *trig, TimeTrig *tim, int save_in_globals)
trig->back = tok.val;
break;
case T_BackAdj:
DBufFree(&buf);
if (trig->back != NO_BACK) return E_BACK_TWICE;
if (trig->d != NO_DAY) return E_DAY_TWICE;
trig->back = tok.val;
trig->d = 1;
trig->adj_for_last = 1;
break;
case T_Once:
DBufFree(&buf);
if (trig->once != NO_ONCE) return E_ONCE_TWICE;
@@ -392,7 +438,7 @@ int ParseRem(ParsePtr s, Trigger *trig, TimeTrig *tim, int save_in_globals)
case T_Omit:
DBufFree(&buf);
if (trig->omitfunc[0]) {
Eprint("Warning: OMIT is ignored if you use OMITFUNC");
Wprint("Warning: OMIT is ignored if you use OMITFUNC");
}
r = ParseLocalOmit(s, trig);
@@ -401,12 +447,12 @@ int ParseRem(ParsePtr s, Trigger *trig, TimeTrig *tim, int save_in_globals)
case T_Empty:
DBufFree(&buf);
if (trig->scanfrom == NO_DATE) trig->scanfrom = JulianToday;
return OK;
parsing = 0;
break;
case T_OmitFunc:
if (trig->localomit) {
Eprint("Warning: OMIT is ignored if you use OMITFUNC");
Wprint("Warning: OMIT is ignored if you use OMITFUNC");
}
r=ParseToken(s, &buf);
if (r) return r;
@@ -428,7 +474,12 @@ int ParseRem(ParsePtr s, Trigger *trig, TimeTrig *tim, int save_in_globals)
case T_Tag:
r = ParseToken(s, &buf);
if (r) return r;
if (strchr(DBufValue(&buf), ',')) {
DBufFree(&buf);
return E_PARSE_ERR;
}
AppendTag(&(trig->tags), DBufValue(&buf));
DBufFree(&buf);
break;
case T_Duration:
@@ -474,10 +525,58 @@ int ParseRem(ParsePtr s, Trigger *trig, TimeTrig *tim, int save_in_globals)
DBufFree(&buf);
trig->typ = MSG_TYPE;
if (s->isnested) return E_CANT_NEST_RTYPE;
if (trig->scanfrom == NO_DATE) trig->scanfrom = JulianToday;
return OK;
parsing = 0;
break;
}
}
if (trig->need_wkday && trig->wd == NO_WD) {
Eprint("Weekday name(s) required");
return E_PARSE_ERR;
}
/* Adjust month and possibly year */
if (trig->adj_for_last) {
if (trig->m != NO_MON) {
trig->m++;
if (trig->m >= 12) {
trig->m = 0;
if (trig->y != NO_YR) {
trig->y++;
}
}
}
trig->adj_for_last = 0;
}
/* Check for some warning conditions */
if (!s->nonconst_expr) {
if (trig->y != NO_YR && trig->m != NO_MON && trig->d != NO_DAY && trig->until != NO_UNTIL) {
if (Julian(trig->y, trig->m, trig->d) > trig->until) {
Wprint("Warning: UNTIL/THROUGH date earlier than start date");
}
}
if (trig->from != NO_DATE) {
if (trig->until != NO_UNTIL && trig->until < trig->from) {
Wprint("Warning: UNTIL/THROUGH date earlier than FROM date");
}
} else if (trig->scanfrom != NO_DATE) {
if (trig->until != NO_UNTIL && trig->until < trig->scanfrom) {
Wprint("Warning: UNTIL/THROUGH date earlier than SCANFROM date");
}
}
}
if (trig->y != NO_YR && trig->m != NO_MON && trig->d != NO_DAY && trig->until != NO_UNTIL && trig->rep == NO_REP) {
Wprint("Warning: Useless use of UNTIL with fully-specified date and no *rep");
}
/* Set scanfrom to default if not set explicitly */
if (trig->scanfrom == NO_DATE) {
trig->scanfrom = JulianToday;
}
return OK;
}
/***************************************************************/
@@ -568,12 +667,18 @@ static int ParseLocalOmit(ParsePtr s, Trigger *t)
/* ParseUntil - parse the UNTIL portion of a reminder */
/* */
/***************************************************************/
static int ParseUntil(ParsePtr s, Trigger *t)
static int ParseUntil(ParsePtr s, Trigger *t, int type)
{
int y = NO_YR,
m = NO_MON,
d = NO_DAY;
char const *which;
if (type == T_Until) {
which = "UNTIL";
} else {
which = "THROUGH";
}
Token tok;
int r;
DynamicBuffer buf;
@@ -589,7 +694,7 @@ static int ParseUntil(ParsePtr s, Trigger *t)
case T_Year:
DBufFree(&buf);
if (y != NO_YR) {
Eprint("UNTIL: %s", ErrMsg[E_YR_TWICE]);
Eprint("%s: %s", which, ErrMsg[E_YR_TWICE]);
return E_YR_TWICE;
}
y = tok.val;
@@ -598,7 +703,7 @@ static int ParseUntil(ParsePtr s, Trigger *t)
case T_Month:
DBufFree(&buf);
if (m != NO_MON) {
Eprint("UNTIL: %s", ErrMsg[E_MON_TWICE]);
Eprint("%s: %s", which, ErrMsg[E_MON_TWICE]);
return E_MON_TWICE;
}
m = tok.val;
@@ -607,7 +712,7 @@ static int ParseUntil(ParsePtr s, Trigger *t)
case T_Day:
DBufFree(&buf);
if (d != NO_DAY) {
Eprint("UNTIL: %s", ErrMsg[E_DAY_TWICE]);
Eprint("%s: %s", which, ErrMsg[E_DAY_TWICE]);
return E_DAY_TWICE;
}
d = tok.val;
@@ -616,15 +721,15 @@ static int ParseUntil(ParsePtr s, Trigger *t)
case T_Date:
DBufFree(&buf);
if (y != NO_YR) {
Eprint("UNTIL: %s", ErrMsg[E_YR_TWICE]);
Eprint("%s: %s", which, ErrMsg[E_YR_TWICE]);
return E_YR_TWICE;
}
if (m != NO_MON) {
Eprint("UNTIL: %s", ErrMsg[E_MON_TWICE]);
Eprint("%s: %s", which, ErrMsg[E_MON_TWICE]);
return E_MON_TWICE;
}
if (d != NO_DAY) {
Eprint("UNTIL: %s", ErrMsg[E_DAY_TWICE]);
Eprint("%s: %s", which, ErrMsg[E_DAY_TWICE]);
return E_DAY_TWICE;
}
FromJulian(tok.val, &y, &m, &d);
@@ -632,7 +737,7 @@ static int ParseUntil(ParsePtr s, Trigger *t)
default:
if (y == NO_YR || m == NO_MON || d == NO_DAY) {
Eprint("UNTIL: %s", ErrMsg[E_INCOMPLETE]);
Eprint("%s: %s", which, ErrMsg[E_INCOMPLETE]);
DBufFree(&buf);
return E_INCOMPLETE;
}
@@ -772,6 +877,8 @@ static int ParseScanFrom(ParsePtr s, Trigger *t, int type)
}
}
}
/***************************************************************/
/* */
/* TriggerReminder */
@@ -833,12 +940,13 @@ int TriggerReminder(ParsePtr p, Trigger *t, TimeTrig *tim, int jul)
}
/* If it's a MSG-type reminder, and no -k option was used, issue the banner. */
if ((t->typ == MSG_TYPE || t->typ == MSF_TYPE)
&& !NumTriggered && !NextMode && !MsgCommand) {
&& !DidMsgReminder && !NextMode && !MsgCommand) {
DidMsgReminder = 1;
if (!DoSubstFromString(DBufValue(&Banner), &buf,
JulianToday, NO_TIME) &&
DBufLen(&buf)) {
printf("%s\n", DBufValue(&buf));
}
printf("%s\n", DBufValue(&buf));
}
DBufFree(&buf);
}
@@ -934,7 +1042,7 @@ int TriggerReminder(ParsePtr p, Trigger *t, TimeTrig *tim, int jul)
if (!r) {
if (!DoCoerce(STR_TYPE, &v)) {
if (is_color) {
DBufPuts(&buf, Colorize(red, green, blue));
DBufPuts(&buf, Colorize(red, green, blue, 0, 1));
}
if (DBufPuts(&buf, v.v.str) != OK) {
DBufFree(&buf);
@@ -948,7 +1056,7 @@ int TriggerReminder(ParsePtr p, Trigger *t, TimeTrig *tim, int jul)
}
if (is_color) {
DBufPuts(&buf, Colorize(red, green, blue));
DBufPuts(&buf, Colorize(red, green, blue, 0, 1));
}
if ( (r=DoSubst(p, &buf, t, tim, jul, NORMAL_MODE)) ) return r;
if (t->typ != RUN_TYPE) {
@@ -959,7 +1067,7 @@ int TriggerReminder(ParsePtr p, Trigger *t, TimeTrig *tim, int jul)
if (!r) {
if (!DoCoerce(STR_TYPE, &v)) {
if (is_color) {
DBufPuts(&buf, Colorize(red, green, blue));
DBufPuts(&buf, Colorize(red, green, blue, 0, 1));
}
if (DBufPuts(&buf, v.v.str) != OK) {
DBufFree(&buf);
@@ -973,7 +1081,7 @@ int TriggerReminder(ParsePtr p, Trigger *t, TimeTrig *tim, int jul)
}
if (is_color) {
DBufPuts(&buf, Decolorize(red, green, blue));
DBufPuts(&buf, Decolorize());
}
if ((!MsgCommand && t->typ == MSG_TYPE) || t->typ == MSF_TYPE) {

View File

@@ -6,11 +6,12 @@
/* reminders are triggered. */
/* */
/* This file is part of REMIND. */
/* Copyright (C) 1992-2021 by Dianne Skoll */
/* Copyright (C) 1992-2022 by Dianne Skoll */
/* */
/***************************************************************/
#include "config.h"
#include "expr.h"
#define L_IN_DOSUBST
#include <stdio.h>
#include <string.h>
@@ -29,9 +30,6 @@
#define NL "\n"
#endif
static char TODAY[] = L_TODAY;
static char TOMORROW[] = L_TOMORROW;
#define SHIP_OUT(s) if(DBufPuts(dbuf, s) != OK) return E_NO_MEM
/***************************************************************/
@@ -53,15 +51,23 @@ int DoSubst(ParsePtr p, DynamicBuffer *dbuf, Trigger *t, TimeTrig *tt, int jul,
int d, m, y;
int tim = tt->ttime;
int h, min, hh, ch, cmin, chh;
int i;
char const *pm, *cpm;
int tdiff, adiff, mdiff, hdiff;
char const *mplu, *hplu, *when, *plu;
int has_quote = 0;
char *ss;
char const *expr;
char *os;
char s[256];
char uf[32];
char mypm[64];
char mycpm[64];
char myplu[64];
int origLen = DBufLen(dbuf);
int altmode;
int r;
Value v;
FromJulian(jul, &y, &m, &d);
@@ -74,16 +80,16 @@ int DoSubst(ParsePtr p, DynamicBuffer *dbuf, Trigger *t, TimeTrig *tt, int jul,
#ifdef L_MPLU_OVER
L_MPLU_OVER
#else /* L_MPLU_OVER */
mplu = (mdiff == 1 ? "" : L_MPLU);
mplu = (mdiff == 1 ? "" : DynamicMplu);
#endif /* L_MPLU_OVER */
#ifdef L_HPLU_OVER
L_HPLU_OVER
#else /* L_HPLU_OVER */
hplu = (hdiff == 1 ? "" : L_HPLU);
hplu = (hdiff == 1 ? "" : DynamicHplu);
#endif /* L_HPLU_OVER */
when = (tdiff < 0 ? L_AGO : L_FROMNOW);
when = (tdiff < 0) ? DynamicAgo : DynamicFromnow;
h = tim / 60;
min = tim % 60;
@@ -91,7 +97,26 @@ int DoSubst(ParsePtr p, DynamicBuffer *dbuf, Trigger *t, TimeTrig *tt, int jul,
#ifdef L_AMPM_OVERRIDE
L_AMPM_OVERRIDE (pm, h)
#else
pm = (h < 12) ? L_AM : L_PM;
r = -1;
if (UserFuncExists("subst_ampm") == 1) {
snprintf(s, sizeof(s), "subst_ampm(%d)", h);
expr = (char const *) s;
r = EvalExpr(&expr, &v, NULL);
if (r == OK) {
if (!DoCoerce(STR_TYPE, &v)) {
snprintf(mypm, sizeof(mypm), "%s", v.v.str);
pm = mypm;
} else {
r = -1;
}
DestroyValue(v);
} else {
Eprint("%s", ErrMsg[r]);
}
}
if (r != OK) {
pm = (h < 12) ? DynamicAm : DynamicPm;
}
#endif
hh = (h == 12) ? 12 : h % 12;
@@ -101,25 +126,60 @@ int DoSubst(ParsePtr p, DynamicBuffer *dbuf, Trigger *t, TimeTrig *tt, int jul,
#ifdef L_AMPM_OVERRIDE
L_AMPM_OVERRIDE (cpm, ch)
#else
cpm = (ch < 12) ? L_AM : L_PM;
r = -1;
if (UserFuncExists("subst_ampm") == 1) {
snprintf(s, sizeof(s), "subst_ampm(%d)", ch);
expr = (char const *) s;
r = EvalExpr(&expr, &v, NULL);
if (r == OK) {
if (!DoCoerce(STR_TYPE, &v)) {
snprintf(mycpm, sizeof(mycpm), "%s", v.v.str);
cpm = mycpm;
} else {
r = -1;
}
} else {
Eprint("%s", ErrMsg[r]);
}
}
if (r != OK) {
cpm = (h < 12) ? DynamicAm : DynamicPm;
}
#endif
chh = (ch == 12) ? 12 : ch % 12;
#ifdef L_ORDINAL_OVERRIDE
L_ORDINAL_OVERRIDE
L_ORDINAL_OVERRIDE;
#else
switch(d) {
case 1:
case 21:
case 31: plu = "st"; break;
if (UserFuncExists("subst_ordinal") == 1) {
snprintf(s, sizeof(s), "subst_ordinal(%d)", d);
expr = (char const *) s;
r = EvalExpr(&expr, &v, NULL);
if (r == OK) {
if (!DoCoerce(STR_TYPE, &v)) {
snprintf(myplu, sizeof(myplu), "%s", v.v.str);
plu = myplu;
} else {
r = -1;
}
} else {
Eprint("%s", ErrMsg[r]);
}
}
if (r != OK) {
switch(d) {
case 1:
case 21:
case 31: plu = "st"; break;
case 2:
case 22: plu = "nd"; break;
case 2:
case 22: plu = "nd"; break;
case 3:
case 23: plu = "rd"; break;
case 3:
case 23: plu = "rd"; break;
default: plu = "th"; break;
default: plu = "th"; break;
}
}
#endif
@@ -131,8 +191,11 @@ int DoSubst(ParsePtr p, DynamicBuffer *dbuf, Trigger *t, TimeTrig *tt, int jul,
}
if (c == '\n') continue;
if (!c) {
if (mode != CAL_MODE && mode != ADVANCE_MODE &&
t->typ != RUN_TYPE && !MsgCommand) {
if (AddBlankLines &&
mode != CAL_MODE &&
mode != ADVANCE_MODE &&
t->typ != RUN_TYPE &&
!MsgCommand) {
if (DBufPutc(dbuf, '\n') != OK) return E_NO_MEM;
}
break;
@@ -162,7 +225,69 @@ int DoSubst(ParsePtr p, DynamicBuffer *dbuf, Trigger *t, TimeTrig *tt, int jul,
break;
}
}
if (c == '{') {
i = 0;
ss = s + snprintf(s, sizeof(s), "subst_");
while (1) {
c = ParseChar(p, &err, 0);
if (err) {
DBufFree(dbuf);
return err;
}
if (c == '}' || !c) {
break;
}
if (i < 64) {
*ss++ = c;
*ss = 0;
i++;
}
}
if (!c) {
Wprint("Warning: Unterminated %%{...} substitution sequence");
}
if (UserFuncExists(s) != 3) {
continue;
}
snprintf(ss, sizeof(s) - (ss-s), "(%d,'%04d-%02d-%02d',%02d:%02d)",
altmode ? 1 : 0, y, m+1, d, h, min);
expr = (char const *) s;
r = EvalExpr(&expr, &v, NULL);
if (r == OK) {
if (!DoCoerce(STR_TYPE, &v)) {
if (DBufPuts(dbuf, v.v.str) != OK) {
DestroyValue(v);
return E_NO_MEM;
}
}
DestroyValue(v);
}
continue;
}
done = 0;
snprintf(uf, sizeof(uf), "subst_%c", c);
if (UserFuncExists(uf) == 3) {
snprintf(s, sizeof(s), "subst_%c(%d,'%04d-%02d-%02d',%02d:%02d)",
c, altmode ? 1 : 0, y, m+1, d, h, min);
expr = (char const *) s;
r = EvalExpr(&expr, &v, NULL);
if (r == OK) {
if (v.type != INT_TYPE || v.v.val != 0) {
if (!DoCoerce(STR_TYPE, &v)) {
if (DBufPuts(dbuf, v.v.str) != OK) {
DestroyValue(v);
return E_NO_MEM;
}
}
DestroyValue(v);
continue;
}
DestroyValue(v);
} else {
Eprint("%s", ErrMsg[r]);
}
}
if (diff <= 1) {
switch(UPPER(c)) {
#ifndef L_NOTOMORROW_A
@@ -204,7 +329,7 @@ int DoSubst(ParsePtr p, DynamicBuffer *dbuf, Trigger *t, TimeTrig *tt, int jul,
#ifndef L_NOTOMORROW_V
case 'V':
#endif
sprintf(s, "%s", (diff ? TOMORROW : TODAY));
snprintf(s, sizeof(s), "%s", (diff ? DynamicTomorrow: DynamicToday));
SHIP_OUT(s);
done = 1;
break;
@@ -213,16 +338,42 @@ int DoSubst(ParsePtr p, DynamicBuffer *dbuf, Trigger *t, TimeTrig *tt, int jul,
}
}
if (!done) {
snprintf(uf, sizeof(uf), "subst_%cx", c);
if (UserFuncExists(uf) == 3) {
snprintf(s, sizeof(s), "subst_%cx(%d,'%04d-%02d-%02d',%02d:%02d)",
c, altmode ? 1 : 0, y, m+1, d, h, min);
expr = (char const *) s;
r = EvalExpr(&expr, &v, NULL);
if (r == OK) {
if (v.type != INT_TYPE || v.v.val != 0) {
if (!DoCoerce(STR_TYPE, &v)) {
if (DBufPuts(dbuf, v.v.str) != OK) {
DestroyValue(v);
return E_NO_MEM;
}
}
DestroyValue(v);
continue;
}
DestroyValue(v);
} else {
Eprint("%s", ErrMsg[r]);
}
}
}
if (!done) switch(UPPER(c)) {
case 'A':
#ifdef L_A_OVER
L_A_OVER
#else
if (altmode == '*') {
sprintf(s, "%s, %d %s, %d", get_day_name(jul%7), d,
if (altmode == '*' || !strcmp(DynamicOn, "")) {
snprintf(s, sizeof(s), "%s, %d %s, %d", get_day_name(jul%7), d,
get_month_name(m), y);
} else {
sprintf(s, "%s %s, %d %s, %d", L_ON, get_day_name(jul%7), d,
snprintf(s, sizeof(s), "%s %s, %d %s, %d", DynamicOn, get_day_name(jul%7), d,
get_month_name(m), y);
}
#endif
@@ -233,7 +384,7 @@ int DoSubst(ParsePtr p, DynamicBuffer *dbuf, Trigger *t, TimeTrig *tt, int jul,
#ifdef L_B_OVER
L_B_OVER
#else
sprintf(s, L_INXDAYS, diff);
snprintf(s, sizeof(s), L_INXDAYS, diff);
#endif
SHIP_OUT(s);
break;
@@ -242,10 +393,10 @@ int DoSubst(ParsePtr p, DynamicBuffer *dbuf, Trigger *t, TimeTrig *tt, int jul,
#ifdef L_C_OVER
L_C_OVER
#else
if (altmode == '*') {
sprintf(s, "%s", get_day_name(jul%7));
if (altmode == '*' || !strcmp(DynamicOn, "")) {
snprintf(s, sizeof(s), "%s", get_day_name(jul%7));
} else {
sprintf(s, "%s %s", L_ON, get_day_name(jul%7));
snprintf(s, sizeof(s), "%s %s", DynamicOn, get_day_name(jul%7));
}
#endif
SHIP_OUT(s);
@@ -255,7 +406,7 @@ int DoSubst(ParsePtr p, DynamicBuffer *dbuf, Trigger *t, TimeTrig *tt, int jul,
#ifdef L_D_OVER
L_D_OVER
#else
sprintf(s, "%d", d);
snprintf(s, sizeof(s), "%d", d);
#endif
SHIP_OUT(s);
break;
@@ -264,11 +415,11 @@ int DoSubst(ParsePtr p, DynamicBuffer *dbuf, Trigger *t, TimeTrig *tt, int jul,
#ifdef L_E_OVER
L_E_OVER
#else
if (altmode == '*') {
sprintf(s, "%02d%c%02d%c%04d", d, DateSep,
if (altmode == '*' || !strcmp(DynamicOn, "")) {
snprintf(s, sizeof(s), "%02d%c%02d%c%04d", d, DateSep,
m+1, DateSep, y);
} else {
sprintf(s, "%s %02d%c%02d%c%04d", L_ON, d, DateSep,
snprintf(s, sizeof(s), "%s %02d%c%02d%c%04d", DynamicOn, d, DateSep,
m+1, DateSep, y);
}
#endif
@@ -279,10 +430,10 @@ int DoSubst(ParsePtr p, DynamicBuffer *dbuf, Trigger *t, TimeTrig *tt, int jul,
#ifdef L_F_OVER
L_F_OVER
#else
if (altmode == '*') {
sprintf(s, "%02d%c%02d%c%04d", m+1, DateSep, d, DateSep, y);
if (altmode == '*' || !strcmp(DynamicOn, "")) {
snprintf(s, sizeof(s), "%02d%c%02d%c%04d", m+1, DateSep, d, DateSep, y);
} else {
sprintf(s, "%s %02d%c%02d%c%04d", L_ON, m+1, DateSep, d, DateSep, y);
snprintf(s, sizeof(s), "%s %02d%c%02d%c%04d", DynamicOn, m+1, DateSep, d, DateSep, y);
}
#endif
SHIP_OUT(s);
@@ -292,10 +443,10 @@ int DoSubst(ParsePtr p, DynamicBuffer *dbuf, Trigger *t, TimeTrig *tt, int jul,
#ifdef L_G_OVER
L_G_OVER
#else
if (altmode == '*') {
sprintf(s, "%s, %d %s", get_day_name(jul%7), d, get_month_name(m));
if (altmode == '*' || !strcmp(DynamicOn, "")) {
snprintf(s, sizeof(s), "%s, %d %s", get_day_name(jul%7), d, get_month_name(m));
} else {
sprintf(s, "%s %s, %d %s", L_ON, get_day_name(jul%7), d, get_month_name(m));
snprintf(s, sizeof(s), "%s %s, %d %s", DynamicOn, get_day_name(jul%7), d, get_month_name(m));
}
#endif
SHIP_OUT(s);
@@ -305,10 +456,10 @@ int DoSubst(ParsePtr p, DynamicBuffer *dbuf, Trigger *t, TimeTrig *tt, int jul,
#ifdef L_H_OVER
L_H_OVER
#else
if (altmode == '*') {
sprintf(s, "%02d%c%02d", d, DateSep, m+1);
if (altmode == '*' || !strcmp(DynamicOn, "")) {
snprintf(s, sizeof(s), "%02d%c%02d", d, DateSep, m+1);
} else {
sprintf(s, "%s %02d%c%02d", L_ON, d, DateSep, m+1);
snprintf(s, sizeof(s), "%s %02d%c%02d", DynamicOn, d, DateSep, m+1);
}
#endif
SHIP_OUT(s);
@@ -318,10 +469,10 @@ int DoSubst(ParsePtr p, DynamicBuffer *dbuf, Trigger *t, TimeTrig *tt, int jul,
#ifdef L_I_OVER
L_I_OVER
#else
if (altmode == '*') {
sprintf(s, "%02d%c%02d", m+1, DateSep, d);
if (altmode == '*' || !strcmp(DynamicOn, "")) {
snprintf(s, sizeof(s), "%02d%c%02d", m+1, DateSep, d);
} else {
sprintf(s, "%s %02d%c%02d", L_ON, m+1, DateSep, d);
snprintf(s, sizeof(s), "%s %02d%c%02d", DynamicOn, m+1, DateSep, d);
}
#endif
SHIP_OUT(s);
@@ -331,11 +482,11 @@ int DoSubst(ParsePtr p, DynamicBuffer *dbuf, Trigger *t, TimeTrig *tt, int jul,
#ifdef L_J_OVER
L_J_OVER
#else
if (altmode == '*') {
sprintf(s, "%s, %s %d%s, %d", get_day_name(jul%7),
if (altmode == '*' || !strcmp(DynamicOn, "")) {
snprintf(s, sizeof(s), "%s, %s %d%s, %d", get_day_name(jul%7),
get_month_name(m), d, plu, y);
} else {
sprintf(s, "%s %s, %s %d%s, %d", L_ON, get_day_name(jul%7),
snprintf(s, sizeof(s), "%s %s, %s %d%s, %d", DynamicOn, get_day_name(jul%7),
get_month_name(m), d, plu, y);
}
#endif
@@ -346,11 +497,11 @@ int DoSubst(ParsePtr p, DynamicBuffer *dbuf, Trigger *t, TimeTrig *tt, int jul,
#ifdef L_K_OVER
L_K_OVER
#else
if (altmode == '*') {
sprintf(s, "%s, %s %d%s", get_day_name(jul%7),
if (altmode == '*' || !strcmp(DynamicOn, "")) {
snprintf(s, sizeof(s), "%s, %s %d%s", get_day_name(jul%7),
get_month_name(m), d, plu);
} else {
sprintf(s, "%s %s, %s %d%s", L_ON, get_day_name(jul%7),
snprintf(s, sizeof(s), "%s %s, %s %d%s", DynamicOn, get_day_name(jul%7),
get_month_name(m), d, plu);
}
#endif
@@ -361,10 +512,10 @@ int DoSubst(ParsePtr p, DynamicBuffer *dbuf, Trigger *t, TimeTrig *tt, int jul,
#ifdef L_L_OVER
L_L_OVER
#else
if (altmode == '*') {
sprintf(s, "%04d%c%02d%c%02d", y, DateSep, m+1, DateSep, d);
if (altmode == '*' || !strcmp(DynamicOn, "")) {
snprintf(s, sizeof(s), "%04d%c%02d%c%02d", y, DateSep, m+1, DateSep, d);
} else {
sprintf(s, "%s %04d%c%02d%c%02d", L_ON, y, DateSep, m+1, DateSep, d);
snprintf(s, sizeof(s), "%s %04d%c%02d%c%02d", DynamicOn, y, DateSep, m+1, DateSep, d);
}
#endif
SHIP_OUT(s);
@@ -374,7 +525,7 @@ int DoSubst(ParsePtr p, DynamicBuffer *dbuf, Trigger *t, TimeTrig *tt, int jul,
#ifdef L_M_OVER
L_M_OVER
#else
sprintf(s, "%s", get_month_name(m));
snprintf(s, sizeof(s), "%s", get_month_name(m));
#endif
SHIP_OUT(s);
break;
@@ -383,7 +534,7 @@ int DoSubst(ParsePtr p, DynamicBuffer *dbuf, Trigger *t, TimeTrig *tt, int jul,
#ifdef L_N_OVER
L_N_OVER
#else
sprintf(s, "%d", m+1);
snprintf(s, sizeof(s), "%d", m+1);
#endif
SHIP_OUT(s);
break;
@@ -392,7 +543,7 @@ int DoSubst(ParsePtr p, DynamicBuffer *dbuf, Trigger *t, TimeTrig *tt, int jul,
#ifdef L_O_OVER
L_O_OVER
#else
if (RealToday == JulianToday) sprintf(s, " (%s)", L_TODAY);
if (RealToday == JulianToday) snprintf(s, sizeof(s), " (%s)", DynamicToday);
else *s = 0;
#endif
SHIP_OUT(s);
@@ -402,7 +553,7 @@ int DoSubst(ParsePtr p, DynamicBuffer *dbuf, Trigger *t, TimeTrig *tt, int jul,
#ifdef L_P_OVER
L_P_OVER
#else
sprintf(s, "%s", (diff == 1 ? "" : L_PLURAL));
snprintf(s, sizeof(s), "%s", (diff == 1 ? "" : L_PLURAL));
#endif
SHIP_OUT(s);
break;
@@ -411,7 +562,7 @@ int DoSubst(ParsePtr p, DynamicBuffer *dbuf, Trigger *t, TimeTrig *tt, int jul,
#ifdef L_Q_OVER
L_Q_OVER
#else
sprintf(s, "%s", (diff == 1 ? "'s" : "s'"));
snprintf(s, sizeof(s), "%s", (diff == 1 ? "'s" : "s'"));
#endif
SHIP_OUT(s);
break;
@@ -420,7 +571,7 @@ int DoSubst(ParsePtr p, DynamicBuffer *dbuf, Trigger *t, TimeTrig *tt, int jul,
#ifdef L_R_OVER
L_R_OVER
#else
sprintf(s, "%02d", d);
snprintf(s, sizeof(s), "%02d", d);
#endif
SHIP_OUT(s);
break;
@@ -429,7 +580,7 @@ int DoSubst(ParsePtr p, DynamicBuffer *dbuf, Trigger *t, TimeTrig *tt, int jul,
#ifdef L_S_OVER
L_S_OVER
#else
sprintf(s, "%s", plu);
snprintf(s, sizeof(s), "%s", plu);
#endif
SHIP_OUT(s);
break;
@@ -438,7 +589,7 @@ int DoSubst(ParsePtr p, DynamicBuffer *dbuf, Trigger *t, TimeTrig *tt, int jul,
#ifdef L_T_OVER
L_T_OVER
#else
sprintf(s, "%02d", m+1);
snprintf(s, sizeof(s), "%02d", m+1);
#endif
SHIP_OUT(s);
break;
@@ -447,11 +598,11 @@ int DoSubst(ParsePtr p, DynamicBuffer *dbuf, Trigger *t, TimeTrig *tt, int jul,
#ifdef L_U_OVER
L_U_OVER
#else
if (altmode == '*') {
sprintf(s, "%s, %d%s %s, %d", get_day_name(jul%7), d,
if (altmode == '*' || !strcmp(DynamicOn, "")) {
snprintf(s, sizeof(s), "%s, %d%s %s, %d", get_day_name(jul%7), d,
plu, get_month_name(m), y);
} else {
sprintf(s, "%s %s, %d%s %s, %d", L_ON, get_day_name(jul%7), d,
snprintf(s, sizeof(s), "%s %s, %d%s %s, %d", DynamicOn, get_day_name(jul%7), d,
plu, get_month_name(m), y);
}
#endif
@@ -462,11 +613,11 @@ int DoSubst(ParsePtr p, DynamicBuffer *dbuf, Trigger *t, TimeTrig *tt, int jul,
#ifdef L_V_OVER
L_V_OVER
#else
if (altmode == '*') {
sprintf(s, "%s, %d%s %s", get_day_name(jul%7), d, plu,
if (altmode == '*' || !strcmp(DynamicOn, "")) {
snprintf(s, sizeof(s), "%s, %d%s %s", get_day_name(jul%7), d, plu,
get_month_name(m));
} else {
sprintf(s, "%s %s, %d%s %s", L_ON, get_day_name(jul%7), d, plu,
snprintf(s, sizeof(s), "%s %s, %d%s %s", DynamicOn, get_day_name(jul%7), d, plu,
get_month_name(m));
}
#endif
@@ -477,7 +628,7 @@ int DoSubst(ParsePtr p, DynamicBuffer *dbuf, Trigger *t, TimeTrig *tt, int jul,
#ifdef L_W_OVER
L_W_OVER
#else
sprintf(s, "%s", get_day_name(jul%7));
snprintf(s, sizeof(s), "%s", get_day_name(jul%7));
#endif
SHIP_OUT(s);
break;
@@ -486,7 +637,7 @@ int DoSubst(ParsePtr p, DynamicBuffer *dbuf, Trigger *t, TimeTrig *tt, int jul,
#ifdef L_X_OVER
L_X_OVER
#else
sprintf(s, "%d", diff);
snprintf(s, sizeof(s), "%d", diff);
#endif
SHIP_OUT(s);
break;
@@ -495,7 +646,7 @@ int DoSubst(ParsePtr p, DynamicBuffer *dbuf, Trigger *t, TimeTrig *tt, int jul,
#ifdef L_Y_OVER
L_Y_OVER
#else
sprintf(s, "%d", y);
snprintf(s, sizeof(s), "%d", y);
#endif
SHIP_OUT(s);
break;
@@ -504,7 +655,7 @@ int DoSubst(ParsePtr p, DynamicBuffer *dbuf, Trigger *t, TimeTrig *tt, int jul,
#ifdef L_Z_OVER
L_Z_OVER
#else
sprintf(s, "%d", y % 100);
snprintf(s, sizeof(s), "%d", y % 100);
#endif
SHIP_OUT(s);
break;
@@ -514,14 +665,14 @@ int DoSubst(ParsePtr p, DynamicBuffer *dbuf, Trigger *t, TimeTrig *tt, int jul,
L_1_OVER
#else
if (tdiff == 0)
sprintf(s, "%s", L_NOW);
snprintf(s, sizeof(s), "%s", DynamicNow);
else if (hdiff == 0)
sprintf(s, "%d %s%s %s", mdiff, L_MINUTE, mplu, when);
snprintf(s, sizeof(s), "%d %s%s %s", mdiff, DynamicMinute, mplu, when);
else if (mdiff == 0)
sprintf(s, "%d %s%s %s", hdiff, L_HOUR, hplu, when);
snprintf(s, sizeof(s), "%d %s%s %s", hdiff, DynamicHour, hplu, when);
else
sprintf(s, "%d %s%s %s %d %s%s %s", hdiff, L_HOUR, hplu,
L_AND, mdiff, L_MINUTE, mplu, when);
snprintf(s, sizeof(s), "%d %s%s %s %d %s%s %s", hdiff, DynamicHour, hplu,
DynamicAnd, mdiff, DynamicMinute, mplu, when);
#endif
SHIP_OUT(s);
break;
@@ -531,9 +682,9 @@ int DoSubst(ParsePtr p, DynamicBuffer *dbuf, Trigger *t, TimeTrig *tt, int jul,
L_2_OVER
#else
if (altmode == '*') {
sprintf(s, "%d%c%02d%s", hh, TimeSep, min, pm);
snprintf(s, sizeof(s), "%d%c%02d%s", hh, TimeSep, min, pm);
} else {
sprintf(s, "%s %d%c%02d%s", L_AT, hh, TimeSep, min, pm);
snprintf(s, sizeof(s), "%s %d%c%02d%s", DynamicAt, hh, TimeSep, min, pm);
}
#endif
SHIP_OUT(s);
@@ -545,9 +696,9 @@ int DoSubst(ParsePtr p, DynamicBuffer *dbuf, Trigger *t, TimeTrig *tt, int jul,
#else
if (altmode == '*') {
sprintf(s, "%02d%c%02d", h, TimeSep, min);
snprintf(s, sizeof(s), "%02d%c%02d", h, TimeSep, min);
} else {
sprintf(s, "%s %02d%c%02d", L_AT, h, TimeSep, min);
snprintf(s, sizeof(s), "%s %02d%c%02d", DynamicAt, h, TimeSep, min);
}
#endif
SHIP_OUT(s);
@@ -557,7 +708,7 @@ int DoSubst(ParsePtr p, DynamicBuffer *dbuf, Trigger *t, TimeTrig *tt, int jul,
#ifdef L_4_OVER
L_4_OVER
#else
sprintf(s, "%d", tdiff);
snprintf(s, sizeof(s), "%d", tdiff);
#endif
SHIP_OUT(s);
break;
@@ -566,7 +717,7 @@ int DoSubst(ParsePtr p, DynamicBuffer *dbuf, Trigger *t, TimeTrig *tt, int jul,
#ifdef L_5_OVER
L_5_OVER
#else
sprintf(s, "%d", adiff);
snprintf(s, sizeof(s), "%d", adiff);
#endif
SHIP_OUT(s);
break;
@@ -575,7 +726,7 @@ int DoSubst(ParsePtr p, DynamicBuffer *dbuf, Trigger *t, TimeTrig *tt, int jul,
#ifdef L_6_OVER
L_6_OVER
#else
sprintf(s, "%s", when);
snprintf(s, sizeof(s), "%s", when);
#endif
SHIP_OUT(s);
break;
@@ -584,7 +735,7 @@ int DoSubst(ParsePtr p, DynamicBuffer *dbuf, Trigger *t, TimeTrig *tt, int jul,
#ifdef L_7_OVER
L_7_OVER
#else
sprintf(s, "%d", hdiff);
snprintf(s, sizeof(s), "%d", hdiff);
#endif
SHIP_OUT(s);
break;
@@ -593,7 +744,7 @@ int DoSubst(ParsePtr p, DynamicBuffer *dbuf, Trigger *t, TimeTrig *tt, int jul,
#ifdef L_8_OVER
L_8_OVER
#else
sprintf(s, "%d", mdiff);
snprintf(s, sizeof(s), "%d", mdiff);
#endif
SHIP_OUT(s);
break;
@@ -602,7 +753,7 @@ int DoSubst(ParsePtr p, DynamicBuffer *dbuf, Trigger *t, TimeTrig *tt, int jul,
#ifdef L_9_OVER
L_9_OVER
#else
sprintf(s, "%s", mplu);
snprintf(s, sizeof(s), "%s", mplu);
#endif
SHIP_OUT(s);
break;
@@ -611,7 +762,7 @@ int DoSubst(ParsePtr p, DynamicBuffer *dbuf, Trigger *t, TimeTrig *tt, int jul,
#ifdef L_0_OVER
L_0_OVER
#else
sprintf(s, "%s", hplu);
snprintf(s, sizeof(s), "%s", hplu);
#endif
SHIP_OUT(s);
break;
@@ -620,7 +771,7 @@ int DoSubst(ParsePtr p, DynamicBuffer *dbuf, Trigger *t, TimeTrig *tt, int jul,
#ifdef L_BANG_OVER
L_BANG_OVER
#else
sprintf(s, "%s", (tdiff >= 0 ? L_IS : L_WAS));
snprintf(s, sizeof(s), "%s", (tdiff >= 0 ? DynamicIs : DynamicWas));
#endif
SHIP_OUT(s);
break;
@@ -629,7 +780,7 @@ int DoSubst(ParsePtr p, DynamicBuffer *dbuf, Trigger *t, TimeTrig *tt, int jul,
#ifdef L_AT_OVER
L_AT_OVER
#else
sprintf(s, "%d%c%02d%s", chh, TimeSep, cmin, cpm);
snprintf(s, sizeof(s), "%d%c%02d%s", chh, TimeSep, cmin, cpm);
#endif
SHIP_OUT(s);
break;
@@ -638,16 +789,16 @@ int DoSubst(ParsePtr p, DynamicBuffer *dbuf, Trigger *t, TimeTrig *tt, int jul,
#ifdef L_HASH_OVER
L_HASH_OVER
#else
sprintf(s, "%02d%c%02d", ch, TimeSep, cmin);
snprintf(s, sizeof(s), "%02d%c%02d", ch, TimeSep, cmin);
#endif
SHIP_OUT(s);
break;
case '_':
if (PsCal == PSCAL_LEVEL2 || PsCal == PSCAL_LEVEL3 || (mode != CAL_MODE && mode != ADVANCE_MODE && !MsgCommand)) {
sprintf(s, "%s", NL);
snprintf(s, sizeof(s), "%s", NL);
} else {
sprintf(s, " ");
snprintf(s, sizeof(s), " ");
}
SHIP_OUT(s);
break;
@@ -657,8 +808,13 @@ int DoSubst(ParsePtr p, DynamicBuffer *dbuf, Trigger *t, TimeTrig *tt, int jul,
break;
case '"':
if (DBufPutc(dbuf, QUOTE_MARKER) != OK) return E_NO_MEM;
has_quote = 1;
if (DontSuppressQuoteMarkers) {
if (DBufPutc(dbuf, '%') != OK) return E_NO_MEM;
if (DBufPutc(dbuf, c) != OK) return E_NO_MEM;
} else {
if (DBufPutc(dbuf, QUOTE_MARKER) != OK) return E_NO_MEM;
has_quote = 1;
}
break;
default:

View File

@@ -6,7 +6,7 @@
/* buffers. */
/* */
/* This file is part of REMIND. */
/* Copyright (C) 1992-2021 by Dianne Skoll */
/* Copyright (C) 1992-2022 by Dianne Skoll */
/* */
/***************************************************************/

View File

@@ -5,7 +5,7 @@
/* Declaration of functions for manipulating dynamic buffers */
/* */
/* This file is part of REMIND. */
/* Copyright (C) 1992-2021 by Dianne Skoll */
/* Copyright (C) 1992-2022 by Dianne Skoll */
/* */
/***************************************************************/
@@ -31,6 +31,8 @@ int DBufGets(DynamicBuffer *dbuf, FILE *fp);
#define DBufValue(bufPtr) ((bufPtr)->buffer)
#define DBufLen(bufPtr) ((bufPtr)->len)
#define DBufPutc(dbuf, c) ( (dbuf)->allocatedLen < (dbuf)->len+1 ) ? (dbuf)->buffer[(dbuf)->len++] = c, (dbuf)->buffer[(dbuf)->len] = 0, OK : DBufPutcFN((dbuf), c)
#define DBufPutc(dbuf, c) ( ( (dbuf)->allocatedLen <= (dbuf)->len+1 ) ? \
DBufPutcFN( (dbuf), c) : \
( (dbuf)->buffer[(dbuf)->len++] = c, (dbuf)->buffer[(dbuf)->len] = 0, OK) )
#endif /* DYNBUF_H */

View File

@@ -5,7 +5,7 @@
/* Error definitions. */
/* */
/* This file is part of REMIND. */
/* Copyright (C) 1992-2021 by Dianne Skoll */
/* Copyright (C) 1992-2022 by Dianne Skoll */
/* */
/***************************************************************/
@@ -70,7 +70,7 @@
#define E_MON_TWICE 51
#define E_DAY_TWICE 52
#define E_UNKNOWN_TOKEN 53
#define E_SPEC_MON_DAY 54
#define E_SPEC_MON 54
#define E_2MANY_PART 55
#define E_2MANY_FULL 56
#define E_PUSH_NOPOP 57
@@ -187,7 +187,7 @@ EXTERN char *ErrMsg[]
"Month specified twice",
"Day specified twice",
"Unknown token",
"Must specify month and day in OMIT command",
"Must specify month in OMIT command",
"Too many partial OMITs",
"Too many full OMITs",
"Warning: PUSH-OMIT-CONTEXT without matching POP-OMIT-CONTEXT",

View File

@@ -5,7 +5,7 @@
/* This file contains routines to parse and evaluate */
/* expressions. */
/* */
/* Copyright 1992-2021 by Dianne Skoll */
/* Copyright 1992-2022 by Dianne Skoll */
/* */
/***************************************************************/
@@ -44,21 +44,32 @@ static int MakeValue (char const *s, Value *v, Var *locals, ParsePtr p);
/* Binary operators - all left-associative */
/* Operator precedence:
* Highest: Unary - Unary !
* / %
* + -
* < <= > >=
* == !=
* &&
* Lowest: ||
*
*/
/* Make SURE they are sorted lexically... this may die on an EBCDIC
system... */
Operator BinOp[] = {
{ "!=", 15, BIN_OP, NotEqual },
{ "%", 20, BIN_OP, Mod },
{ "%", 20, BIN_OP, Mod },
{ "&&", 14, BIN_OP, LogAND },
{ "*", 20, BIN_OP, Multiply },
{ "+", 18, BIN_OP, Add },
{ "-", 18, BIN_OP, Subtract },
{ "/", 20, BIN_OP, Divide },
{ "<", 16, BIN_OP, LessThan },
{ "*", 20, BIN_OP, Multiply },
{ "+", 18, BIN_OP, Add },
{ "-", 18, BIN_OP, Subtract },
{ "/", 20, BIN_OP, Divide },
{ "<", 16, BIN_OP, LessThan },
{ "<=", 16, BIN_OP, LessOrEqual },
{ "==", 15, BIN_OP, EqualTo },
{ ">", 16, BIN_OP, GreaterThan },
{ ">", 16, BIN_OP, GreaterThan },
{ ">=", 16, BIN_OP, GreaterOrEqual },
{ "||", 12, BIN_OP, LogOR },
};
@@ -66,16 +77,19 @@ Operator BinOp[] = {
/* These ones must be sorted too. */
Operator UnOp[] = {
{ "!", 22, UN_OP, LogNot },
{ "-", 22, UN_OP, UnMinus },
{ "!", 22, UN_OP, LogNot },
{ "-", 22, UN_OP, UnMinus },
};
#define NUM_UN_OPS (sizeof(UnOp) / sizeof(Operator))
extern BuiltinFunc Func[];
Operator OpStack[OP_STACK_SIZE];
Value ValStack[VAL_STACK_SIZE];
int OpStackPtr, ValStackPtr;
static Operator OpStack[OP_STACK_SIZE];
static int OpStackPtr = 0;
/* ValStack can't be static - needed by funcs.c */
Value ValStack[VAL_STACK_SIZE];
int ValStackPtr = 0;
/***************************************************************/
/* */
@@ -115,12 +129,13 @@ static int DebugPerform(Operator *op)
/* Clean the stack after an error occurs. */
/* */
/***************************************************************/
static void CleanStack(void)
static void CleanStack(int old_op_stack_ptr, int old_val_stack_ptr)
{
int i;
for (i=0; i<ValStackPtr; i++) DestroyValue(ValStack[i]);
ValStackPtr = 0;
for (i=old_val_stack_ptr; i<ValStackPtr; i++) DestroyValue(ValStack[i]);
ValStackPtr = old_val_stack_ptr;
OpStackPtr = old_op_stack_ptr;
}
/***************************************************************/
@@ -238,6 +253,10 @@ static int ParseExprToken(DynamicBuffer *buf, char const **in)
DBufFree(buf);
return E_NO_MEM;
}
if (!**in) {
DBufFree(buf);
return E_MISS_QUOTE;
}
continue;
}
c = *(*in)++;
@@ -306,8 +325,8 @@ int EvalExpr(char const **e, Value *v, ParsePtr p)
{
int r;
OpStackPtr = 0;
ValStackPtr = 0;
int old_op_stack_ptr = OpStackPtr;
int old_val_stack_ptr = ValStackPtr;
r = Evaluate(e, NULL, p);
@@ -316,11 +335,15 @@ int EvalExpr(char const **e, Value *v, ParsePtr p)
DBufFree(&ExprBuf);
if (r) {
CleanStack();
CleanStack(old_op_stack_ptr, old_val_stack_ptr);
/* fprintf(stderr, "O=%d V=%d\n", OpStackPtr, ValStackPtr); */
return r;
}
*v = *ValStack;
ValStack[0].type = ERR_TYPE;
OpStackPtr = old_op_stack_ptr;
ValStackPtr = old_val_stack_ptr;
*v = ValStack[old_val_stack_ptr];
ValStack[old_val_stack_ptr].type = ERR_TYPE;
/* fprintf(stderr, "O=%d V=%d\n", OpStackPtr, ValStackPtr); */
return r;
}
@@ -766,12 +789,11 @@ static int Add(void)
/* If both are ints, just add 'em */
if (v2.type == INT_TYPE && v1.type == INT_TYPE) {
int old = v1.v.val;
v1.v.val += v2.v.val;
/* Check for overflow */
if (_private_add_overflow(v1.v.val, v2.v.val, old)) {
if (_private_add_overflow(v1.v.val, v2.v.val)) {
return E_2HIGH;
}
v1.v.val += v2.v.val;
PushValStack(v1);
return OK;
}
@@ -779,9 +801,8 @@ static int Add(void)
/* If it's a date plus an int, add 'em */
if ((v1.type == DATE_TYPE && v2.type == INT_TYPE) ||
(v1.type == INT_TYPE && v2.type == DATE_TYPE)) {
int old = v1.v.val;
if (_private_add_overflow(v1.v.val, v2.v.val)) return E_DATE_OVER;
v1.v.val += v2.v.val;
if (_private_add_overflow(v1.v.val, v2.v.val, old)) return E_DATE_OVER;
if (v1.v.val < 0) return E_DATE_OVER;
v1.type = DATE_TYPE;
PushValStack(v1);
@@ -791,9 +812,8 @@ static int Add(void)
/* If it's a datetime plus an int or a time, add 'em */
if ((v1.type == DATETIME_TYPE && (v2.type == INT_TYPE || v2.type == TIME_TYPE)) ||
((v1.type == INT_TYPE || v1.type == TIME_TYPE) && v2.type == DATETIME_TYPE)) {
int old = v1.v.val;
if (_private_add_overflow(v1.v.val, v2.v.val)) return E_DATE_OVER;
v1.v.val += v2.v.val;
if (_private_add_overflow(v1.v.val, v2.v.val, old)) return E_DATE_OVER;
if (v1.v.val < 0) return E_DATE_OVER;
v1.type = DATETIME_TYPE;
PushValStack(v1);
@@ -805,9 +825,8 @@ static int Add(void)
if ((v1.type == TIME_TYPE && v2.type == INT_TYPE) ||
(v1.type == INT_TYPE && v2.type == TIME_TYPE) ||
(v1.type == TIME_TYPE && v2.type == TIME_TYPE)) {
int old = v1.v.val;
if (_private_add_overflow(v1.v.val, v2.v.val)) return E_DATE_OVER;
v1.v.val += v2.v.val;
if (_private_add_overflow(v1.v.val, v2.v.val, old)) return E_DATE_OVER;
v1.v.val = v1.v.val % MINUTES_PER_DAY;
if (v1.v.val < 0) v1.v.val += MINUTES_PER_DAY;
v1.type = TIME_TYPE;
@@ -868,18 +887,16 @@ static int Subtract(void)
/* If they're both INTs, do subtraction */
if (v1.type == INT_TYPE && v2.type == INT_TYPE) {
int old = v1.v.val;
if (_private_sub_overflow(v1.v.val, v2.v.val)) return E_2HIGH;
v1.v.val -= v2.v.val;
if (_private_sub_overflow(v1.v.val, v2.v.val, old)) return E_2HIGH;
PushValStack(v1);
return OK;
}
/* If it's a date minus an int, do subtraction, checking for underflow */
if (v1.type == DATE_TYPE && v2.type == INT_TYPE) {
int old = v1.v.val;
if (_private_sub_overflow(v1.v.val, v2.v.val)) return E_DATE_OVER;
v1.v.val -= v2.v.val;
if (_private_sub_overflow(v1.v.val, v2.v.val, old)) return E_DATE_OVER;
if (v1.v.val < 0) return E_DATE_OVER;
PushValStack(v1);
return OK;
@@ -888,9 +905,8 @@ static int Subtract(void)
/* If it's a datetime minus an int or a time, do subtraction,
* checking for underflow */
if (v1.type == DATETIME_TYPE && (v2.type == INT_TYPE || v2.type == TIME_TYPE)) {
int old = v1.v.val;
if (_private_sub_overflow(v1.v.val, v2.v.val)) return E_DATE_OVER;
v1.v.val -= v2.v.val;
if (_private_sub_overflow(v1.v.val, v2.v.val, old)) return E_DATE_OVER;
if (v1.v.val < 0) return E_DATE_OVER;
PushValStack(v1);
return OK;
@@ -908,9 +924,8 @@ static int Subtract(void)
if ((v1.type == TIME_TYPE && v2.type == TIME_TYPE) ||
(v1.type == DATETIME_TYPE && v2.type == DATETIME_TYPE) ||
(v1.type == DATE_TYPE && v2.type == DATE_TYPE)) {
int old = v1.v.val;
if (_private_sub_overflow(v1.v.val, v2.v.val)) return E_DATE_OVER;
v1.v.val -= v2.v.val;
if (_private_sub_overflow(v1.v.val, v2.v.val, old)) return E_DATE_OVER;
v1.type = INT_TYPE;
PushValStack(v1);
return OK;
@@ -945,11 +960,8 @@ static int Multiply(void)
(v1.v.val == -1 && v2.v.val == INT_MIN)) {
return E_2HIGH;
}
int old = v1.v.val;
if (_private_mul_overflow(v1.v.val, v2.v.val)) return E_2HIGH;
v1.v.val *= v2.v.val;
if (v2.v.val != 0) {
if (_private_div(v1.v.val, v2.v.val) != old) return E_2HIGH;
}
PushValStack(v1);
return OK;
}
@@ -1108,13 +1120,16 @@ static int LogOR(void)
return r;
}
if (v1.type == INT_TYPE && v2.type == INT_TYPE) {
v1.v.val = (v1.v.val || v2.v.val) ? 1 : 0;
PushValStack(v1);
return OK;
if (v1.type != v2.type || v1.type == STR_TYPE || v2.type == STR_TYPE) {
DestroyValue(v1); DestroyValue(v2);
return E_BAD_TYPE;
}
DestroyValue(v1); DestroyValue(v2);
return E_BAD_TYPE;
if (v1.v.val == 0) {
v1.v.val = v2.v.val;
}
PushValStack(v1);
return OK;
}
/***************************************************************/
@@ -1135,13 +1150,15 @@ static int LogAND(void)
return r;
}
if (v1.type == INT_TYPE && v2.type == INT_TYPE) {
v1.v.val = (v1.v.val && v2.v.val) ? 1 : 0;
PushValStack(v1);
return OK;
if (v1.type != v2.type || v1.type == STR_TYPE || v2.type == STR_TYPE) {
DestroyValue(v1); DestroyValue(v2);
return E_BAD_TYPE;
}
DestroyValue(v1); DestroyValue(v2);
return E_BAD_TYPE;
if (v1.v.val != 0) {
v1.v.val = v2.v.val;
}
PushValStack(v1);
return OK;
}
/***************************************************************/
@@ -1155,9 +1172,8 @@ static int UnMinus(void)
{
Value *v = &ValStack[ValStackPtr-1];
if (v->type != INT_TYPE) return E_BAD_TYPE;
int old = v->v.val;
if (v->v.val == INT_MIN) return E_2HIGH;
v->v.val = -v->v.val;
if (_private_unminus_overflow(old, v->v.val)) return E_2HIGH;
return OK;
}
@@ -1178,9 +1194,9 @@ static int LogNot(void)
/***************************************************************/
/* */
/* FindFunc */
/* FindOperator */
/* */
/* Find a function. */
/* Find an operator. */
/* */
/***************************************************************/
Operator *FindOperator(char const *name, Operator where[], int num)
@@ -1189,7 +1205,7 @@ Operator *FindOperator(char const *name, Operator where[], int num)
int mid, r;
while (top >= bot) {
mid = (top + bot) / 2;
r = StrCmpi(name, where[mid].name);
r = strcmp(name, where[mid].name);
if (!r) return &where[mid];
else if (r > 0) bot = mid+1;
else top = mid-1;
@@ -1197,6 +1213,20 @@ Operator *FindOperator(char const *name, Operator where[], int num)
return NULL;
}
/* Compare two strings case-insensitively, where we KNOW
that the second string is definitely lower-case */
static int strcmp_lcfirst(char const *s1, char const *s2)
{
int r;
while (*s1 && *s2) {
r = tolower(*s1) - *s2;
if (r) return r;
s1++;
s2++;
}
return tolower(*s1) - *s2;
}
/***************************************************************/
/* */
/* FindFunc */
@@ -1210,7 +1240,7 @@ BuiltinFunc *FindFunc(char const *name, BuiltinFunc where[], int num)
int mid, r;
while (top >= bot) {
mid = (top + bot) / 2;
r = StrCmpi(name, where[mid].name);
r = strcmp_lcfirst(name, where[mid].name);
if (!r) return &where[mid];
else if (r > 0) bot = mid+1;
else top = mid-1;
@@ -1228,12 +1258,31 @@ BuiltinFunc *FindFunc(char const *name, BuiltinFunc where[], int num)
void PrintValue (Value *v, FILE *fp)
{
int y, m, d;
char const *s;
unsigned char const *s;
if (v->type == STR_TYPE) {
s=v->v.str;
s = (unsigned char const *) v->v.str;
putc('"', fp);
for (y=0; y<MAX_PRT_LEN && *s; y++) putc(*s++, fp);
for (y=0; y<MAX_PRT_LEN && *s; y++) {
switch(*s) {
case '\a': fprintf(ErrFp, "\\a"); break;
case '\b': fprintf(ErrFp, "\\b"); break;
case '\f': fprintf(ErrFp, "\\f"); break;
case '\n': fprintf(ErrFp, "\\n"); break;
case '\r': fprintf(ErrFp, "\\r"); break;
case '\t': fprintf(ErrFp, "\\t"); break;
case '\v': fprintf(ErrFp, "\\v"); break;
case '"': fprintf(ErrFp, "\\\""); break;
case '\\': fprintf(ErrFp, "\\\\"); break;
default:
if (*s < 32) {
fprintf(ErrFp, "\\x%02x", (unsigned int) *s);
} else {
putc(*s, ErrFp); break;
}
}
s++;
}
putc('"',fp);
if (*s) fprintf(fp, "...");
}

View File

@@ -5,7 +5,7 @@
/* Contains a few definitions used by expression evaluator. */
/* */
/* This file is part of REMIND. */
/* Copyright (C) 1992-2021 by Dianne Skoll */
/* Copyright (C) 1992-2022 by Dianne Skoll */
/* */
/***************************************************************/
@@ -58,7 +58,7 @@ else \
in various arithmetic operators. They have to be in separate
functions with extern linkage to defeat compiler optimizations
that would otherwise break the overflow checks. */
extern int _private_div(int a, int b);
extern int _private_add_overflow(int result, int b, int old);
extern int _private_sub_overflow(int result, int b, int old);
extern int _private_unminus_overflow(int a, int b);
extern int _private_mul_overflow(int a, int b);
extern int _private_add_overflow(int a, int b);
extern int _private_sub_overflow(int a, int b);

View File

@@ -7,7 +7,7 @@
/* files. */
/* */
/* This file is part of REMIND. */
/* Copyright (C) 1992-2021 by Dianne Skoll */
/* Copyright (C) 1992-2022 by Dianne Skoll */
/* */
/***************************************************************/
@@ -163,6 +163,7 @@ int ReadLine(void)
LineNo = CLine->LineNo;
CLine = CLine->next;
FreshLine = 1;
clear_callstack();
if (DebugFlag & DB_ECHO_LINE) OutputLine(ErrFp);
return OK;
}
@@ -263,6 +264,7 @@ static int ReadLineFromFile(int use_pclose)
}
FreshLine = 1;
clear_callstack();
if (DebugFlag & DB_ECHO_LINE) OutputLine(ErrFp);
return OK;
}
@@ -818,6 +820,7 @@ static int IncludeCmd(char const *cmd)
int old_flag;
FreshLine = 1;
clear_callstack();
if (IStackPtr+1 >= INCLUDE_NEST) return E_NESTED_INCLUDE;
i = &IStack[IStackPtr];
@@ -935,6 +938,7 @@ int IncludeFile(char const *fname)
struct stat statbuf;
FreshLine = 1;
clear_callstack();
if (IStackPtr+1 >= INCLUDE_NEST) return E_NESTED_INCLUDE;
i = &IStack[IStackPtr];

View File

@@ -6,19 +6,26 @@
/* expressions. */
/* */
/* This file is part of REMIND. */
/* Copyright (C) 1992-2021 by Dianne Skoll */
/* Copyright (C) 1992-2022 by Dianne Skoll */
/* */
/***************************************************************/
#include "version.h"
#include "config.h"
#ifdef REM_USE_WCHAR
#define _XOPEN_SOURCE 600
#include <wctype.h>
#include <wchar.h>
#endif
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <ctype.h>
#include <math.h>
#include <sys/ioctl.h>
#include <unistd.h>
@@ -58,6 +65,8 @@ static int FADusk (func_info *);
static int FAbs (func_info *);
static int FAccess (func_info *);
static int FAmpm (func_info *);
static int FAnsicolor (func_info *);
static int FTrig (func_info *);
static int FIsAny (func_info *);
static int FArgs (func_info *);
static int FAsc (func_info *);
@@ -65,6 +74,7 @@ static int FBaseyr (func_info *);
static int FChar (func_info *);
static int FChoose (func_info *);
static int FCoerce (func_info *);
static int FColumns (func_info *);
static int FCurrent (func_info *);
static int FDate (func_info *);
static int FDateTime (func_info *);
@@ -93,6 +103,7 @@ static int FIsdst (func_info *);
static int FIsleap (func_info *);
static int FIsomitted (func_info *);
static int FLanguage (func_info *);
static int FLocalToUTC (func_info *);
static int FLower (func_info *);
static int FMax (func_info *);
static int FMin (func_info *);
@@ -110,22 +121,27 @@ static int FNonomitted (func_info *);
static int FNow (func_info *);
static int FOrd (func_info *);
static int FOstype (func_info *);
static int FPad (func_info *);
static int FPlural (func_info *);
static int FPsmoon (func_info *);
static int FPsshade (func_info *);
static int FRealCurrent (func_info *);
static int FRealnow (func_info *);
static int FRealtoday (func_info *);
static int FRows (func_info *);
static int FSgn (func_info *);
static int FShell (func_info *);
static int FSlide (func_info *);
static int FStdout (func_info *);
static int FStrlen (func_info *);
static int FSubstr (func_info *);
static int FSunrise (func_info *);
static int FSunset (func_info *);
static int FTime (func_info *);
static int FTimepart (func_info *);
static int FTimezone (func_info *);
static int FToday (func_info *);
static int FTrig (func_info *);
static int FTrigback (func_info *);
static int FTrigdate (func_info *);
static int FTrigdatetime (func_info *);
@@ -136,6 +152,7 @@ static int FTrigeventstart (func_info *);
static int FTrigfrom (func_info *);
static int FTrigger (func_info *);
static int FTrigpriority (func_info *);
static int FTrigtags (func_info *);
static int FTrigrep (func_info *);
static int FTrigscanfrom (func_info *);
static int FTrigtime (func_info *);
@@ -146,6 +163,7 @@ static int FTrigvalid (func_info *);
static int FTypeof (func_info *);
static int FTzconvert (func_info *);
static int FUpper (func_info *);
static int FUTCToLocal (func_info *);
static int FValue (func_info *);
static int FVersion (func_info *);
static int FWeekno (func_info *);
@@ -157,6 +175,7 @@ static int FShellescape (func_info *);
static int CleanUpAfterFunc (func_info *);
static int CheckArgs (BuiltinFunc *f, int nargs);
static int SunStuff (int rise, double cosz, int jul);
static int tz_set_tz (char const *tz);
/* "Overload" the struct Operator definition */
#define NO_MAX 127
@@ -210,12 +229,14 @@ BuiltinFunc Func[] = {
{ "adawn", 0, 1, 0, FADawn},
{ "adusk", 0, 1, 0, FADusk},
{ "ampm", 1, 3, 1, FAmpm },
{ "ansicolor", 1, 5, 1, FAnsicolor },
{ "args", 1, 1, 0, FArgs },
{ "asc", 1, 1, 1, FAsc },
{ "baseyr", 0, 0, 1, FBaseyr },
{ "char", 1, NO_MAX, 1, FChar },
{ "choose", 2, NO_MAX, 1, FChoose },
{ "coerce", 2, 2, 1, FCoerce },
{ "columns", 0, 1, 0, FColumns },
{ "current", 0, 0, 0, FCurrent },
{ "date", 3, 3, 1, FDate },
{ "datepart", 1, 1, 1, FDatepart },
@@ -245,6 +266,7 @@ BuiltinFunc Func[] = {
{ "isleap", 1, 1, 1, FIsleap },
{ "isomitted", 1, 1, 0, FIsomitted },
{ "language", 0, 0, 1, FLanguage },
{ "localtoutc", 1, 1, 1, FLocalToUTC },
{ "lower", 1, 1, 1, FLower },
{ "max", 1, NO_MAX, 1, FMax },
{ "min", 1, NO_MAX, 1, FMin },
@@ -262,23 +284,28 @@ BuiltinFunc Func[] = {
{ "now", 0, 0, 0, FNow },
{ "ord", 1, 1, 1, FOrd },
{ "ostype", 0, 0, 1, FOstype },
{ "pad", 3, 4, 1, FPad },
{ "plural", 1, 3, 1, FPlural },
{ "psmoon", 1, 4, 1, FPsmoon},
{ "psshade", 1, 3, 1, FPsshade},
{ "realcurrent", 0, 0, 0, FRealCurrent},
{ "realnow", 0, 0, 0, FRealnow},
{ "realtoday", 0, 0, 0, FRealtoday },
{ "rows", 0, 0, 0, FRows },
{ "sgn", 1, 1, 1, FSgn },
{ "shell", 1, 2, 0, FShell },
{ "shellescape", 1, 1, 1, FShellescape },
{ "slide", 2, NO_MAX, 0, FSlide },
{ "stdout", 0, 0, 1, FStdout },
{ "strlen", 1, 1, 1, FStrlen },
{ "substr", 2, 3, 1, FSubstr },
{ "sunrise", 0, 1, 0, FSunrise},
{ "sunset", 0, 1, 0, FSunset },
{ "time", 2, 2, 1, FTime },
{ "timepart", 1, 1, 1, FTimepart },
{ "timezone", 0, 1, 1, FTimezone },
{ "today", 0, 0, 0, FToday },
{ "trig", 0, NO_MAX, 0, FTrig },
{ "trigback", 0, 0, 0, FTrigback },
{ "trigdate", 0, 0, 0, FTrigdate },
{ "trigdatetime", 0, 0, 0, FTrigdatetime },
@@ -291,6 +318,7 @@ BuiltinFunc Func[] = {
{ "trigpriority", 0, 0, 0, FTrigpriority },
{ "trigrep", 0, 0, 0, FTrigrep },
{ "trigscanfrom", 0, 0, 0, FTrigscanfrom },
{ "trigtags", 0, 0, 0, FTrigtags },
{ "trigtime", 0, 0, 0, FTrigtime },
{ "trigtimedelta",0, 0, 0, FTrigtimedelta },
{ "trigtimerep", 0, 0, 0, FTrigtimerep },
@@ -299,6 +327,7 @@ BuiltinFunc Func[] = {
{ "typeof", 1, 1, 1, FTypeof },
{ "tzconvert", 2, 3, 0, FTzconvert },
{ "upper", 1, 1, 1, FUpper },
{ "utctolocal", 1, 1, 1, FUTCToLocal },
{ "value", 1, 2, 0, FValue },
{ "version", 0, 0, 1, FVersion },
{ "weekno", 0, 3, 1, FWeekno },
@@ -897,6 +926,87 @@ static int FSgn(func_info *info)
return OK;
}
static int parse_color_helper(char const *str, int *r, int *g, int *b)
{
if (!*str) {
/* Empty string means "reset to normal" */
*r = -1;
*g = -1;
*b = -1;
return OK;
}
if (sscanf(str, "%d %d %d", r, g, b) != 3) {
return E_BAD_TYPE;
}
return OK;
}
/***************************************************************/
/* */
/* FAnsicolor - return an ANSI terminal color sequence */
/* */
/***************************************************************/
static int FAnsicolor(func_info *info)
{
int r=0, g=0, b=0, bg=0, clamp=1;
int status = 0;
int index = 0;
bg = 0;
clamp = 1;
/* If first arg is a string: Parse out the colors */
if (ARG(0).type == STR_TYPE) {
/* If first arg is a string: Parse out the colors */
status = parse_color_helper(ARGSTR(0), &r, &g, &b);
if (status != 0) {
return status;
}
index = 1;
} else if (ARG(0).type == INT_TYPE) {
/* Must be at least three arguments */
if (Nargs < 3) return E_2FEW_ARGS;
ASSERT_TYPE(1, INT_TYPE);
ASSERT_TYPE(2, INT_TYPE);
r = ARGV(0);
g = ARGV(1);
b = ARGV(2);
index = 3;
}
if (r < -1 || g < -1 || b < -1) return E_2LOW;
if (r > 255 || g > 255 || b > 255) return E_2HIGH;
/* If any is -1, then all must be -1 */
if (r == -1 || g == -1 || b == -1) {
if (r != -1 || g != -1 || b != -1) {
return E_2LOW;
}
}
if (Nargs > index) {
ASSERT_TYPE(index, INT_TYPE);
if (ARGV(index) < 0) return E_2LOW;
if (ARGV(index) > 1) return E_2HIGH;
bg = ARGV(index);
index++;
if (Nargs > index) {
ASSERT_TYPE(index, INT_TYPE);
if (ARGV(index) < 0) return E_2LOW;
if (ARGV(index) > 1) return E_2HIGH;
clamp = ARGV(index);
}
}
/* All righ! We have our parameters; now return the string */
if (!UseVTColors) {
/* Not using any colors: Empty strin */
return RetStrVal("", info);
}
if (r < 0) {
/* Return ANSI "reset to normal" string */
return RetStrVal(Decolorize(), info);
}
return RetStrVal(Colorize(r, g, b, bg, clamp), info);
}
/***************************************************************/
/* */
/* FAmpm - return a time as a string with "AM" or "PM" suffix */
@@ -995,6 +1105,73 @@ static int FOrd(func_info *info)
return RetStrVal(buf, info);
}
/***************************************************************/
/* */
/* FPad - Pad a string to min length */
/* */
/* pad("1", "0", 4) --> "0004" */
/* pad("1", "0", 4, 1) --> "4000" */
/* pad("foo", "bar", 7) -> "barbfoo" */
/* */
/***************************************************************/
static int FPad(func_info *info)
{
int r;
char *s;
DynamicBuffer dbuf;
size_t len;
size_t wantlen;
size_t i;
ASSERT_TYPE(1, STR_TYPE);
ASSERT_TYPE(2, INT_TYPE);
if (Nargs == 4) {
ASSERT_TYPE(3, INT_TYPE);
}
if (ARG(0).type != STR_TYPE) {
r = DoCoerce(STR_TYPE, &ARG(0));
if (r != OK) return r;
}
wantlen = ARGV(2);
len = strlen(ARGSTR(0));
if (len >= wantlen) {
DCOPYVAL(RetVal, ARG(0));
return OK;
}
if (strlen(ARGSTR(1)) == 0) {
return E_BAD_TYPE;
}
if (MaxStringLen > 0 && wantlen > (size_t) MaxStringLen) {
return E_STRING_TOO_LONG;
}
DBufInit(&dbuf);
s = ARGSTR(1);
if (Nargs < 4 || !ARGV(3)) {
/* Pad on the LEFT */
for (i=0; i<wantlen-len; i++) {
DBufPutc(&dbuf, *s++);
if (!*s) s = ARGSTR(1);
}
DBufPuts(&dbuf, ARGSTR(0));
} else {
/* Pad on the RIGHT */
DBufPuts(&dbuf, ARGSTR(0));
for (i=0; i<wantlen-len; i++) {
DBufPutc(&dbuf, *s++);
if (!*s) s = ARGSTR(1);
}
}
r = RetStrVal(DBufValue(&dbuf), info);
DBufFree(&dbuf);
return r;
}
/***************************************************************/
/* */
/* FPlural - pluralization function */
@@ -1165,6 +1342,35 @@ static int FLower(func_info *info)
return OK;
}
/***************************************************************/
/* */
/* FStdout - return the type of file descriptor for stdout */
/* */
/***************************************************************/
static int FStdout(func_info *info)
{
struct stat statbuf;
int r;
if (isatty(STDOUT_FILENO)) {
return RetStrVal("TTY", info);
}
if (fstat(STDOUT_FILENO, &statbuf) < 0) {
return RetStrVal("UNKNOWN", info);
}
switch(statbuf.st_mode & S_IFMT) {
case S_IFBLK: r = RetStrVal("BLOCKDEV", info); break;
case S_IFCHR: r = RetStrVal("CHARDEV", info); break;
case S_IFDIR: r = RetStrVal("DIR",info); break;
case S_IFIFO: r = RetStrVal("PIPE",info); break;
case S_IFLNK: r = RetStrVal("SYMLINK", info); break;
case S_IFREG: r = RetStrVal("FILE",info); break;
case S_IFSOCK: r = RetStrVal("SOCKET", info); break;
default: r = RetStrVal("UNKNOWN", info); break;
}
return r;
}
/***************************************************************/
/* */
/* FToday - return the system's notion of "today" */
@@ -1366,6 +1572,11 @@ static int FTrigrep(func_info *info)
return OK;
}
static int FTrigtags(func_info *info)
{
return RetStrVal(DBufValue(&(LastTrigger.tags)), info);
}
static int FTrigpriority(func_info *info)
{
RetVal.type = INT_TYPE;
@@ -2122,6 +2333,115 @@ static int FTimeStuff(int wantmins, func_info *info)
return OK;
}
static int FTimezone(func_info *info)
{
int yr, mon, day, hr, min, jul, now;
struct tm local, *withzone;
time_t t;
char buf[64];
if (Nargs == 0) {
jul = JulianToday;
now = (SystemTime(0) / 60);
} else {
if (!HASDATE(ARG(0))) return E_BAD_TYPE;
jul = DATEPART(ARG(0));
if (HASTIME(ARG(0))) {
now = TIMEPART(ARG(0));
} else {
now = 0;
}
}
FromJulian(jul, &yr, &mon, &day);
hr = now / 60;
min = now % 60;
memset(&local, 0, sizeof(local));
local.tm_sec = 0;
local.tm_min = min;
local.tm_hour = hr;
local.tm_mday = day;
local.tm_mon = mon;
local.tm_year = yr-1900;
local.tm_isdst = -1;
t = mktime(&local);
withzone = localtime(&t);
buf[0] = 0;
strftime(buf, sizeof(buf), "%Z", withzone);
return RetStrVal(buf, info);
}
static int FLocalToUTC(func_info *info)
{
int yr, mon, day, hr, min, jul;
time_t loc_t;
struct tm local, *utc;
ASSERT_TYPE(0, DATETIME_TYPE);
FromJulian(DATEPART(ARG(0)), &yr, &mon, &day);
hr = TIMEPART(ARG(0))/60;
min = TIMEPART(ARG(0))%60;
memset(&local, 0, sizeof(local));
local.tm_sec = 0;
local.tm_min = min;
local.tm_hour = hr;
local.tm_mday = day;
local.tm_mon = mon;
local.tm_year = yr-1900;
local.tm_isdst = -1;
loc_t = mktime(&local);
if (loc_t == -1) {
return E_MKTIME_PROBLEM;
}
utc = gmtime(&loc_t);
jul = Julian(utc->tm_year+1900, utc->tm_mon, utc->tm_mday);
RetVal.type = DATETIME_TYPE;
RETVAL = MINUTES_PER_DAY * jul + utc->tm_hour*60 + utc->tm_min;
return OK;
}
static int FUTCToLocal(func_info *info)
{
int yr, mon, day, hr, min, jul;
time_t utc_t;
struct tm *local, utc;
char const *old_tz;
ASSERT_TYPE(0, DATETIME_TYPE);
FromJulian(DATEPART(ARG(0)), &yr, &mon, &day);
hr = TIMEPART(ARG(0))/60;
min = TIMEPART(ARG(0))%60;
old_tz = getenv("TZ");
tz_set_tz("UTC");
memset(&utc, 0, sizeof(utc));
utc.tm_sec = 0;
utc.tm_min = min;
utc.tm_hour = hr;
utc.tm_mday = day;
utc.tm_mon = mon;
utc.tm_year = yr-1900;
utc.tm_isdst = 0;
utc_t = mktime(&utc);
tz_set_tz(old_tz);
if (utc_t == -1) {
return E_MKTIME_PROBLEM;
}
local = localtime(&utc_t);
jul = Julian(local->tm_year+1900, local->tm_mon, local->tm_mday);
RetVal.type = DATETIME_TYPE;
RETVAL = MINUTES_PER_DAY * jul + local->tm_hour*60 + local->tm_min;
return OK;
}
/***************************************************************/
/* */
/* Sunrise and sunset functions. */
@@ -2234,10 +2554,10 @@ static int SunStuff(int rise, double cosz, int jul)
/* Sometimes, we get roundoff error. Check for "reasonableness" of
answer. */
if (rise) {
/* Sunrise so close to midnight it wrapped around -- permament light */
/* Sunrise so close to midnight it wrapped around -- permanent light */
if (hours >= 23) return NO_TIME;
} else {
/* Sunset so close to midnight it wrapped around -- permament light */
/* Sunset so close to midnight it wrapped around -- permanent light */
if (hours <= 1) return -NO_TIME;
}
return hours*60 + mins;
@@ -2411,8 +2731,7 @@ static int FPsshade(func_info *info)
if (!psshade_warned) {
psshade_warned = 1;
Eprint("psshade() is deprecated; use SPECIAL SHADE instead.");
FreshLine = 1;
Wprint("psshade() is deprecated; use SPECIAL SHADE instead.");
}
sprintf(s, "/_A LineWidth 2 div def ");
@@ -2467,8 +2786,7 @@ static int FPsmoon(func_info *info)
}
if (!psmoon_warned) {
psmoon_warned = 1;
Eprint("psmoon() is deprecated; use SPECIAL MOON instead.");
FreshLine = 1;
Wprint("psmoon() is deprecated; use SPECIAL MOON instead.");
}
if (size > 0) {
sprintf(sizebuf, "%d", size);
@@ -2825,11 +3143,11 @@ FSlide(func_info *info)
}
/* If ALL weekdays are omitted... barf! */
if (localomit == 127 && amt != 0) return E_2MANY_LOCALOMIT;
if ((WeekdayOmits | localomit) == 0x7F && amt != 0) return E_2MANY_LOCALOMIT;
if (amt > 0) {
while(amt) {
d++;
r = IsOmitted(d, localomit, NULL,&omit);
r = IsOmitted(d, localomit, NULL, &omit);
if (r) return r;
if (!omit) amt--;
}
@@ -2837,7 +3155,7 @@ FSlide(func_info *info)
while(amt) {
d--;
if (d < 0) return E_DATE_OVER;
r = IsOmitted(d, localomit, NULL,&omit);
r = IsOmitted(d, localomit, NULL, &omit);
if (r) return r;
if (!omit) amt++;
}
@@ -2971,8 +3289,12 @@ FEvalTrig(func_info *info)
CreateParser(ARGSTR(0), &p);
p.allownested = 0;
r = ParseRem(&p, &trig, &tim, 0);
if (r) return r;
if (r) {
DestroyParser(&p);
return r;
}
if (trig.typ != NO_TYPE) {
DestroyParser(&p);
FreeTrig(&trig);
return E_PARSE_ERR;
}
@@ -2981,7 +3303,7 @@ FEvalTrig(func_info *info)
} else {
/* Hokey... */
if (trig.scanfrom != JulianToday) {
Eprint("Warning: SCANFROM is ignored in two-argument form of evaltrig()");
Wprint("Warning: SCANFROM is ignored in two-argument form of evaltrig()");
}
jul = ComputeTrigger(scanfrom, &trig, &tim, &r, 0);
}
@@ -2990,6 +3312,7 @@ FEvalTrig(func_info *info)
jul = -1;
}
FreeTrig(&trig);
DestroyParser(&p);
if (r) return r;
if (jul < 0) {
RetVal.type = INT_TYPE;
@@ -3003,3 +3326,133 @@ FEvalTrig(func_info *info)
}
return OK;
}
static int LastTrig = 0;
static int
FTrig(func_info *info)
{
Parser p;
Trigger trig;
TimeTrig tim;
int jul;
int r;
int i;
RetVal.type = DATE_TYPE;
if (Nargs == 0) {
RETVAL = LastTrig;
return OK;
}
for (i=0; i<Nargs; i++) {
ASSERT_TYPE(i, STR_TYPE);
}
RETVAL = 0;
for (i=0; i<Nargs; i++) {
CreateParser(ARGSTR(i), &p);
p.allownested = 0;
r = ParseRem(&p, &trig, &tim, 0);
if (r) {
DestroyParser(&p);
return r;
}
if (trig.typ != NO_TYPE) {
DestroyParser(&p);
FreeTrig(&trig);
return E_PARSE_ERR;
}
jul = ComputeTrigger(trig.scanfrom, &trig, &tim, &r, 0);
if (r == E_CANT_TRIG) {
DestroyParser(&p);
FreeTrig(&trig);
continue;
}
if (ShouldTriggerReminder(&trig, &tim, jul, &r)) {
LastTrig = jul;
RETVAL = jul;
DestroyParser(&p);
FreeTrig(&trig);
return OK;
}
DestroyParser(&p);
FreeTrig(&trig);
}
return OK;
}
static int
rows_or_cols(func_info *info, int want_rows)
{
struct winsize w;
int fd = STDOUT_FILENO;
RetVal.type = INT_TYPE;
if (!isatty(fd)) {
fd = open("/dev/tty", O_RDONLY);
if (fd < 0) {
RETVAL = -1;
return OK;
}
}
if (ioctl(fd, TIOCGWINSZ, &w) == 0) {
if (want_rows) RETVAL = w.ws_row;
else RETVAL = w.ws_col;
} else {
RETVAL = -1;
}
if (fd != STDOUT_FILENO) {
close(fd);
}
return OK;
}
static int FRows(func_info *info)
{
return rows_or_cols(info, 1);
}
static int FColumns(func_info *info)
{
#ifdef REM_USE_WCHAR
size_t len;
wchar_t *buf, *s;
int width;
#endif
if (Nargs == 0) {
return rows_or_cols(info, 0);
}
ASSERT_TYPE(0, STR_TYPE);
#ifdef REM_USE_WCHAR
len = mbstowcs(NULL, ARGSTR(0), 0);
if (len == (size_t) -1) return E_NO_MEM;
buf = calloc(len+1, sizeof(wchar_t));
if (!buf) return E_NO_MEM;
(void) mbstowcs(buf, ARGSTR(0), len+1);
s = buf;
width = 0;
while (*s) {
if (*s == 0x1B && *(s+1) == '[') {
/* Skip escape sequences */
s += 2;
while (*s && (*s < 0x40 || *s > 0x7E)) {
s++;
}
if (*s) {
s++;
}
continue;
}
width += wcwidth(*s);
s++;
}
free(buf);
RetVal.type = INT_TYPE;
RETVAL = width;
return OK;
#else
return E_BAD_TYPE;
#endif
}

View File

@@ -8,15 +8,16 @@
/* globals.h and err.h */
/* */
/* This file is part of REMIND. */
/* Copyright (C) 1992-2021 by Dianne Skoll */
/* Copyright (C) 1992-2022 by Dianne Skoll */
/* */
/***************************************************************/
#include "config.h"
#include <stdio.h> /* For defintion of FILE - sigh! */
#include <stdio.h> /* For definition of FILE - sigh! */
#include "types.h"
#include "custom.h"
#include "lang.h"
#define MK_GLOBALS 1
#include "globals.h"
#include "err.h"

View File

@@ -11,6 +11,7 @@
/* */
/***************************************************************/
#ifdef MK_GLOBALS
#undef EXTERN
#define EXTERN
@@ -24,6 +25,10 @@
#ifdef HAVE_SYS_TYPES_H
#include <sys/types.h>
#endif
EXTERN FILE *ErrFp;
#include "dynbuf.h"
#include "lang.h"
#define MAX_TRUSTED_USERS 20
@@ -53,9 +58,10 @@ EXTERN INIT( int DoSimpleCalendar, 0);
EXTERN INIT( int DoSimpleCalDelta, 0);
EXTERN INIT( int DoPrefixLineNo, 0);
EXTERN INIT( int MondayFirst, 0);
EXTERN INIT( int AddBlankLines, 1);
EXTERN INIT( int Iterations, 1);
EXTERN INIT( int PsCal, 0);
EXTERN INIT( int CalWidth, -1);
EXTERN INIT( int CalWidth, 80);
EXTERN INIT( int CalWeeks, 0);
EXTERN INIT( int CalMonths, 0);
EXTERN INIT( int Hush, 0);
@@ -75,6 +81,8 @@ EXTERN INIT( long SysTime, -1L);
EXTERN char const *InitialFile;
EXTERN int FileAccessDate;
EXTERN INIT( int WeekdayOmits, 0);
EXTERN INIT( int DontSuppressQuoteMarkers, 0);
EXTERN INIT( int DontFork, 0);
EXTERN INIT( int DontQueue, 0);
EXTERN INIT( int NumQueued, 0);
@@ -88,13 +96,12 @@ EXTERN INIT( int DefaultColorB, -1);
EXTERN INIT( int DefaultColorG, -1);
EXTERN INIT( int SynthesizeTags, 0);
EXTERN INIT( int ScFormat, SC_AMPM);
EXTERN INIT( int MaxSatIter, 150);
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);
EXTERN FILE *ErrFp;
EXTERN INIT( FILE *PurgeFP, NULL);
EXTERN INIT( int NumIfs, 0);
EXTERN INIT( unsigned int IfFlags, 0);
@@ -106,11 +113,13 @@ EXTERN INIT( int LastTriggerTime, 0);
EXTERN INIT( int ShouldCache, 0);
EXTERN char const *CurLine;
EXTERN INIT( int NumTriggered, 0);
EXTERN INIT( int DidMsgReminder, 0);
EXTERN int ArgC;
EXTERN char const **ArgV;
EXTERN INIT( int CalLines, CAL_LINES);
EXTERN INIT( int CalPad, 1);
EXTERN INIT( int UseVTChars, 0);
EXTERN INIT( int UseBGVTColors, 0);
EXTERN INIT( int UseUTF8Chars, 0);
EXTERN INIT( int UseVTColors, 0);
EXTERN INIT( int Use256Colors, 0);
@@ -141,11 +150,6 @@ EXTERN INIT( int SubsIndent, 0);
EXTERN INIT( char *EndSent, ".?!");
EXTERN INIT( char *EndSentIg, "\"')]}>");
/* We need the language stuff here... */
#include "lang.h"
#include "dynbuf.h"
EXTERN DynamicBuffer Banner;
EXTERN DynamicBuffer LineBuffer;
EXTERN DynamicBuffer ExprBuf;
@@ -227,3 +231,98 @@ EXTERN int MonthIndex[2][12]
#endif
;
EXTERN char *DynamicAgo
#ifdef MK_GLOBALS
= L_AGO
#endif
;
EXTERN char *DynamicAm
#ifdef MK_GLOBALS
= L_AM
#endif
;
EXTERN char *DynamicAnd
#ifdef MK_GLOBALS
= L_AND
#endif
;
EXTERN char *DynamicAt
#ifdef MK_GLOBALS
= L_AT
#endif
;
EXTERN char *DynamicFromnow
#ifdef MK_GLOBALS
= L_FROMNOW
#endif
;
EXTERN char *DynamicHour
#ifdef MK_GLOBALS
= L_HOUR
#endif
;
EXTERN char *DynamicHplu
#ifdef MK_GLOBALS
= L_HPLU
#endif
;
EXTERN char *DynamicIs
#ifdef MK_GLOBALS
= L_IS
#endif
;
EXTERN char *DynamicMinute
#ifdef MK_GLOBALS
= L_MINUTE
#endif
;
EXTERN char *DynamicMplu
#ifdef MK_GLOBALS
= L_MPLU
#endif
;
EXTERN char *DynamicNow
#ifdef MK_GLOBALS
= L_NOW
#endif
;
EXTERN char *DynamicOn
#ifdef MK_GLOBALS
= L_ON
#endif
;
EXTERN char *DynamicPm
#ifdef MK_GLOBALS
= L_PM
#endif
;
EXTERN char *DynamicToday
#ifdef MK_GLOBALS
= L_TODAY
#endif
;
EXTERN char *DynamicTomorrow
#ifdef MK_GLOBALS
= L_TOMORROW
#endif
;
EXTERN char *DynamicWas
#ifdef MK_GLOBALS
= L_WAS
#endif
;
#define XSTR(x) #x
#define STRSYSDIR(x) XSTR(x)
EXTERN char *SysDir
#ifdef MK_GLOBALS
= STRSYSDIR(SYSDIR)
#endif
;
EXTERN int SuppressLRM
#ifdef MK_GLOBALS
= 0
#endif
;

View File

@@ -5,7 +5,7 @@
/* Support for the Hebrew calendar */
/* */
/* This file is part of REMIND. */
/* Copyright (C) 1992-2021 by Dianne Skoll */
/* Copyright (C) 1992-2022 by Dianne Skoll */
/* */
/* Derived from code written by Amos Shapir in 1978; revised */
/* 1985. */

View File

@@ -7,7 +7,7 @@
/* in normal mode. */
/* */
/* This file is part of REMIND. */
/* Copyright (C) 1992-2021 by Dianne Skoll */
/* Copyright (C) 1992-2022 by Dianne Skoll */
/* */
/***************************************************************/
@@ -21,6 +21,10 @@
#include <stdlib.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <errno.h>
#include <pwd.h>
#include <unistd.h>
#include <sys/ioctl.h>
@@ -30,10 +34,10 @@
#endif
#include "types.h"
#include "globals.h"
#include "protos.h"
#include "expr.h"
#include "err.h"
#include "globals.h"
/***************************************************************
*
@@ -43,7 +47,8 @@
* simple calendar format.
* -r = Disallow RUN mode
* -c[n] = Produce a calendar for n months (default = 1)
* -@[n,m] = Colorize n=0 VT100 n=1 85 n=2 True m=0 dark terminal m=1 light
* -@[n,m,b]= Colorize n=0 VT100 n=1 85 n=2 True m=0 dark terminal m=1 light
* b=0 ignore SHADE b=1 respect SHADE
* -w[n,n,n] = Specify output device width, padding and spacing
* -s[n] = Produce calendar in "simple calendar" format
* -p[n] = Produce calendar in format compatible with rem2ps
@@ -94,6 +99,25 @@ static void AddTrustedUser(char const *username);
static DynamicBuffer default_filename_buf;
static void
InitCalWidthAndFormWidth(int fd)
{
struct winsize w;
if (!isatty(fd)) {
return;
}
if (ioctl(fd, TIOCGWINSZ, &w) == 0) {
CalWidth = w.ws_col;
if (CalWidth < 71) {
CalWidth = 71;
}
FormWidth = w.ws_col - 8;
if (FormWidth < 20) FormWidth = 20;
if (FormWidth > 500) FormWidth = 500;
}
}
/***************************************************************/
/* */
/* DefaultFilename */
@@ -141,20 +165,14 @@ void InitRemind(int argc, char const *argv[])
int weeks;
int x;
int jul;
int ttyfd;
jul = NO_DATE;
/* If stdout is a terminal, initialize $FormWidth to terminal width-8,
but clamp to [20, 500] */
if (isatty(STDOUT_FILENO)) {
struct winsize w;
if (ioctl(STDOUT_FILENO, TIOCGWINSZ, &w) == 0) {
FormWidth = w.ws_col - 8;
if (FormWidth < 20) FormWidth = 20;
if (FormWidth > 500) FormWidth = 500;
}
}
InitCalWidthAndFormWidth(STDOUT_FILENO);
/* Initialize global dynamic buffers */
DBufInit(&Banner);
DBufInit(&LineBuffer);
@@ -232,17 +250,37 @@ void InitRemind(int argc, char const *argv[])
Use256Colors = 1;
} else if (x == 2) {
UseTrueColors = 1;
}
} else if (x != 0) {
fprintf(ErrFp, "%s: -@n,m,b: n must be 0, 1 or 2 (assuming 0)\n",
argv[0]);
}
}
if (*arg == ',') {
arg++;
PARSENUM(x, arg);
if (x == 0) {
TerminalBackground = TERMINAL_BACKGROUND_DARK;
} else if (x == 1) {
TerminalBackground = TERMINAL_BACKGROUND_LIGHT;
}
if (*arg != ',') {
PARSENUM(x, arg);
if (x == 0) {
TerminalBackground = TERMINAL_BACKGROUND_DARK;
} else if (x == 1) {
TerminalBackground = TERMINAL_BACKGROUND_LIGHT;
} else if (x == 2) {
TerminalBackground = TERMINAL_BACKGROUND_UNKNOWN;
} else {
fprintf(ErrFp, "%s: -@n,m,b: m must be 0, 1 or 2 (assuming 2)\n",
argv[0]);
}
}
}
if (*arg == ',') {
arg++;
PARSENUM(x, arg);
if (x != 0 && x != 1) {
fprintf(ErrFp, "%s: -@n,m,b: b must be 0 or 1 (assuming 0)\n",
argv[0]);
x = 0;
}
UseBGVTColors = x;
}
break;
case 'j':
@@ -459,6 +497,7 @@ void InitRemind(int argc, char const *argv[])
DoSimpleCalendar = 1;
PsCal = PSCAL_LEVEL1;
while (*arg == 'a' || *arg == 'A' ||
*arg == 'q' || *arg == 'Q' ||
*arg == 'p' || *arg == 'P') {
if (*arg == 'a' || *arg == 'A') {
DoSimpleCalDelta = 1;
@@ -471,7 +510,9 @@ void InitRemind(int argc, char const *argv[])
} else {
PsCal = PSCAL_LEVEL3;
}
}
} else if (*arg == 'q' || *arg == 'Q') {
DontSuppressQuoteMarkers = 1;
}
arg++;
}
PARSENUM(CalMonths, arg);
@@ -486,11 +527,27 @@ void InitRemind(int argc, char const *argv[])
case 'w':
case 'W':
if (*arg != ',') {
PARSENUM(CalWidth, arg);
if (CalWidth != 0 && CalWidth < 71) CalWidth = 71;
if (CalWidth == 0) {
CalWidth = -1;
}
if (*arg == 't') {
arg++;
/* -wt means get width from /dev/tty */
ttyfd = open("/dev/tty", O_RDONLY);
if (!ttyfd) {
fprintf(stderr, "%s: `-wt': Cannot open /dev/tty: %s\n",
argv[0], strerror(errno));
} else {
InitCalWidthAndFormWidth(ttyfd);
close(ttyfd);
}
} else {
PARSENUM(CalWidth, arg);
if (CalWidth != 0 && CalWidth < 71) CalWidth = 71;
if (CalWidth == 0) {
CalWidth = -1;
}
FormWidth = CalWidth - 8;
if (FormWidth < 20) FormWidth = 20;
if (FormWidth > 500) FormWidth = 500;
}
}
if (*arg == ',') {
arg++;
@@ -672,7 +729,7 @@ void InitRemind(int argc, char const *argv[])
#ifndef L_USAGE_OVERRIDE
void Usage(void)
{
fprintf(ErrFp, "\nREMIND %s (%s version) Copyright 1992-2021 Dianne Skoll\n", VERSION, L_LANGNAME);
fprintf(ErrFp, "\nREMIND %s (%s version) Copyright 1992-2022 Dianne Skoll\n", VERSION, L_LANGNAME);
#ifdef BETA
fprintf(ErrFp, ">>>> BETA VERSION <<<<\n");
#endif
@@ -680,7 +737,7 @@ void Usage(void)
fprintf(ErrFp, "Options:\n");
fprintf(ErrFp, " -n Output next occurrence of reminders in simple format\n");
fprintf(ErrFp, " -r Disable RUN directives\n");
fprintf(ErrFp, " -@[n,m] Colorize COLOR reminders\n");
fprintf(ErrFp, " -@[n,m,b] Colorize COLOR/SHADE reminders\n");
fprintf(ErrFp, " -c[a][n] Produce a calendar for n (default 1) months\n");
fprintf(ErrFp, " -c[a]+[n] Produce a calendar for n (default 1) weeks\n");
fprintf(ErrFp, " -w[n[,p[,s]]] Specify width, padding and spacing of calendar\n");
@@ -698,7 +755,7 @@ void Usage(void)
fprintf(ErrFp, " -d... Debug: e=echo x=expr-eval t=trig v=dumpvars l=showline f=tracefiles\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=150)\n");
fprintf(ErrFp, " -x[n] Iteration limit for SATISFY clause (def=1000)\n");
fprintf(ErrFp, " -kcmd Run `cmd' for MSG-type reminders\n");
fprintf(ErrFp, " -g[dddd] Sort reminders by date, time, priority, and 'timedness'\n");
fprintf(ErrFp, " -ivar=val Initialize var to val and preserve var\n");

View File

@@ -5,7 +5,7 @@
/* Header file for language support for various languages. */
/* */
/* This file is part of REMIND. */
/* Copyright (C) 1992-2021 by Dianne Skoll */
/* Copyright (C) 1992-2022 by Dianne Skoll */
/* */
/***************************************************************/
@@ -23,7 +23,7 @@
#define ITALIAN 9 /* translated by Valerio Aimale */
#define ROMANIAN 10 /* translated by Liviu Daia */
#define SPANISH 11 /* translated by Rafa Couto */
#define ICELANDIC 12 /* translated by Björn Davíðsson */
#define ICELANDIC 12 /* translated by Björn Davíðsson */
/* Add more languages here - but please e-mail dianne@skoll.ca
to have your favorite language assigned a number. If you add a

View File

@@ -6,7 +6,7 @@
/* */
/* This file is part of REMIND. */
/* */
/* REMIND is Copyright (C) 1992-2021 by Dianne Skoll */
/* REMIND is Copyright (C) 1992-2022 by Dianne Skoll */
/* This file is Copyright (C) 1993 by Mogens Lynnerup. */
/* */
/***************************************************************/
@@ -48,9 +48,6 @@
#define L_AM "am"
#define L_PM "pm"
/*** The following are only used in dosubst.c ***/
#ifdef L_IN_DOSUBST
/* Ago and from now */
#define L_AGO "siden"
#define L_FROMNOW "fra nu"
@@ -91,5 +88,3 @@
#define L_I_OVER sprintf(s, "den %02d%c%02d", m+1, DateSep, d);
#define L_U_OVER L_A_OVER
#define L_V_OVER L_G_OVER
#endif /* L_IN_DOSUBST */

View File

@@ -11,7 +11,7 @@
/* Further corrections by Erik-Jan Vens */
/* */
/* This file is part of REMIND. */
/* Copyright (C) 1992-2021 by Dianne Skoll */
/* Copyright (C) 1992-2022 by Dianne Skoll */
/* */
/***************************************************************/
@@ -52,9 +52,6 @@
#define L_AM "am"
#define L_PM "pm"
/*** The following are only used in dosubst.c ***/
#ifdef L_IN_DOSUBST
/* Ago and from now */
#define L_AGO "geleden"
#define L_FROMNOW "vanaf nu"
@@ -91,15 +88,14 @@ if (tdiff == 0) \
sprintf(s, L_NOW); \
else if (hdiff == 0) \
sprintf(s, "%d %s %s", mdiff, \
(mdiff == 1 ? "minuut" : "minuten"), when); \
((mdiff == 1) ? "minuut" : "minuten"), when); \
else if (mdiff == 0) \
sprintf(s, "%d %s %s", hdiff, \
(mdiff == 1 ? "uur" : "uren"), when); \
else sprintf(s, "%d %s %s %d %s %s", hdiff, \
(hdiff == 1 ? "uur" : "uren"), \
L_AND, mdiff, \
(mdiff == 1 ? "minuut" : "minuten"), \
when);
((hdiff == 1) ? "uur" : "uren"), when); \
else sprintf(s, "%d %s %s %d %s %s", hdiff, \
(hdiff == 1 ? "uur" : "uren"), \
L_AND, mdiff, \
(mdiff == 1 ? "minuut" : "minuten"), \
when);
#endif /* L_IN_DOSUBST */

View File

@@ -5,7 +5,7 @@
/* Support for the English language. */
/* */
/* This file is part of REMIND. */
/* Copyright (C) 1992-2021 by Dianne Skoll */
/* Copyright (C) 1992-2022 by Dianne Skoll */
/* */
/***************************************************************/
@@ -46,9 +46,6 @@
#define L_AM "am"
#define L_PM "pm"
/*** The following are only used in dosubst.c ***/
#ifdef L_IN_DOSUBST
/* Ago and from now */
#define L_AGO "ago"
#define L_FROMNOW "from now"
@@ -72,11 +69,9 @@
#define L_WAS "was"
#define L_AND "and"
/* What to add to make "hour" plural */
#define L_HPLU "s"
#define L_HPLU "s"
/* What to add to make "minute" plural */
#define L_MPLU "s"
/* Define any overrides here, such as L_ORDINAL_OVERRIDE, L_A_OVER, etc.
See the file dosubst.c for more info. */
#endif /* L_IN_DOSUBST */

View File

@@ -11,7 +11,7 @@
/* */
/* This file is part of REMIND. */
/* This file is Copyright (C) 1993-1998 by Mikko Silvonen. */
/* REMIND is Copyright (C) 1992-2021 by Dianne Skoll */
/* REMIND is Copyright (C) 1992-2022 by Dianne Skoll */
/* */
/***************************************************************/
@@ -52,9 +52,6 @@
#define L_AM " ap."
#define L_PM " ip."
/*** The following are only used in dosubst.c ***/
#ifdef L_IN_DOSUBST
/* Ago and from now */
#define L_AGO "sitten"
#define L_FROMNOW "kuluttua"
@@ -138,7 +135,6 @@ else { \
} \
sprintf(s + strlen(s), when); \
}
#endif /* L_IN_DOSUBST */
/* The next ones are used only when MK_GLOBALS is set */
#ifdef MK_GLOBALS
@@ -199,7 +195,7 @@ EXTERN char *ErrMsg[] =
"Kuukausi annettu kahdesti",
"Päivä annettu kahdesti",
"Tuntematon sana tai merkki",
"OMIT-komennossa on annettava kuukausi ja päivä",
"OMIT-komennossa on annettava kuukausi",
"Liian monta osittaista OMIT-komentoa",
"Liian monta täydellistä OMIT-komentoa",
"Varoitus: PUSH-OMIT-CONTEXT ilman POP-OMIT-CONTEXTia",
@@ -257,7 +253,7 @@ EXTERN char *ErrMsg[] =
#define L_USAGE_OVERRIDE 1
void Usage(void)
{
fprintf(ErrFp, "\nREMIND %s (%s version) Copyright 1992-2021 Dianne Skoll\n", VERSION, L_LANGNAME);
fprintf(ErrFp, "\nREMIND %s (%s version) Copyright 1992-2022 Dianne Skoll\n", VERSION, L_LANGNAME);
#ifdef BETA
fprintf(ErrFp, ">>>> BETAVERSIO <<<<\n");
#endif
@@ -283,7 +279,7 @@ void Usage(void)
fprintf(ErrFp, " -d... Virheenetsintä: e=echo x=expr-eval t=trig v=dumpvars l=showline\n");
fprintf(ErrFp, " -e Ohjaa virhetulostus stdout-vuohon\n");
fprintf(ErrFp, " -b[n] Ajan ilmaisu: 0=ap/ip, 1=24 tuntia, 2=ei aikoja\n");
fprintf(ErrFp, " -x[n] SATISFY-lauseen toistoraja (oletus 150)\n");
fprintf(ErrFp, " -x[n] SATISFY-lauseen toistoraja (oletus 1000)\n");
fprintf(ErrFp, " -kcmd Suorita 'cmd' MSG-tyyppisille viesteille\n");
fprintf(ErrFp, " -g[ddd] Lajittele viestit päiväyksen, ajan ja tärkeyden mukaan\n");
fprintf(ErrFp, " -ivar=val Alusta muuttuja var arvolla val ja säilytä var\n");

View File

@@ -8,7 +8,7 @@
/* */
/* This file is part of REMIND. */
/* */
/* REMIND is Copyright (C) 1992-2021 by Dianne Skoll */
/* REMIND is Copyright (C) 1992-2022 by Dianne Skoll */
/* This file is Copyright (C) 1993 by Laurent Duperval and */
/* Dianne Skoll. */
/* */
@@ -51,9 +51,6 @@
#define L_AM "am"
#define L_PM "pm"
/*** The following are only used in dosubst.c ***/
#ifdef L_IN_DOSUBST
/* Ago and from now */
#define L_AGO "il y a"
#define L_FROMNOW "dans"
@@ -113,8 +110,6 @@ else if (tdiff < 0) { \
#define L_K_OVER if (altmode == '*') { sprintf(s, "%s, %d%s %s", DayName[jul%7], d, plu, MonthName[m]); } else { sprintf(s, "%s %s, %d%s %s", L_ON, DayName[jul%7], d, plu, MonthName[m]); }
#endif /* L_IN_DOSUBST */
/* The next ones are used only when MK_GLOBALS is set */
#ifdef MK_GLOBALS
#define L_ERR_OVERRIDE 1
@@ -232,7 +227,7 @@ EXTERN char *ErrMsg[] =
#define L_USAGE_OVERRIDE 1
void Usage(void)
{
fprintf(ErrFp, "\nREMIND %s (%s version) Copyright 1992-2021 Dianne Skoll\n", VERSION, L_LANGNAME);
fprintf(ErrFp, "\nREMIND %s (%s version) Copyright 1992-2022 Dianne Skoll\n", VERSION, L_LANGNAME);
#ifdef BETA
fprintf(ErrFp, ">>>> BETA VERSION <<<<\n");
#endif
@@ -258,7 +253,7 @@ void Usage(void)
fprintf(ErrFp, " -d... Debug: e=echo x=expr-eval t=trig v=dumpvars l=showline\n");
fprintf(ErrFp, " -e Envoyer les messages de stderr à stdout\n");
fprintf(ErrFp, " -b[n] Formats de l'heure pour le calendrier: 0=am/pm, 1=24hr, 2=aucun\n");
fprintf(ErrFp, " -x[n] Limite d'itérations pour la clause SATISFY (def=150)\n");
fprintf(ErrFp, " -x[n] Limite d'itérations pour la clause SATISFY (def=1000)\n");
fprintf(ErrFp, " -kcmd Exécuter 'cmd' pour les rappels de type MSG\n");
fprintf(ErrFp, " -g[ddd] Trier les rappels par date, heure et priorité avant d'émettre\n");
fprintf(ErrFp, " -ivar=val Initialiser var à val et conserver var\n");

View File

@@ -9,7 +9,7 @@
/* I don't speak German. */
/* */
/* This file is part of REMIND. */
/* Copyright (C) 1992-2021 by Dianne Skoll */
/* Copyright (C) 1992-2022 by Dianne Skoll */
/* */
/***************************************************************/
@@ -50,9 +50,6 @@
#define L_AM "am"
#define L_PM "pm"
/*** The following are only used in dosubst.c ***/
#ifdef L_IN_DOSUBST
/* Ago and from now */
#define L_AGO "vorher"
#define L_FROMNOW "von heute"
@@ -88,5 +85,3 @@
#define L_G_OVER if (altmode == '*') { sprintf(s, "%s, den %d. %s", DayName[jul%7], d, MonthName[m]); } else { sprintf(s, "%s %s, den %d. %s", L_ON, DayName[jul%7], d, MonthName[m]); }
#define L_U_OVER L_A_OVER
#define L_V_OVER L_G_OVER
#endif /* L_IN_DOSUBST */

View File

@@ -5,8 +5,8 @@
/* Support for the Icelandic language. */
/* */
/* This file is part of REMIND. */
/* Copyright (C) 1992-2021 by Dianne Skoll */
/* Translated by Björn Davíðsson (bjossi@snerpa.is) */
/* Copyright (C) 1992-2022 by Dianne Skoll */
/* Translated by Björn Davíðsson (bjossi@snerpa.is) */
/* */
/***************************************************************/
@@ -15,59 +15,56 @@
/* Day names */
#define L_SUNDAY "sunnudagur"
#define L_MONDAY "mánudagur"
#define L_TUESDAY "þriðjudagur"
#define L_WEDNESDAY "miðvikudagur"
#define L_MONDAY "mánudagur"
#define L_TUESDAY "þriðjudagur"
#define L_WEDNESDAY "miðvikudagur"
#define L_THURSDAY "fimmtudagur"
#define L_FRIDAY "föstudagur"
#define L_FRIDAY "föstudagur"
#define L_SATURDAY "laugardagur"
/* Month names */
#define L_JAN "janúar"
#define L_FEB "febrúar"
#define L_JAN "janúar"
#define L_FEB "febrúar"
#define L_MAR "mars"
#define L_APR "apríl"
#define L_MAY "maí"
#define L_JUN "júní"
#define L_JUL "júlí"
#define L_AUG "ágúst"
#define L_APR "apríl"
#define L_MAY "maí"
#define L_JUN "júní"
#define L_JUL "júlí"
#define L_AUG "ágúst"
#define L_SEP "september"
#define L_OCT "október"
#define L_NOV "nóvember"
#define L_OCT "október"
#define L_NOV "nóvember"
#define L_DEC "desember"
/* Today and tomorrow */
#define L_TODAY "í dag"
#define L_TOMORROW "á morgun"
#define L_TODAY "í dag"
#define L_TOMORROW "á morgun"
/* The default banner */
#define L_BANNER "Minnisatriði: %w, %d%s %m, %y%o:"
#define L_BANNER "Minnisatriði: %w, %d%s %m, %y%o:"
/* "am" and "pm" */
#define L_AM "fh"
#define L_PM "eh"
/*** The following are only used in dosubst.c ***/
#ifdef L_IN_DOSUBST
/* Ago and from now */
#define L_AGO "síðan"
#define L_FROMNOW "frá því nú"
#define L_AGO "síðan"
#define L_FROMNOW "frá því nú"
/* "in %d days' time" */
#define L_INXDAYS "eftir %d daga"
/* "on" as in "on date..." */
#define L_ON "þann"
#define L_ON "þann"
/* Pluralizing - this is a problem for many languages and may require
a more drastic fix */
#define L_PLURAL "a"
/* Minutes, hours, at, etc */
#define L_NOW "núna"
#define L_NOW "núna"
#define L_AT "kl."
#define L_MINUTE "mínútu"
#define L_MINUTE "mínútu"
#define L_HOUR "klukkustund"
#define L_IS "er"
#define L_WAS "var"
@@ -79,5 +76,3 @@
/* Define any overrides here, such as L_ORDINAL_OVERRIDE, L_A_OVER, etc.
See the file dosubst.c for more info. */
#endif /* L_IN_DOSUBST */

View File

@@ -7,7 +7,7 @@
/* This file is part of REMIND. */
/* It is Copyright (C) 1996 by Valerio Aimale */
/* */
/* Remind is copyright (C) 1992-2021 by Dianne Skoll */
/* Remind is copyright (C) 1992-2022 by Dianne Skoll */
/* */
/***************************************************************/
@@ -49,9 +49,6 @@
#define L_AM "am"
#define L_PM "pm"
/*** The following are only used in dosubst.c ***/
#ifdef L_IN_DOSUBST
/* Ago and from now */
#define L_AGO "fa"
#define L_FROMNOW "da oggi"
@@ -114,6 +111,3 @@
#define L_V_OVER sprintf(s, "%s, %d %s", DayName[jul%7], d, \
MonthName[m]);
#endif /* L_IN_DOSUBST */

View File

@@ -6,7 +6,7 @@
/* */
/* This file is part of REMIND. */
/* This file is Copyright (C) 1993 by Trygve Randen. */
/* Remind is Copyright (C) 1992-2021 by Dianne Skoll */
/* Remind is Copyright (C) 1992-2022 by Dianne Skoll */
/* */
/***************************************************************/
@@ -47,9 +47,6 @@
#define L_AM "am"
#define L_PM "pm"
/*** The following are only used in dosubst.c ***/
#ifdef L_IN_DOSUBST
/* Ago and from now */
#define L_AGO "siden"
#define L_FROMNOW "fra nå"
@@ -84,6 +81,3 @@
#define L_G_OVER if (altmode == '*') { sprintf(s, "%s, den %d. %s", DayName[jul%7], d, MonthName[m]); } else { sprintf(s, "%s %s, den %d. %s", L_ON, DayName[jul%7], d, MonthName[m]); }
#define L_U_OVER L_A_OVER
#define L_V_OVER L_G_OVER
#endif /* L_IN_DOSUBST */

View File

@@ -9,7 +9,7 @@
/* Polish. */
/* */
/* This file is part of REMIND. */
/* Copyright (C) 1992-2021 by Dianne Skoll */
/* Copyright (C) 1992-2022 by Dianne Skoll */
/* */
/***************************************************************/
@@ -50,9 +50,6 @@
#define L_AM "am"
#define L_PM "pm"
/*** The following are only used in dosubst.c ***/
#ifdef L_IN_DOSUBST
/* Ago and from now */
#define L_AGO "temu"
#define L_FROMNOW "od teraz"
@@ -75,13 +72,17 @@
# define L_IS "będzie"
# define L_WAS "było"
#define L_AND "i"
#define L_HPLU ""
#define L_MPLU ""
/* What to add to make "hour" or "minute" plural */
#define L_NPLU( N ) ((N == 1) ? "ę" : ((N==12) || (N==13) || (N==14)) ? "" : \
((N%10==2) || (N%10==3) || (N%10==4)) ? "y" : "" )
/* What to add to make "hour" plural */
#define L_HPLU L_NPLU( hdiff )
#define L_HPLU_OVER hplu = L_NPLU( hdiff );
/* What to add to make "minute" plural */
#define L_MPLU L_NPLU( mdiff )
#define L_MPLU_OVER mplu = L_NPLU( mdiff );
/* Define any overrides here, such as L_ORDINAL_OVERRIDE, L_A_OVER, etc.
See the file dosubst.c for more info. */
@@ -99,32 +100,30 @@ ampm = (hour<12) ? \
#define L_U_OVER L_A_OVER
#define L_V_OVER L_G_OVER
#endif /* L_IN_DOSUBST */
#define L_0_OVER sprintf(s, L_HPLU);
#define L_9_OVER sprintf(s, L_MPLU);
#define L_0_OVER sprintf(s, L_NPLU(hdiff));
#define L_9_OVER sprintf(s, L_NPLU(mdiff));
#define L_1_OVER \
if (tdiff == 0) \
sprintf(s, L_NOW); \
else if (tdiff > 0) \
{ \
if (hdiff == 0) \
sprintf(s, "za %d %s%s", mdiff, L_MINUTE, L_MPLU); \
sprintf(s, "za %d %s%s", mdiff, L_MINUTE, L_NPLU(mdiff)); \
else if (mdiff == 0) \
sprintf(s, "za %d %s%s", hdiff, L_HOUR, L_HPLU); \
sprintf(s, "za %d %s%s", hdiff, L_HOUR, L_NPLU(hdiff)); \
else \
sprintf(s, "za %d %s%s %s %d %s%s", hdiff, L_HOUR, L_HPLU, \
L_AND, mdiff, L_MINUTE, L_MPLU); \
sprintf(s, "za %d %s%s %s %d %s%s", hdiff, L_HOUR, L_NPLU(hdiff), \
L_AND, mdiff, L_MINUTE, L_NPLU(mdiff)); \
} \
else \
{ \
if (hdiff == 0) \
sprintf(s, "%d %s%s temu", mdiff, L_MINUTE, L_MPLU); \
sprintf(s, "%d %s%s temu", mdiff, L_MINUTE, L_NPLU(mdiff)); \
else if (mdiff == 0) \
sprintf(s, "%d %s%s temu", hdiff, L_HOUR, L_HPLU); \
sprintf(s, "%d %s%s temu", hdiff, L_HOUR, L_NPLU(hdiff)); \
else \
sprintf(s, "%d %s%s %s %d %s%s temu", hdiff, L_HOUR, L_HPLU, \
L_AND, mdiff, L_MINUTE, L_MPLU); \
sprintf(s, "%d %s%s %s %d %s%s temu", hdiff, L_HOUR, L_NPLU(hdiff), \
L_AND, mdiff, L_MINUTE, L_NPLU(mdiff)); \
}
/* The next ones are used only when MK_GLOBALS is set */
@@ -186,7 +185,7 @@ EXTERN char *ErrMsg[] =
"Miesiąc podany dwókrotnie",
"Dzień podany dwókrotnie",
"Nieznane słowo",
"W komendzie OMIT trzeba podać miesiąc i dzień",
"W komendzie OMIT trzeba podać miesiąc",
"Za dużo częściowych komend OMIT",
"Za dużo pełnych komend OMIT",
"Ostrzeżenie: PUSH-OMIT-CONTEXT bez POP-OMIT-CONTEXT",
@@ -244,7 +243,7 @@ EXTERN char *ErrMsg[] =
#define L_USAGE_OVERRIDE 1
void Usage(void)
{
fprintf(ErrFp, "\nREMIND %s (%s version) Copyright 1992-2021 Dianne Skoll\n", VERSION, L_LANGNAME);
fprintf(ErrFp, "\nREMIND %s (%s version) Copyright 1992-2022 Dianne Skoll\n", VERSION, L_LANGNAME);
#ifdef BETA
fprintf(ErrFp, ">>>> BETA VERSION <<<<\n");
#endif
@@ -270,7 +269,7 @@ void Usage(void)
fprintf(ErrFp, " -d... Odpluskwianie: e=echo x=expr-eval t=trig v=dumpvars l=showline\n");
fprintf(ErrFp, " -e Komunikaty o błędach skieruj na stdout\n");
fprintf(ErrFp, " -b[n] Format czasu: 0=am/pm, 1=24godz., 2=żaden\n");
fprintf(ErrFp, " -x[n] Limit powtórzeń klauzuli SATISFY (domyślnie=150)\n");
fprintf(ErrFp, " -x[n] Limit powtórzeń klauzuli SATISFY (domyślnie=1000)\n");
fprintf(ErrFp, " -kcmd Wywołaj 'cmd' dla przypomnień typu MSG\n");
fprintf(ErrFp, " -g[ddd] Sortuj przypomnienia według daty, czasu i priorytetu\n");
fprintf(ErrFp, " -ivar=val Zainicjuj zmienną var wartościa val i zachowaj ja\n");

View File

@@ -8,7 +8,7 @@
/* */
/* This file is part of REMIND. */
/* */
/* REMIND is Copyright (C) 1992-2021 by Dianne Skoll */
/* REMIND is Copyright (C) 1992-2022 by Dianne Skoll */
/* This file is Copyright (C) 1996 by Marco Paganini and */
/* Dianne Skoll. */
/* */
@@ -51,9 +51,6 @@
#define L_AM "am"
#define L_PM "pm"
/*** The following are only used in dosubst.c ***/
#ifdef L_IN_DOSUBST
/* Ago and from now */
#define L_AGO "atras"
#define L_FROMNOW "adiante"
@@ -138,8 +135,6 @@
} \
}
#endif /* L_IN_DOSUBST */
/* The next ones are used only when MK_GLOBALS is set */
#ifdef MK_GLOBALS
#define L_ERR_OVERRIDE 1
@@ -199,7 +194,7 @@ EXTERN char *ErrMsg[] =
"Mes especificado duas vezes",
"Dia especificado duas vezes",
"Token desconhecido",
"Mes e dia devem ser especificados no comando OMIT",
"O mes deve ser especificados no comando OMIT",
"Muitos OMITs parciais",
"Muitos OMITs full",
"Aviso: PUSH-OMIT-CONTEXT sem POP-OMIT-CONTEXT correspondente",
@@ -257,7 +252,7 @@ EXTERN char *ErrMsg[] =
#define L_USAGE_OVERRIDE 1
void Usage(void)
{
fprintf(ErrFp, "\nREMIND %s (versao %s) (C) 1992-2021 Dianne Skoll\n", VERSION, L_LANGNAME);
fprintf(ErrFp, "\nREMIND %s (versao %s) (C) 1992-2022 Dianne Skoll\n", VERSION, L_LANGNAME);
#ifdef BETA
fprintf(ErrFp, ">>>> VERSAO BETA <<<<\n");
#endif
@@ -283,7 +278,7 @@ void Usage(void)
fprintf(ErrFp, " -d... Debug: e=echo x=expr-eval t=trigger v=dumpvars l=showline\n");
fprintf(ErrFp, " -e Desvia mensagens normalmente enviadas a stderr para stdout\n");
fprintf(ErrFp, " -b[n] Formato da hora para o cal: 0=am/pm, 1=24hr, 2=nenhum\n");
fprintf(ErrFp, " -x[n] Limite de iteracoes para a clausula SATISFY (default=150)\n");
fprintf(ErrFp, " -x[n] Limite de iteracoes para a clausula SATISFY (default=1000)\n");
fprintf(ErrFp, " -kcmd Executa `cmd' para os compromissos com MSG\n");
fprintf(ErrFp, " -g[ddd] Classifica compromissos por data, hora e prioridade antes de exibir\n");
fprintf(ErrFp, " -ivar=val Inicializa (e preserva) variavel var com val\n");

View File

@@ -8,7 +8,7 @@
/* */
/* This file is part of REMIND. */
/* */
/* REMIND is Copyright (C) 1992-2021 by Dianne Skoll */
/* REMIND is Copyright (C) 1992-2022 by Dianne Skoll */
/* This file is Copyright (C) 1996-1998 by Liviu Daia */
/* */
/***************************************************************/
@@ -50,9 +50,6 @@
#define L_AM "am"
#define L_PM "pm"
#ifdef L_IN_DOSUBST
/*** The following are only used in dosubst.c ***/
/* Ago and from now */
#define L_AGO "acum"
#define L_FROMNOW "peste"
@@ -76,6 +73,7 @@
#define L_WAS "a fost"
/* What to add to make "minute" plural */
#define L_MPLU "e"
#define L_HPLU "e"
/* What to add to make "hour" plural */
#define L_HPLU_OVER hplu = (hdiff == 1 ? "ă" : "e");
@@ -104,5 +102,3 @@
else \
sprintf(s, "%s %d %s%s %s %d %s%s", when, hdiff, \
L_HOUR, hplu, L_AND, mdiff, L_MINUTE, mplu);
#endif /* L_IN_DOSUBST */

View File

@@ -7,7 +7,7 @@
/* Author: Rafa Couto <rafacouto@biogate.com> */
/* */
/* This file is part of REMIND. */
/* Copyright (C) 1992-2021 by Dianne Skoll */
/* Copyright (C) 1992-2022 by Dianne Skoll */
/* */
/***************************************************************/
@@ -47,9 +47,6 @@
#define L_AM "am"
#define L_PM "pm"
/*** The following are only used in dosubst.c ***/
#ifdef L_IN_DOSUBST
/* Hace y desde hoy */
#define L_AGO "hace"
#define L_FROMNOW "desde hoy"
@@ -74,5 +71,3 @@
#define L_HPLU "s"
#define L_MPLU "s"
#endif /* L_IN_DOSUBST */

View File

@@ -6,12 +6,14 @@
/* routines, etc. */
/* */
/* This file is part of REMIND. */
/* Copyright (C) 1992-2021 by Dianne Skoll */
/* Copyright (C) 1992-2022 by Dianne Skoll */
/* */
/***************************************************************/
#define _XOPEN_SOURCE 600
#include "config.h"
#include <errno.h>
#include <stdlib.h>
#include <unistd.h>
#include <stdio.h>
@@ -35,6 +37,10 @@
#endif
#include <sys/types.h>
#ifdef REM_USE_WCHAR
#include <wctype.h>
#include <wchar.h>
#endif
#include "types.h"
#include "protos.h"
@@ -67,6 +73,7 @@ int main(int argc, char *argv[])
ArgV = (char const **) argv;
InitRemind(argc, (char const **) argv);
DBufInit(&(LastTrigger.tags));
ClearLastTriggers();
if (DoCalendar || (DoSimpleCalendar && (!NextMode || PsCal))) {
@@ -169,6 +176,8 @@ static void DoReminders(void)
Parser p;
int purge_handled;
DidMsgReminder = 0;
if (!UseStdin) {
FileAccessDate = GetAccessDate(InitialFile);
} else {
@@ -176,7 +185,7 @@ static void DoReminders(void)
}
if (FileAccessDate < 0) {
fprintf(ErrFp, "%s: `%s'.\n", ErrMsg[E_CANTACCESS], InitialFile);
fprintf(ErrFp, "%s: `%s': %s.\n", ErrMsg[E_CANTACCESS], InitialFile, strerror(errno));
exit(1);
}
@@ -253,6 +262,7 @@ static void DoReminders(void)
case T_Flush: r=DoFlush(&p); break;
case T_Set: r=DoSet(&p); break;
case T_Fset: r=DoFset(&p); break;
case T_Funset: r=DoFunset(&p); break;
case T_UnSet: r=DoUnset(&p); break;
case T_Clr: r=DoClear(&p); break;
case T_Debug: r=DoDebug(&p); break;
@@ -329,7 +339,8 @@ int Julian(int year, int month, int day)
/* */
/* FromJulian */
/* */
/* Convert a Julian date to year, month, day. */
/* Convert a Julian date to year, month, day. You may supply */
/* NULL for y, m or d if you're not interested in that value */
/* */
/***************************************************************/
void FromJulian(int jul, int *y, int *m, int *d)
@@ -358,9 +369,15 @@ void FromJulian(int jul, int *y, int *m, int *d)
try_mon++;
t = DaysInMonth(try_mon, try_yr);
}
*y = try_yr;
*m = try_mon;
*d = jul + 1;
if (y) {
*y = try_yr;
}
if (m) {
*m = try_mon;
}
if (d) {
*d = jul + 1;
}
return;
}
@@ -568,6 +585,29 @@ int EvaluateExpr(ParsePtr p, Value *v)
return OK;
}
/***************************************************************/
/* */
/* Wprint - print a warning message. */
/* */
/***************************************************************/
void Wprint(char const *fmt, ...)
{
va_list argptr;
if (FileName) {
if (strcmp(FileName, "-"))
(void) fprintf(ErrFp, "%s(%d): ", FileName, LineNo);
else
(void) fprintf(ErrFp, "-stdin-(%d): ", LineNo);
}
va_start(argptr, fmt);
(void) vfprintf(ErrFp, fmt, argptr);
(void) fputc('\n', ErrFp);
va_end(argptr);
return;
}
/***************************************************************/
/* */
/* Eprint - print an error message. */
@@ -582,13 +622,23 @@ void Eprint(char const *fmt, ...)
if (FreshLine && FileName) {
FreshLine = 0;
if (strcmp(FileName, "-"))
if (strcmp(FileName, "-")) {
(void) fprintf(ErrFp, "%s(%d): ", FileName, LineNo);
else
if (print_callstack(ErrFp)) {
(void) fprintf(ErrFp, ": ");
}
} else {
(void) fprintf(ErrFp, "-stdin-(%d): ", LineNo);
if (print_callstack(ErrFp)) {
(void) fprintf(ErrFp, ": ");
}
}
if (DebugFlag & DB_PRTLINE) OutputLine(ErrFp);
} else if (FileName) {
fprintf(ErrFp, " ");
if (print_callstack(ErrFp)) {
(void) fprintf(ErrFp, ": ");
}
}
va_start(argptr, fmt);
@@ -824,19 +874,19 @@ int DoIfTrig(ParsePtr p)
Eprint("%s", ErrMsg[r]);
}
}
syndrome = IF_TRUE | BEFORE_ELSE;
syndrome = IF_FALSE | BEFORE_ELSE;
}
else {
if (ShouldTriggerReminder(&trig, &tim, jul, &err)) {
syndrome = IF_TRUE | BEFORE_ELSE;
} else {
syndrome = IF_FALSE | BEFORE_ELSE;
if (PurgeMode) {
PurgeEchoLine("%s\n", "#!P: The next IFTRIG did not trigger.");
PurgeEchoLine("%s\n", "#!P: REM statements in IFTRIG block not checked for purging.");
}
}
}
if (syndrome == (IF_FALSE | BEFORE_ELSE) && PurgeMode) {
PurgeEchoLine("%s\n", "#!P: The next IFTRIG did not trigger.");
PurgeEchoLine("%s\n", "#!P: REM statements in IFTRIG block not checked for purging.");
}
FreeTrig(&trig);
}
NumIfs++;
@@ -1112,8 +1162,8 @@ int DoErrMsg(ParsePtr p)
/* The array FoldArray[2][7] contains sample years which begin
on the specified weekday. For example, FoldArray[0][2] is a
non-leapyear beginning on Wednesday, and FoldArray[1][5] is a
leapyear beginning on Saturday. Used to fold back dates which
non-leap year beginning on Wednesday, and FoldArray[1][5] is a
leap year beginning on Saturday. Used to fold back dates which
are too high for the standard Unix representation.
NOTE: This implies that you cannot set BASE > 2001!!!!! */
static int FoldArray[2][7] = {
@@ -1143,6 +1193,8 @@ int CalcMinsFromUTC(int jul, int tim, int *mins, int *isdst)
local.tm_sec = 0;
local.tm_min = tim % 60;
local.tm_hour = tim / 60;
local.tm_mday = day;
local.tm_mon = mon;
local.tm_year = yr-1900;
@@ -1171,6 +1223,144 @@ int CalcMinsFromUTC(int jul, int tim, int *mins, int *isdst)
return 0;
}
static char const *OutputEscapeSequences(char const *s, int print)
{
while (*s == 0x1B && *(s+1) == '[') {
if (print) putchar(*s);
s++;
if (print) putchar(*s);
s++;
while (*s && (*s < 0x40 || *s > 0x7E)) {
if (print) putchar(*s);
s++;
}
if (*s) {
if (print) putchar(*s);
s++;
}
}
return s;
}
#ifdef REM_USE_WCHAR
#define ISWBLANK(c) (iswspace(c) && (c) != '\n')
static wchar_t const *OutputEscapeSequencesWS(wchar_t const *s, int print)
{
while (*s == 0x1B && *(s+1) == '[') {
if (print) PutWideChar(*s);
s++;
if (print) PutWideChar(*s);
s++;
while (*s && (*s < 0x40 || *s > 0x7E)) {
if (print) PutWideChar(*s);
s++;
}
if (*s) {
if (print) PutWideChar(*s);
s++;
}
}
return s;
}
static void
FillParagraphWCAux(wchar_t const *s)
{
int line = 0;
int i, j;
int doublespace = 1;
int pendspace;
int len;
wchar_t const *t;
int roomleft;
/* Start formatting */
while(1) {
/* If it's a carriage return, output it and start new paragraph */
if (*s == '\n') {
putchar('\n');
s++;
line = 0;
while(ISWBLANK(*s)) s++;
continue;
}
if (!*s) {
return;
}
/* Over here, we're at the beginning of a line. Emit the correct
number of spaces */
j = line ? SubsIndent : FirstIndent;
for (i=0; i<j; i++) {
putchar(' ');
}
/* Calculate the amount of room left on this line */
roomleft = FormWidth - j;
pendspace = 0;
/* Emit words until the next one won't fit */
while(1) {
while(ISWBLANK(*s)) s++;
if (*s == '\n') break;
while(1) {
t = s;
s = OutputEscapeSequencesWS(s, 1);
if (s == t) break;
while(ISWBLANK(*s)) s++;
}
t = s;
len = 0;
while(*s && !iswspace(*s)) {
if (*s == 0x1B && *(s+1) == '[') {
s = OutputEscapeSequencesWS(s, 0);
continue;
}
len += wcwidth(*s);
s++;
}
if (s == t) {
return;
}
if (!pendspace || len+pendspace <= roomleft) {
for (i=0; i<pendspace; i++) {
putchar(' ');
}
while(t < s) {
PutWideChar(*t);
if (strchr(EndSent, *t)) doublespace = 2;
else if (!strchr(EndSentIg, *t)) doublespace = 1;
t++;
}
} else {
s = t;
putchar('\n');
line++;
break;
}
roomleft -= len+doublespace;
pendspace = doublespace;
}
}
}
static int
FillParagraphWC(char const *s)
{
size_t len;
wchar_t *buf;
len = mbstowcs(NULL, s, 0);
if (len == (size_t) -1) return E_NO_MEM;
buf = calloc(len+1, sizeof(wchar_t));
if (!buf) return E_NO_MEM;
(void) mbstowcs(buf, s, len+1);
FillParagraphWCAux(buf);
free(buf);
return OK;
}
#endif
/***************************************************************/
/* */
/* FillParagraph */
@@ -1197,11 +1387,17 @@ void FillParagraph(char const *s)
char const *t;
int roomleft;
if (!s || !*s) return;
/* Skip leading spaces */
while(ISBLANK(*s)) s++;
if (!*s) return;
#ifdef REM_USE_WCHAR
if (FillParagraphWC(s) == OK) {
return;
}
#endif
/* Start formatting */
while(1) {
@@ -1232,10 +1428,23 @@ void FillParagraph(char const *s)
while(1) {
while(ISBLANK(*s)) s++;
if (*s == '\n') break;
while(1) {
t = s;
s = OutputEscapeSequences(s, 1);
if (s == t) break;
while(ISBLANK(*s)) s++;
}
t = s;
while(*s && !isspace(*s)) s++;
len = s - t;
if (!len) {
len = 0;
while(*s && !isspace(*s)) {
if (*s == 0x1B && *(s+1) == '[') {
s = OutputEscapeSequences(s, 0);
continue;
}
s++;
len++;
}
if (s == t) {
return;
}
if (!pendspace || len+pendspace <= roomleft) {
@@ -1324,13 +1533,23 @@ void UTCToLocal(int utcdate, int utctime, int *locdate, int *loctime)
/* command-line flag is supplied. */
/* */
/***************************************************************/
static sig_atomic_t got_sigint = 0;
void SigIntHandler(int d)
void
SigIntHandler(int d)
{
UNUSED(d);
signal(SIGINT, SigIntHandler);
GotSigInt();
exit(0);
got_sigint = 1;
}
int
GotSigInt(void)
{
if (got_sigint) {
got_sigint = 0;
return 1;
}
return 0;
}
void
@@ -1371,6 +1590,7 @@ ClearLastTriggers(void)
LastTrigger.warn[0] = 0;
LastTrigger.omitfunc[0] = 0;
LastTrigger.passthru[0] = 0;
DBufFree(&(LastTrigger.tags));
LastTimeTrig.ttime = NO_TIME;
LastTimeTrig.delta = NO_DELTA;
@@ -1391,8 +1611,10 @@ SaveAllTriggerInfo(Trigger const *t, TimeTrig const *tt, int trigdate, int trigt
void
SaveLastTrigger(Trigger const *t)
{
DBufFree(&(LastTrigger.tags));
memcpy(&LastTrigger, t, sizeof(LastTrigger));
DBufInit(&(LastTrigger.tags));
DBufPuts(&(LastTrigger.tags), DBufValue(&(t->tags)));
}
void

View File

@@ -5,7 +5,7 @@
/* Calculations for figuring out moon phases. */
/* */
/* This file is part of REMIND. */
/* Copyright (C) 1992-2021 by Dianne Skoll */
/* Copyright (C) 1992-2022 by Dianne Skoll */
/* */
/***************************************************************/
@@ -400,8 +400,8 @@ static double phase(double pdate,
double *suangdia)
{
double Day, N, M, Ec, Lambdasun, ml, MM, MN, Ev, Ae, A3, MmP,
mEc, A4, lP, V, lPP, NP, y, x, Lambdamoon,
double Day, N, M, Ec, Lambdasun, ml, MM, Ev, Ae, A3, MmP,
mEc, A4, lP, V, lPP,
MoonAge, MoonPhase,
MoonDist, MoonDFrac, MoonAng,
F, SunDist, SunAng;
@@ -431,9 +431,6 @@ static double phase(double pdate,
/* Moon's mean anomaly */
MM = fixangle(ml - 0.1114041 * Day - mmlongp);
/* Moon's ascending node mean longitude */
MN = fixangle(mlnode - 0.0529539 * Day);
/* Evection */
Ev = 1.2739 * sin(torad(2 * (ml - Lambdasun) - MM));
@@ -461,19 +458,6 @@ static double phase(double pdate,
/* 1 longitude */
lPP = lP + V;
/* Corrected longitude of the node */
NP = MN - 0.16 * sin(torad(M));
/* Y inclination coordinate */
y = sin(torad(lPP - NP)) * cos(torad(minc));
/* X inclination coordinate */
x = cos(torad(lPP - NP));
/* Ecliptic longitude */
Lambdamoon = todeg(atan2(y, x));
Lambdamoon += NP;
/* Calculation of the phase of the Moon */
/* Age of the Moon in degrees */

View File

@@ -6,7 +6,7 @@
/* the data structures for OMITted dates. */
/* */
/* This file is part of REMIND. */
/* Copyright (C) 1992-2021 by Dianne Skoll */
/* Copyright (C) 1992-2022 by Dianne Skoll */
/* */
/***************************************************************/
@@ -28,6 +28,8 @@ static void InsertIntoSortedArray (int *array, int num, int key);
static int FullOmitArray[MAX_FULL_OMITS];
static int PartialOmitArray[MAX_PARTIAL_OMITS];
/* WeekdayOmits is declared in global.h */
/* How many of each omit types do we have? */
static int NumFullOmits, NumPartialOmits;
@@ -37,6 +39,7 @@ typedef struct omitcontext {
int numfull, numpart;
int *fullsave;
int *partsave;
int weekdaysave;
} OmitContext;
/* The stack of saved omit contexts */
@@ -52,6 +55,7 @@ static OmitContext *SavedOmitContexts = NULL;
int ClearGlobalOmits(void)
{
NumFullOmits = NumPartialOmits = 0;
WeekdayOmits = 0;
return OK;
}
@@ -113,6 +117,7 @@ int PushOmitContext(ParsePtr p)
context->numfull = NumFullOmits;
context->numpart = NumPartialOmits;
context->weekdaysave = WeekdayOmits;
context->fullsave = malloc(NumFullOmits * sizeof(int));
if (NumFullOmits && !context->fullsave) {
free(context);
@@ -154,6 +159,7 @@ int PopOmitContext(ParsePtr p)
if (!c) return E_POP_NO_PUSH;
NumFullOmits = c->numfull;
NumPartialOmits = c->numpart;
WeekdayOmits = c->weekdaysave;
/* Copy the context over */
for (i=0; i<NumFullOmits; i++)
@@ -213,6 +219,12 @@ int IsOmitted(int jul, int localomit, char const *omitfunc, int *omit)
return OK;
}
/* Is it omitted because of global weekday omits? */
if (WeekdayOmits & (1 << (jul % 7))) {
*omit = 1;
return OK;
}
/* Is it omitted because of fully-specified omits? */
if (BexistsIntArray(FullOmitArray, NumFullOmits, jul)) {
*omit = 1;
@@ -271,7 +283,6 @@ static void InsertIntoSortedArray(int *array, int num, int key)
*cur = key;
}
static int DoThroughOmit(ParsePtr p, int y, int m, int d);
static void DumpOmits(void);
/***************************************************************/
@@ -283,11 +294,16 @@ static void DumpOmits(void);
/***************************************************************/
int DoOmit(ParsePtr p)
{
int y = NO_YR, m = NO_MON, d = NO_DAY, r;
int y[2] = {NO_YR, NO_YR}, m[2] = {NO_MON, NO_MON}, d[2] = {NO_DAY, NO_DAY}, r;
Token tok;
int parsing=1;
int parsing = 1;
int seen_through = 0;
int syndrome;
int not_first_token = -1;
int start, end, tmp;
int wd = 0;
int mc, dc;
DynamicBuffer buf;
DBufInit(&buf);
@@ -298,9 +314,15 @@ int DoOmit(ParsePtr p)
if ( (r=ParseToken(p, &buf)) ) return r;
FindToken(DBufValue(&buf), &tok);
switch (tok.type) {
case T_Dumpvars:
if (not_first_token) return E_PARSE_ERR;
case T_WkDay:
DBufFree(&buf);
if (wd & (1 << tok.val)) return E_WD_TWICE;
wd |= (1 << tok.val);
break;
case T_Dumpvars:
DBufFree(&buf);
if (not_first_token) return E_PARSE_ERR;
r = VerifyEoln(p);
if (r != OK) return r;
DumpOmits();
@@ -308,28 +330,28 @@ int DoOmit(ParsePtr p)
case T_Date:
DBufFree(&buf);
if (y != NO_YR) return E_YR_TWICE;
if (m != NO_MON) return E_MON_TWICE;
if (d != NO_DAY) return E_DAY_TWICE;
FromJulian(tok.val, &y, &m, &d);
if (y[seen_through] != NO_YR) return E_YR_TWICE;
if (m[seen_through] != NO_MON) return E_MON_TWICE;
if (d[seen_through] != NO_DAY) return E_DAY_TWICE;
FromJulian(tok.val, &y[seen_through], &m[seen_through], &d[seen_through]);
break;
case T_Year:
DBufFree(&buf);
if (y != NO_YR) return E_YR_TWICE;
y = tok.val;
if (y[seen_through] != NO_YR) return E_YR_TWICE;
y[seen_through] = tok.val;
break;
case T_Month:
DBufFree(&buf);
if (m != NO_MON) return E_MON_TWICE;
m = tok.val;
if (m[seen_through] != NO_MON) return E_MON_TWICE;
m[seen_through] = tok.val;
break;
case T_Day:
DBufFree(&buf);
if (d != NO_DAY) return E_DAY_TWICE;
d = tok.val;
if (d[seen_through] != NO_DAY) return E_DAY_TWICE;
d[seen_through] = tok.val;
break;
case T_Delta:
@@ -338,8 +360,10 @@ int DoOmit(ParsePtr p)
case T_Through:
DBufFree(&buf);
if (y == NO_YR || m == NO_MON || d == NO_DAY) return E_INCOMPLETE;
return DoThroughOmit(p, y, m, d);
if (wd) return E_PARSE_ERR;
if (seen_through) return E_UNTIL_TWICE;
seen_through = 1;
break;
case T_Empty:
case T_Comment:
@@ -358,26 +382,97 @@ int DoOmit(ParsePtr p)
return E_UNKNOWN_TOKEN;
}
}
if (m == NO_MON || d == NO_DAY) return E_SPEC_MON_DAY;
if (y == NO_YR) {
if (NumPartialOmits == MAX_PARTIAL_OMITS) return E_2MANY_PART;
if (wd) {
if (y[0] != NO_YR || m[0] != NO_MON || d[0] != NO_DAY) {
return E_PARSE_ERR;
}
if ((WeekdayOmits | wd) == 0x7F) {
return E_2MANY_LOCALOMIT;
}
WeekdayOmits |= wd;
if (tok.type == T_Tag || tok.type == T_Duration || tok.type == T_RemType || tok.type == T_Priority) return E_PARSE_AS_REM;
return OK;
}
if (d > MonthDays[m]) return E_BAD_DATE;
syndrome = (m<<5) + d;
if (!BexistsIntArray(PartialOmitArray, NumPartialOmits, syndrome)) {
InsertIntoSortedArray(PartialOmitArray, NumPartialOmits, syndrome);
NumPartialOmits++;
}
if (!seen_through) {
/* We must have at least a month */
if (m[0] == NO_MON) return E_SPEC_MON;
m[1] = m[0];
y[1] = y[0];
if (d[0] == NO_DAY) {
d[0] = 1;
if (y[0] == NO_YR) {
d[1] = MonthDays[m[0]];
} else {
d[1] = DaysInMonth(m[0], y[0]);
}
} else {
d[1] = d[0];
m[1] = m[0];
y[1] = y[0];
}
} else {
if (d > DaysInMonth(m, y)) return E_BAD_DATE;
syndrome = Julian(y, m, d);
r = AddGlobalOmit(syndrome);
if (r) {
return r;
if (m[0] == NO_MON) return E_SPEC_MON;
if (m[1] == NO_MON) return E_SPEC_MON;
if ((y[0] != NO_YR && y[1] == NO_YR) ||
(y[0] == NO_YR && y[1] != NO_YR)) {
return E_BAD_DATE;
}
if (d[0] == NO_DAY) d[0] = 1;
if (d[1] == NO_DAY) {
if (y[1] == NO_YR) {
d[1] = MonthDays[m[1]];
} else {
d[1] = DaysInMonth(m[1], y[1]);
}
}
}
if (y[0] == NO_YR) {
/* Partial OMITs */
if (d[0] > MonthDays[m[0]]) return E_BAD_DATE;
if (d[1] > MonthDays[m[1]]) return E_BAD_DATE;
dc = d[0];
mc = m[0];
while(1) {
syndrome = (mc<<5) + dc;
if (!BexistsIntArray(PartialOmitArray, NumPartialOmits, syndrome)) {
InsertIntoSortedArray(PartialOmitArray, NumPartialOmits, syndrome);
NumPartialOmits++;
}
if (mc == m[1] && dc == d[1]) {
break;
}
dc++;
if (dc > MonthDays[mc]) {
dc = 1;
mc++;
if (mc > 11) {
mc = 0;
}
}
}
} else {
/* Full OMITs */
if (d[0] > DaysInMonth(m[0], y[0])) return E_BAD_DATE;
if (d[1] > DaysInMonth(m[1], y[1])) return E_BAD_DATE;
start = Julian(y[0], m[0], d[0]);
end = Julian(y[1], m[1], d[1]);
if (end < start) {
Eprint("Error: THROUGH date earlier than start date");
return E_BAD_DATE;
}
for (tmp = start; tmp <= end; tmp++) {
if (!BexistsIntArray(FullOmitArray, NumFullOmits, tmp)) {
if (NumFullOmits >= MAX_FULL_OMITS) return E_2MANY_FULL;
InsertIntoSortedArray(FullOmitArray, NumFullOmits, tmp);
NumFullOmits++;
}
}
}
if (tok.type == T_Tag || tok.type == T_Duration || tok.type == T_RemType || tok.type == T_Priority) return E_PARSE_AS_REM;
return OK;
@@ -394,95 +489,6 @@ AddGlobalOmit(int jul)
return OK;
}
static int
DoThroughOmit(ParsePtr p, int ystart, int mstart, int dstart)
{
int yend = NO_YR, mend = NO_MON, dend = NO_DAY, r;
int start, end, tmp;
int parsing = 1;
Token tok;
DynamicBuffer buf;
DBufInit(&buf);
while(parsing) {
if ( (r=ParseToken(p, &buf)) ) return r;
FindToken(DBufValue(&buf), &tok);
switch(tok.type) {
case T_Date:
DBufFree(&buf);
if (yend != NO_YR) return E_YR_TWICE;
if (mend != NO_MON) return E_MON_TWICE;
if (dend != NO_DAY) return E_DAY_TWICE;
FromJulian(tok.val, &yend, &mend, &dend);
break;
case T_Year:
DBufFree(&buf);
if (yend != NO_YR) return E_YR_TWICE;
yend = tok.val;
break;
case T_Month:
DBufFree(&buf);
if (mend != NO_MON) return E_MON_TWICE;
mend = tok.val;
break;
case T_Day:
DBufFree(&buf);
if (dend != NO_DAY) return E_DAY_TWICE;
dend = tok.val;
break;
case T_Empty:
case T_Comment:
case T_RemType:
case T_Priority:
case T_Tag:
case T_Duration:
DBufFree(&buf);
parsing = 0;
break;
default:
Eprint("%s: `%s' (OMIT)", ErrMsg[E_UNKNOWN_TOKEN],
DBufValue(&buf));
DBufFree(&buf);
return E_UNKNOWN_TOKEN;
}
}
if (yend == NO_YR || mend == NO_MON || dend == NO_DAY) return E_INCOMPLETE;
if (dend > DaysInMonth(mend, yend)) return E_BAD_DATE;
if (dstart > DaysInMonth(mstart, ystart)) return E_BAD_DATE;
start = Julian(ystart, mstart, dstart);
end = Julian(yend, mend, dend);
if (end < start) {
Eprint("Warning: Swapping dates on OMIT ... THROUGH ... line");
tmp = start;
start = end;
end = tmp;
}
tmp = end - start + 1;
/* Don't create any OMITs if there would be too many. */
if (NumFullOmits + tmp >= MAX_FULL_OMITS) return E_2MANY_FULL;
for (tmp = start; tmp <= end; tmp++) {
if (!BexistsIntArray(FullOmitArray, NumFullOmits, tmp)) {
InsertIntoSortedArray(FullOmitArray, NumFullOmits, tmp);
NumFullOmits++;
}
}
if (tok.type == T_Tag || tok.type == T_Duration || tok.type == T_RemType || tok.type == T_Priority) return E_PARSE_AS_REM;
return OK;
}
void
DumpOmits(void)
{
@@ -508,5 +514,15 @@ DumpOmits(void)
printf("\t%02d%c%02d\n", m+1, DateSep, d);
}
}
printf("Global Weekday OMITs:\n");
if (WeekdayOmits == 0) {
printf("\tNone.\n");
} else {
for (i=0; i<7; i++) {
if (WeekdayOmits & (1<<i)) {
printf("\t%s\n", EnglishDayName[i]);
}
}
}
}

View File

@@ -5,7 +5,7 @@
/* Function Prototypes. */
/* */
/* This file is part of REMIND. */
/* Copyright (C) 1992-2021 by Dianne Skoll */
/* Copyright (C) 1992-2022 by Dianne Skoll */
/* */
/***************************************************************/
@@ -22,9 +22,11 @@
#define isempty(c) (isspace(c) || ((c) == '\\'))
#include "dynbuf.h"
#include <ctype.h>
int CallUserFunc (char const *name, int nargs, ParsePtr p);
int DoFset (ParsePtr p);
int DoFunset (ParsePtr p);
void ProduceCalendar (void);
char const *SimpleTime (int tim);
char const *CalendarTime (int tim, int duration);
@@ -62,6 +64,7 @@ int EvaluateExpr (ParsePtr p, Value *v);
int Evaluate (char const **s, Var *locals, ParsePtr p);
int FnPopValStack (Value *val);
void Eprint (char const *fmt, ...);
void Wprint (char const *fmt, ...);
void OutputLine (FILE *fp);
void CreateParser (char const *s, ParsePtr p);
void DestroyParser (ParsePtr p);
@@ -142,7 +145,7 @@ int MoonPhase (int date, int time);
void HuntPhase (int startdate, int starttim, int phas, int *date, int *time);
int CompareRems (int dat1, int tim1, int prio1, int dat2, int tim2, int prio2, int bydate, int bytime, int byprio, int untimed_first);
void SigIntHandler (int d);
void GotSigInt (void);
int GotSigInt (void);
void PurgeEchoLine(char const *fmt, ...);
void FreeTrig(Trigger *t);
void AppendTag(DynamicBuffer *buf, char const *s);
@@ -153,8 +156,8 @@ void SaveLastTimeTrig(TimeTrig const *t);
void SaveAllTriggerInfo(Trigger const *t, TimeTrig const *tt, int trigdate, int trigtime, int valid);
void PerIterationInit(void);
char const *Decolorize(int r, int g, int b);
char const *Colorize(int r, int g, int b);
char const *Decolorize(void);
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);
@@ -169,3 +172,15 @@ void set_components_from_lat_and_long(void);
char const *get_day_name(int wkday);
char const *get_month_name(int mon);
int push_call(char const *filename, char const *func, int lineno);
void clear_callstack(void);
int have_callstack(void);
int print_callstack(FILE *fp);
void pop_call(void);
#ifdef REM_USE_WCHAR
#define _XOPEN_SOURCE 600
#include <wctype.h>
#include <wchar.h>
void PutWideChar(wchar_t const wc);
#endif

View File

@@ -5,7 +5,7 @@
/* Queue up reminders for subsequent execution. */
/* */
/* This file is part of REMIND. */
/* Copyright (C) 1992-2021 by Dianne Skoll */
/* Copyright (C) 1992-2022 by Dianne Skoll */
/* */
/***************************************************************/
@@ -59,6 +59,7 @@ static QueuedRem *FindNextReminder (void);
static int CalculateNextTimeUsingSched (QueuedRem *q);
static void DaemonWait (struct timeval *sleep_tv);
static void reread (void);
static void PrintQueue(void);
/***************************************************************/
/* */
@@ -123,9 +124,10 @@ void HandleQueuedReminders(void)
Trigger trig;
struct timeval tv;
struct timeval sleep_tv;
struct sigaction sa;
/* Suppress the BANNER from being issued */
NumTriggered = 1;
DidMsgReminder = 1;
/* Turn off sorting -- otherwise, TriggerReminder has no effect! */
SortByDate = 0;
@@ -161,7 +163,11 @@ void HandleQueuedReminders(void)
q = q->next;
}
if (!DontFork || Daemon) signal(SIGINT, SigIntHandler);
if (!DontFork || Daemon) {
sa.sa_handler = SigIntHandler;
sa.sa_flags = 0;
(void) sigaction(SIGINT, &sa, NULL);
}
/* Sit in a loop, issuing reminders when necessary */
while(1) {
@@ -184,7 +190,9 @@ void HandleQueuedReminders(void)
while (TimeToSleep > 0L) {
SleepTime = TimeToSleep;
if (Daemon > 0 && SleepTime > (unsigned int) 60*Daemon) SleepTime = 60*Daemon;
if (Daemon > 0 && SleepTime > (unsigned int) 60*Daemon) {
SleepTime = 60*Daemon;
}
/* Wake up once a minute to recalibrate sleep time in
case of laptop hibernation */
@@ -203,6 +211,10 @@ void HandleQueuedReminders(void)
sleep(SleepTime);
}
if (GotSigInt()) {
PrintQueue();
}
/* If not in daemon mode and day has rolled around,
exit -- not much we can do. */
if (!Daemon) {
@@ -230,7 +242,7 @@ void HandleQueuedReminders(void)
/* Do NOT trigger the reminder if tt.nexttime is more than a
minute in the past. This can happen if the clock is
changed or a laptop awakes from hibernation.
However, DO triger if tt.nexttime == tt.ttime so all
However, DO trigger if tt.nexttime == tt.ttime so all
queued reminders are triggered at least once. */
if ((SystemTime(1) - (q->tt.nexttime * 60) <= 60) ||
(q->tt.nexttime == q->tt.ttime)) {
@@ -335,13 +347,13 @@ static QueuedRem *FindNextReminder(void)
/***************************************************************/
/* */
/* GotSigInt */
/* PrintQueue */
/* */
/* Split out what's done on a SIGINT from the SIGINT Handler. */
/* This will be necessary for OS/2 multithreaded. */
/* For debugging: Print queue contents to STDOUT */
/* */
/***************************************************************/
void GotSigInt(void)
static
void PrintQueue(void)
{
QueuedRem *q = QueueHead;
@@ -366,6 +378,7 @@ void GotSigInt(void)
q = q->next;
}
printf(NL);
printf("To terminate program, send SIGQUIT (probably Ctrl-\\ on the keyboard.)%s", NL);
}
/***************************************************************/

View File

@@ -5,7 +5,7 @@
/* Print a PostScript calendar. */
/* */
/* This file is part of REMIND. */
/* Copyright (C) 1992-2021 by Dianne Skoll */
/* Copyright (C) 1992-2022 by Dianne Skoll */
/* */
/***************************************************************/
@@ -349,7 +349,7 @@ int main(int argc, char *argv[])
!strcmp(DBufValue(&buf), PSBEGIN2)) {
if (!validfile) {
if (Verbose) {
fprintf(stderr, "Rem2PS: Version %s Copyright 1992-2021 by Dianne Skoll\n\n", VERSION);
fprintf(stderr, "Rem2PS: Version %s Copyright 1992-2022 by Dianne Skoll\n\n", VERSION);
fprintf(stderr, "Generating PostScript calendar\n");
}
}

View File

@@ -5,7 +5,7 @@
/* Define the PostScript prologue */
/* */
/* This file is part of REMIND. */
/* Copyright (C) 1992-2021 by Dianne Skoll */
/* Copyright (C) 1992-2022 by Dianne Skoll */
/* */
/***************************************************************/
@@ -13,7 +13,7 @@ char *PSProlog1[] =
{
"% This file was produced by Remind and Rem2PS, written by",
"% Dianne Skoll.",
"% Remind and Rem2PS are Copyright 1992-2021 Dianne Skoll.",
"% Remind and Rem2PS are Copyright 1992-2022 Dianne Skoll.",
"/ISOLatin1Encoding where { pop save true }{ false } ifelse",
" /ISOLatin1Encoding [ StandardEncoding 0 45 getinterval aload pop /minus",
" StandardEncoding 46 98 getinterval aload pop /dotlessi /grave /acute",

View File

@@ -5,7 +5,7 @@
/* Routines for sorting reminders by trigger date */
/* */
/* This file is part of REMIND. */
/* Copyright (C) 1992-2021 by Dianne Skoll */
/* Copyright (C) 1992-2022 by Dianne Skoll */
/* */
/***************************************************************/

View File

@@ -4,9 +4,23 @@
ALL=`grep ^#define lang.h | grep -v '#define LANG' | awk '{print $2}'`
OUTPUT_COMPILED=lang-compiled.out
OUTPUT_RUNTIME=lang-runtime.out
cat /dev/null > $OUTPUT_COMPILED
cat /dev/null > $OUTPUT_RUNTIME
for i in $ALL ; do
make clean
make -j`nproc` all LANGDEF=-DLANG=$i || exit 1
./remind -q -r ../tests/tstlang.rem
./remind -q -r ../tests/tstlang.rem >> $OUTPUT_COMPILED 2>&1
done
# Rebuild English version
make clean
make -j`nproc` all || exit 1
ALL=`ls ../include/lang/*.rem`
for i in $ALL; do
./remind -q -r "-ii=\"$i\"" ../tests/tstlang.rem >> $OUTPUT_RUNTIME 2>&1
done
exit 0

View File

@@ -6,7 +6,7 @@
/* classifying the tokens parsed. */
/* */
/* This file is part of REMIND. */
/* Copyright (C) 1992-2021 by Dianne Skoll */
/* Copyright (C) 1992-2022 by Dianne Skoll */
/* */
/***************************************************************/
@@ -43,30 +43,37 @@ Token TokArray[] = {
{ "at", 2, T_At, 0 },
{ "august", 3, T_Month, 7 },
{ "banner", 3, T_Banner, 0 },
{ "before", 3, T_Skip, BEFORE_SKIP },
{ "before", 3, T_Skip, BEFORE_SKIP },
{ "cal", 3, T_RemType, CAL_TYPE },
{ "clear-omit-context", 5, T_Clr, 0 },
{ "debug", 5, T_Debug, 0 },
{ "debug", 5, T_Debug, 0 },
{ "december", 3, T_Month, 11 },
{ "do", 2, T_IncludeR, 0 },
{ "dumpvars", 4, T_Dumpvars, 0 },
{ "dumpvars", 4, T_Dumpvars, 0 },
{ "duration", 3, T_Duration, 0 },
{ "else", 4, T_Else, 0 },
{ "else", 4, T_Else, 0 },
{ "endif", 5, T_EndIf, 0 },
{ "errmsg", 6, T_ErrMsg, 0 },
{ "errmsg", 6, T_ErrMsg, 0 },
{ "exit", 4, T_Exit, 0 },
{ "february", 3, T_Month, 1 },
{ "first", 5, T_Ordinal, 0 },
{ "flush", 5, T_Flush, 0 },
{ "fourth", 6, T_Ordinal, 3 },
{ "friday", 3, T_WkDay, 4 },
{ "from", 4, T_Scanfrom, FROM_TYPE },
{ "fset", 4, T_Fset, 0 },
{ "funset", 6, T_Funset, 0 },
{ "if", 2, T_If, 0 },
{ "iftrig", 6, T_IfTrig, 0 },
{ "in", 2, T_In, 0 },
{ "include", 3, T_Include, 0 },
{ "includecmd", 10, T_IncludeCmd, 0 },
{ "january", 3, T_Month, 0 },
{ "july", 3, T_Month, 6 },
{ "june", 3, T_Month, 5 },
{ "last", 4, T_Ordinal, -1 },
{ "lastday", 7, T_BackAdj, -1 },
{ "lastworkday", 11, T_BackAdj, 1 },
{ "march", 3, T_Month, 2 },
{ "may", 3, T_Month, 4 },
{ "maybe-uncomputable", 5, T_MaybeUncomputable, 0},
@@ -90,12 +97,14 @@ Token TokArray[] = {
{ "saturday", 3, T_WkDay, 5 },
{ "scanfrom", 4, T_Scanfrom, SCANFROM_TYPE },
{ "sched", 5, T_Sched, 0 },
{ "second", 6, T_Ordinal, 1 },
{ "september", 3, T_Month, 8 },
{ "set", 3, T_Set, 0 },
{ "skip", 3, T_Skip, SKIP_SKIP },
{ "special", 7, T_RemType, PASSTHRU_TYPE },
{ "sunday", 3, T_WkDay, 6 },
{ "tag", 3, T_Tag, 0 },
{ "third", 5, T_Ordinal, 2 },
{ "through", 7, T_Through, 0 },
{ "thursday", 3, T_WkDay, 3 },
{ "tuesday", 3, T_WkDay, 1 },
@@ -147,10 +156,6 @@ void FindToken(char const *s, Token *tok)
int top, bot, mid, r, max;
int l;
#if LANG != ENGLISH
size_t i;
#endif
tok->type = T_Illegal;
if (! *s) {
tok->type = T_Empty;
@@ -325,6 +330,14 @@ void FindNumericToken(char const *s, Token *t)
t->type = T_Back;
t->val *= mult;
return;
} else if (*s == '~') {
s++;
if (*s == '~') { mult = -1; s++; }
PARSENUM(t->val, s);
if (*s) return; /* Illegal token if followed by non-numeric char */
t->type = T_BackAdj;
t->val *= mult;
return;
}
return; /* Unknown token type */
}
@@ -342,7 +355,8 @@ static int TokStrCmp(Token const *t, char const *s)
register int r;
char const *tk = t->name;
while(*tk && *s && !(*s == ',' && *(s+1) == 0)) {
r = tolower(*tk) - tolower(*s);
/* t->name is already lower-case */
r = *tk - tolower(*s);
tk++;
s++;
if (r) return r;
@@ -350,5 +364,5 @@ static int TokStrCmp(Token const *t, char const *s)
/* Ignore trailing commas on s */
if (!*s || (*s == ',' && !*(s+1))) return 0;
return (tolower(*tk) - tolower(*s));
return (*tk - tolower(*s));
}

View File

@@ -5,7 +5,7 @@
/* Routines for figuring out the trigger date of a reminder */
/* */
/* This file is part of REMIND. */
/* Copyright (C) 1992-2021 by Dianne Skoll */
/* Copyright (C) 1992-2022 by Dianne Skoll */
/* */
/***************************************************************/
@@ -530,7 +530,7 @@ int ComputeTriggerNoAdjustDuration(int today, Trigger *trig, TimeTrig *tim,
*err = OK;
/* But check for obvious problems... */
if (trig->localomit == 1 + 2 + 4 + 8 + 16 + 32 + 64) {
if ((WeekdayOmits | trig->localomit) == 0x7F) {
*err = E_2MANY_LOCALOMIT;
return -1;
}

View File

@@ -5,7 +5,7 @@
/* Type definitions all dumped here. */
/* */
/* This file is part of REMIND. */
/* Copyright (C) 1992-2021 by Dianne Skoll */
/* Copyright (C) 1992-2022 by Dianne Skoll */
/* */
/***************************************************************/
@@ -69,6 +69,8 @@ typedef struct {
int once;
int scanfrom;
int from;
int adj_for_last; /* Adjust month/year for use of LAST */
int need_wkday; /* Set if we *need* a weekday */
int priority;
int duration_days; /* Duration converted to days to search */
int eventstart; /* Original event start (datetime) */
@@ -153,11 +155,12 @@ enum TokTypes
/* Commands first */
T_Rem, T_Push, T_Pop, T_Preserve, T_Include, T_IncludeR, T_IncludeCmd, T_If, T_Else, T_EndIf,
T_IfTrig, T_ErrMsg,
T_Set, T_UnSet, T_Fset, T_Omit, T_Banner, T_Exit,
T_Set, T_UnSet, T_Fset, T_Funset, T_Omit, T_Banner, T_Exit,
T_AddOmit,
T_WkDay,
T_Month, T_Time, T_Date, T_DateTime,
T_Skip, T_At, T_RemType, T_Until, T_Year, T_Day, T_Rep, T_Delta, T_Back,
T_Skip, T_At, T_RemType, T_Until, T_Year, T_Day, T_Rep, T_Delta,
T_Back, T_BackAdj,
T_Once,
T_Empty,
T_Comment,
@@ -175,7 +178,10 @@ enum TokTypes
T_LongTime,
T_OmitFunc,
T_Through,
T_MaybeUncomputable
T_MaybeUncomputable,
T_Ordinal,
T_In,
T_LastBack
};
/* The structure of a token */
@@ -232,6 +238,6 @@ typedef struct {
/* Pure JSON */
#define PSCAL_LEVEL3 3
#define TERMINAL_BACKGROUND_UNKNOWN 0
#define TERMINAL_BACKGROUND_DARK 1
#define TERMINAL_BACKGROUND_LIGHT 2
#define TERMINAL_BACKGROUND_UNKNOWN -1
#define TERMINAL_BACKGROUND_DARK 0
#define TERMINAL_BACKGROUND_LIGHT 1

View File

@@ -6,7 +6,7 @@
/* functions. */
/* */
/* This file is part of REMIND. */
/* Copyright (C) 1992-2021 by Dianne Skoll */
/* Copyright (C) 1992-2022 by Dianne Skoll */
/* */
/***************************************************************/
@@ -32,6 +32,8 @@ typedef struct udf_struct {
Var *locals;
char IsActive;
int nargs;
char const *filename;
int lineno;
} UserFunc;
/* The hash table */
@@ -51,6 +53,34 @@ static void FSet (UserFunc *f);
static int SetUpLocalVars (UserFunc *f);
static void DestroyLocalVals (UserFunc *f);
/***************************************************************/
/* */
/* DoFunset */
/* */
/* Undefine a user-defined function - the FUNSET command. */
/* */
/***************************************************************/
int DoFunset(ParsePtr p)
{
int r;
int seen_one = 0;
DynamicBuffer buf;
DBufInit(&buf);
while(1) {
r = ParseIdentifier(p, &buf);
if (r == E_EOLN) {
DBufFree(&buf);
break;
}
seen_one = 1;
FUnset(DBufValue(&buf));
DBufFree(&buf);
}
if (seen_one) return OK;
return E_PARSE_ERR;
}
/***************************************************************/
/* */
/* DoFset */
@@ -93,6 +123,11 @@ int DoFset(ParsePtr p)
DBufFree(&buf);
return E_NO_MEM;
}
func->filename = StrDup(FileName);
if (!func->filename) {
return E_NO_MEM;
}
func->lineno = LineNo;
StrnCpy(func->name, DBufValue(&buf), VAR_NAME_LEN);
DBufFree(&buf);
if (!Hush) {
@@ -167,7 +202,7 @@ int DoFset(ParsePtr p)
/* Add the function definition */
FSet(func);
if (orig_namelen > VAR_NAME_LEN) {
Eprint("Warning: Function name `%s...' truncated to `%s'",
Wprint("Warning: Function name `%s...' truncated to `%s'",
func->name, func->name);
}
return OK;
@@ -196,6 +231,9 @@ static void DestroyUserFunc(UserFunc *f)
/* Free the function definition */
if (f->text) free( (char *) f->text);
/* Free the filename */
if (f->filename) free( (char *) f->filename);
/* Free the data structure itself */
free(f);
}
@@ -306,7 +344,11 @@ int CallUserFunc(char const *name, int nargs, ParsePtr p)
/* Skip the opening bracket, if there's one */
while (isempty(*s)) s++;
if (*s == BEG_OF_EXPR) s++;
push_call(f->filename, f->name, f->lineno);
h = Evaluate(&s, f->locals, p);
if (h == OK) {
pop_call();
}
f->IsActive = 0;
DestroyLocalVals(f);
if (DebugFlag &DB_PRTEXPR) {

View File

@@ -5,7 +5,7 @@
/* Useful utility functions. */
/* */
/* This file is part of REMIND. */
/* Copyright (C) 1992-2021 by Dianne Skoll */
/* Copyright (C) 1992-2022 by Dianne Skoll */
/* */
/***************************************************************/
@@ -24,8 +24,6 @@ static char const DontEscapeMe[] =
#include "globals.h"
#include "protos.h"
#define UPPER(c) toupper(c)
/***************************************************************/
/* */
/* StrnCpy */
@@ -68,12 +66,12 @@ int StrinCmp(char const *s1, char const *s2, int n)
register int r;
while (n && *s1 && *s2) {
n--;
r = UPPER(*s1) - UPPER(*s2);
r = toupper(*s1) - toupper(*s2);
if (r) return r;
s1++;
s2++;
}
if (n) return (UPPER(*s1) - UPPER(*s2)); else return 0;
if (n) return (toupper(*s1) - toupper(*s2)); else return 0;
}
/***************************************************************/
@@ -102,12 +100,12 @@ int StrCmpi(char const *s1, char const *s2)
{
int r;
while (*s1 && *s2) {
r = UPPER(*s1) - UPPER(*s2);
r = toupper(*s1) - toupper(*s2);
if (r) return r;
s1++;
s2++;
}
return UPPER(*s1) - UPPER(*s2);
return toupper(*s1) - toupper(*s2);
}
/***************************************************************/
@@ -130,24 +128,33 @@ int DateOK(int y, int m, int d)
/* Functions designed to defeat gcc optimizer */
int _private_div(int a, int b) { return a/b; }
int _private_add_overflow(int result, int b, int old)
int _private_mul_overflow(int a, int b)
{
if (b > 0 && result < old) return 1;
if (b < 0 && result > old) return 1;
return 0;
}
int _private_sub_overflow(int result, int b, int old)
{
if (b < 0 && result < old) return 1;
if (b > 0 && result > old) return 1;
double aa = (double) a;
double bb = (double) b;
if (aa*bb > (double) INT_MAX || aa*bb < (double) INT_MIN) {
return 1;
}
return 0;
}
int _private_unminus_overflow(int a, int b)
int _private_add_overflow(int a, int b)
{
if (a > 0 && b > 0) return 1;
if (a < 0 && b < 0) return 1;
double aa = (double) a;
double bb = (double) b;
if (aa+bb < (double) INT_MIN) return 1;
if (aa+bb > (double) INT_MAX) return 1;
return 0;
}
int _private_sub_overflow(int a, int b)
{
double aa = (double) a;
double bb = (double) b;
if (aa-bb < (double) INT_MIN) return 1;
if (aa-bb > (double) INT_MAX) return 1;
return 0;
}
@@ -162,3 +169,90 @@ ShellEscape(char const *in, DynamicBuffer *out)
}
return OK;
}
/* Call-stack for printing errors from user-defined functions */
typedef struct cs_s {
struct cs_s *next;
char const *filename;
char const *func;
int lineno;
} cs;
static cs *callstack = NULL;
static void
destroy_cs(cs *entry)
{
if (entry->filename) free( (void *) entry->filename);
if (entry->func) free( (void *) entry->func);
free( (void *) entry);
}
int
push_call(char const *filename, char const *func, int lineno)
{
cs *entry = NEW(cs);
if (!entry) {
return E_NO_MEM;
}
entry->next = NULL;
entry->filename = StrDup(filename);
entry->func = StrDup(func);
entry->lineno = lineno;
if (!entry->filename || !entry->func) {
destroy_cs(entry);
return E_NO_MEM;
}
entry->next = callstack;
callstack = entry;
return OK;
}
void
clear_callstack(void)
{
cs *entry = callstack;
cs *next;
while(entry) {
next = entry->next;
destroy_cs(entry);
entry = next;
}
callstack = NULL;
}
int
have_callstack(void)
{
if (callstack) return 1;
return 0;
}
static void
print_callstack_aux(FILE *fp, cs *entry)
{
if (entry) {
print_callstack_aux(fp, entry->next);
fprintf(fp, "\n");
(void) fprintf(fp, "%s(%d): In function `%s'", entry->filename, entry->lineno, entry->func);
}
}
int
print_callstack(FILE *fp)
{
print_callstack_aux(fp, callstack);
if (callstack) return 1;
return 0;
}
void
pop_call(void)
{
cs *entry = callstack;
if (entry) {
callstack = entry->next;
destroy_cs(entry);
}
}

Some files were not shown because too many files have changed in this diff Show More