mirror of
https://salsa.debian.org/dskoll/remind.git
synced 2026-04-16 14:28:40 +02:00
Compare commits
909 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
72b0bf96fe | ||
|
|
3388849fa5 | ||
|
|
dc9650d5fa | ||
|
|
8eb40ae748 | ||
|
|
89184f1d0f | ||
|
|
e899c790b9 | ||
|
|
bd6d695020 | ||
|
|
20d4626a71 | ||
|
|
8ff94c5031 | ||
|
|
ee185a0eeb | ||
|
|
06f8932efd | ||
|
|
1dc627148c | ||
|
|
3cdde5351f | ||
|
|
6e93b8a73d | ||
|
|
267e8533cf | ||
|
|
d3bfb0a28f | ||
|
|
5a31bc7058 | ||
|
|
746bde71bd | ||
|
|
b274ac635c | ||
|
|
9e0a74e583 | ||
|
|
0f782f7697 | ||
|
|
8efde3e9af | ||
|
|
3bf3137dc4 | ||
|
|
63ec32d28d | ||
|
|
d2f4177cdb | ||
|
|
1d958fb7a8 | ||
|
|
fcd580d42e | ||
|
|
34dab68805 | ||
|
|
216dd03922 | ||
|
|
5eef9ac621 | ||
|
|
6b798d5f7c | ||
|
|
22ccce0934 | ||
|
|
fe2af14952 | ||
|
|
8e99ed27e7 | ||
|
|
bb12362cc8 | ||
|
|
1bfc630a64 | ||
|
|
987983f8ae | ||
|
|
657a6118aa | ||
|
|
43e7e6ec7f | ||
|
|
b8b3c19fbf | ||
|
|
69298c96a5 | ||
|
|
7356138872 | ||
|
|
616966f5df | ||
|
|
a59e277c21 | ||
|
|
740ae2c3e9 | ||
|
|
25b7a40f2b | ||
|
|
2beaab1a2f | ||
|
|
60793d53c6 | ||
|
|
4f869c8c81 | ||
|
|
8955180a35 | ||
|
|
a30cbf5797 | ||
|
|
b2bd6109dc | ||
|
|
9455ec48d7 | ||
|
|
f751f5defa | ||
|
|
994edbebbe | ||
|
|
70959b791c | ||
|
|
524ece5119 | ||
|
|
6334bd61b6 | ||
|
|
2e56edd557 | ||
|
|
8cae1d21cd | ||
|
|
1de6ed16eb | ||
|
|
860cb94f41 | ||
|
|
6b505704e9 | ||
|
|
167631451d | ||
|
|
fa5180b94d | ||
|
|
ae01d7be43 | ||
|
|
d5ce39ade1 | ||
|
|
a043dfe8b9 | ||
|
|
7cfb75e3b3 | ||
|
|
a18f0d982f | ||
|
|
0e2dc805c2 | ||
|
|
4c1e11df2c | ||
|
|
76776d054a | ||
|
|
45ebd05cb6 | ||
|
|
0203ce3979 | ||
|
|
72d10178bf | ||
|
|
96f4e26d53 | ||
|
|
4fd86f1b6a | ||
|
|
2f3ee0aec3 | ||
|
|
a5dde31160 | ||
|
|
b45428df05 | ||
|
|
d938763643 | ||
|
|
e4e2157622 | ||
|
|
04b349c6c7 | ||
|
|
7fe3eb7391 | ||
|
|
c1992b577a | ||
|
|
632283d47f | ||
|
|
1d9e46997c | ||
|
|
861ce34022 | ||
|
|
32e8db322d | ||
|
|
3df2b72175 | ||
|
|
e7ac4f95be | ||
|
|
e7ed69287b | ||
|
|
2e80417f53 | ||
|
|
ee435d2bb9 | ||
|
|
bb516946be | ||
|
|
81157e1cb5 | ||
|
|
51dfd707a2 | ||
|
|
7c3bf8601b | ||
|
|
714195efe5 | ||
|
|
eaeca2d09b | ||
|
|
ffa3b13437 | ||
|
|
2551e98d11 | ||
|
|
1bfd7761bc | ||
|
|
de9cb1d0a3 | ||
|
|
b2d32b514a | ||
|
|
6e53fd6924 | ||
|
|
8296d2b962 | ||
|
|
d6e66ee1e6 | ||
|
|
a49532b9c5 | ||
|
|
57d87f4caf | ||
|
|
ec9b30c616 | ||
|
|
27d8a62ab6 | ||
|
|
5077814c4a | ||
|
|
ca795a352a | ||
|
|
e59fc36458 | ||
|
|
39e3657539 | ||
|
|
6031f70701 | ||
|
|
3567c9e55f | ||
|
|
26de4e3fd3 | ||
|
|
cd65c6144d | ||
|
|
d32edbbb1f | ||
|
|
eae48a5538 | ||
|
|
63eba104d9 | ||
|
|
ae64961735 | ||
|
|
f7bb91320c | ||
|
|
c11071a859 | ||
|
|
53cbcc22db | ||
|
|
af9dcec3e9 | ||
|
|
d5a4b0d235 | ||
|
|
3b870403d9 | ||
|
|
284d822884 | ||
|
|
d881a26ad0 | ||
|
|
8519edde29 | ||
|
|
a30c467c48 | ||
|
|
887cd83ebe | ||
|
|
242d787ca2 | ||
|
|
5dd2cf7356 | ||
|
|
5efb70909d | ||
|
|
a60d466774 | ||
|
|
1c01f36271 | ||
|
|
3718632551 | ||
|
|
e8f3d5ff9f | ||
|
|
d77e27942d | ||
|
|
734cc61489 | ||
|
|
44d489d3d2 | ||
|
|
3e36ffa9ff | ||
|
|
12104a96b1 | ||
|
|
8ab8d65a15 | ||
|
|
f7a8122cef | ||
|
|
77d9bbb7d6 | ||
|
|
623def52fd | ||
|
|
d088e35142 | ||
|
|
5821e55eb8 | ||
|
|
1ee989c65d | ||
|
|
62388fb21f | ||
|
|
13571f84af | ||
|
|
03fdc06b65 | ||
|
|
4bce675ae6 | ||
|
|
7b64623115 | ||
|
|
e268bbf31d | ||
|
|
5863404de6 | ||
|
|
2de5996f4e | ||
|
|
695e79602a | ||
|
|
cf0d958da5 | ||
|
|
85b0348fa7 | ||
|
|
15a5d9a876 | ||
|
|
1baa6dab0c | ||
|
|
34bb250ba3 | ||
|
|
598b1b7464 | ||
|
|
e63d4be4e8 | ||
|
|
65561e7f34 | ||
|
|
da31dadb71 | ||
|
|
705adbb82a | ||
|
|
269f9788b6 | ||
|
|
5e1c5ae384 | ||
|
|
562eb83bde | ||
|
|
a53db00243 | ||
|
|
11375729db | ||
|
|
9fee354e6c | ||
|
|
ec76554d41 | ||
|
|
ddb0817c99 | ||
|
|
3d6ecd1f72 | ||
|
|
e3ec6565e9 | ||
|
|
8ed49ead7f | ||
|
|
49fbca416f | ||
|
|
82cd438fff | ||
|
|
946e1bca38 | ||
|
|
e40c81b5bf | ||
|
|
f23418480d | ||
|
|
bb4df39c50 | ||
|
|
5fec775863 | ||
|
|
a85980fec2 | ||
|
|
f3ea2962e6 | ||
|
|
3a5af23ab6 | ||
|
|
f9656edc51 | ||
|
|
5134b47d47 | ||
|
|
d4a183f3bf | ||
|
|
87e392de6c | ||
|
|
afc1667e64 | ||
|
|
8d25270c43 | ||
|
|
929866a770 | ||
|
|
395bad96a7 | ||
|
|
cd7be006c9 | ||
|
|
f658ba7ee7 | ||
|
|
7416f4c035 | ||
|
|
2860159ff7 | ||
|
|
64fa71ab09 | ||
|
|
ffbba7d4d1 | ||
|
|
fdcc2d8acf | ||
|
|
f1aa4d16af | ||
|
|
a55c5580f3 | ||
|
|
569e315306 | ||
|
|
acd641845d | ||
|
|
6b7e6f6788 | ||
|
|
4248b9c624 | ||
|
|
6de98d1357 | ||
|
|
18f21693af | ||
|
|
6fa500a860 | ||
|
|
941c02582e | ||
|
|
e56e3924d9 | ||
|
|
d1384a8f69 | ||
|
|
0488d689aa | ||
|
|
988a94e669 | ||
|
|
ac7e93ac1c | ||
|
|
bb7e9ee676 | ||
|
|
ac949ce7bd | ||
|
|
0fa8eed11f | ||
|
|
df8694a128 | ||
|
|
13df3d96e5 | ||
|
|
e345eb15f2 | ||
|
|
e8b2872a87 | ||
|
|
2f196e3c9f | ||
|
|
839b844a10 | ||
|
|
0cea410529 | ||
|
|
90397ece64 | ||
|
|
0b95fc290c | ||
|
|
9a4e8b6070 | ||
|
|
924fd16ade | ||
|
|
0815fe19cc | ||
|
|
7f445e1b66 | ||
|
|
31afc60af4 | ||
|
|
9d34a8aa42 | ||
|
|
91325ff489 | ||
|
|
1f99d6df59 | ||
|
|
8a608a06b8 | ||
|
|
bb34474e59 | ||
|
|
029c054489 | ||
|
|
01400d0672 | ||
|
|
a1eafb2c89 | ||
|
|
af88e393f9 | ||
|
|
3a250ce765 | ||
|
|
d651ac40a8 | ||
|
|
653324e220 | ||
|
|
e5c6703eaa | ||
|
|
1596d9c76a | ||
|
|
4aacf74e25 | ||
|
|
ae58bc7c11 | ||
|
|
387125d983 | ||
|
|
aa5f9297b2 | ||
|
|
8c4a7e766f | ||
|
|
d7f32d3901 | ||
|
|
d4f09e2a31 | ||
|
|
8b5fe4f2a0 | ||
|
|
98fc4a917f | ||
|
|
e633530a36 | ||
|
|
bfea9915b9 | ||
|
|
d68ed6e75d | ||
|
|
a22631d768 | ||
|
|
552bf84e33 | ||
|
|
28d0251093 | ||
|
|
f3d969f658 | ||
|
|
2afe95d090 | ||
|
|
3692a6b265 | ||
|
|
8fc19358bb | ||
|
|
c8f9773d83 | ||
|
|
e1091db82f | ||
|
|
9f8ed13434 | ||
|
|
914f03d5eb | ||
|
|
a801f6d4ce | ||
|
|
fde5a7b4ca | ||
|
|
0e1fff6339 | ||
|
|
60fdeac2e9 | ||
|
|
3b3f10d448 | ||
|
|
48a4314dd2 | ||
|
|
9beff3a24a | ||
|
|
1ef90c7a61 | ||
|
|
5c886d181e | ||
|
|
da4d830163 | ||
|
|
c7abb7986c | ||
|
|
5a3b3d8a06 | ||
|
|
127cee03df | ||
|
|
7455748d54 | ||
|
|
e278d0e768 | ||
|
|
a5acc12239 | ||
|
|
a25afb9771 | ||
|
|
6252a472b5 | ||
|
|
dbe4c662c1 | ||
|
|
b77a261c87 | ||
|
|
351c54cc50 | ||
|
|
72d0b13ad5 | ||
|
|
bea2a6541c | ||
|
|
5258e98f54 | ||
|
|
af9d42721c | ||
|
|
8ed43f5c3e | ||
|
|
ec02a87c2b | ||
|
|
6c2ec04d40 | ||
|
|
9f91cdf0b9 | ||
|
|
8ada68ce54 | ||
|
|
d7975634af | ||
|
|
87be68fecf | ||
|
|
b42d5fd412 | ||
|
|
603228b944 | ||
|
|
c62f676813 | ||
|
|
c7654c27a6 | ||
|
|
b00bf05fea | ||
|
|
29bd07d4ef | ||
|
|
b7047da89e | ||
|
|
f26334e25f | ||
|
|
b80bc5f788 | ||
|
|
91549e18ce | ||
|
|
07fd975935 | ||
|
|
f9d968cf68 | ||
|
|
6a7e696a60 | ||
|
|
6734fae1db | ||
|
|
481fbc20a1 | ||
|
|
3c120bf561 | ||
|
|
ee65e04974 | ||
|
|
4ee6bb0eca | ||
|
|
b9839421f2 | ||
|
|
67601507fa | ||
|
|
c2e5534462 | ||
|
|
f4ea3af6fc | ||
|
|
e0998a3991 | ||
|
|
d67e580d0a | ||
|
|
d6ce54eea4 | ||
|
|
8b9ec43029 | ||
|
|
9d68134f0f | ||
|
|
3d91371870 | ||
|
|
d1c0ef63b0 | ||
|
|
2a59da61e1 | ||
|
|
2bc5e21627 | ||
|
|
7d77bfd12a | ||
|
|
0ff589c288 | ||
|
|
f3cca092be | ||
|
|
7218d55f08 | ||
|
|
ec72c74016 | ||
|
|
c946f08235 | ||
|
|
a8543ac349 | ||
|
|
dd3c0e14ed | ||
|
|
a2bc0acd3c | ||
|
|
a34266741a | ||
|
|
dedb9766c9 | ||
|
|
aedd759f50 | ||
|
|
a24c2f6905 | ||
|
|
fac31a10b8 | ||
|
|
fba9f139ed | ||
|
|
588d9debe8 | ||
|
|
805c2e0c69 | ||
|
|
2c2b1440b3 | ||
|
|
6973f62d74 | ||
|
|
f547c1e714 | ||
|
|
f8ea124b1f | ||
|
|
820e2aec4d | ||
|
|
01ce6b2d8f | ||
|
|
b39e0eab7e | ||
|
|
d6fc451d74 | ||
|
|
ac91556fc2 | ||
|
|
ccf639efe6 | ||
|
|
a8aa3b328b | ||
|
|
74a3b3e73d | ||
|
|
c0e68b57ea | ||
|
|
0ad4ea26eb | ||
|
|
ea7aafaf5e | ||
|
|
18043080ba | ||
|
|
7cd8cf3a77 | ||
|
|
21da52ec36 | ||
|
|
7a0c164843 | ||
|
|
5cf4961f19 | ||
|
|
68926d145b | ||
|
|
fdc3e4d23d | ||
|
|
f179c837e1 | ||
|
|
740bb44956 | ||
|
|
5b953769fe | ||
|
|
1ae00ce778 | ||
|
|
a01e05c1db | ||
|
|
63fb3e99f3 | ||
|
|
6cf7f5d2d8 | ||
|
|
316eb43303 | ||
|
|
576112a39a | ||
|
|
6607223abb | ||
|
|
9e85b1932d | ||
|
|
4ba7f5b1f2 | ||
|
|
fc93ae890a | ||
|
|
8051d01945 | ||
|
|
63430c59f7 | ||
|
|
c646bfc63f | ||
|
|
58dea8f69b | ||
|
|
f1c82dcb37 | ||
|
|
b984b66819 | ||
|
|
44bdae302b | ||
|
|
8eb6b250fb | ||
|
|
d838c41bf2 | ||
|
|
f9dbf36496 | ||
|
|
fe1427db28 | ||
|
|
2621ad5604 | ||
|
|
efecf2e1ea | ||
|
|
8666e6357e | ||
|
|
ae7069c9cb | ||
|
|
0c6ab3e607 | ||
|
|
17d6a60c0a | ||
|
|
e3e0a541dc | ||
|
|
712aa08fbc | ||
|
|
98c5bf511e | ||
|
|
1f9281628f | ||
|
|
8fb15aed17 | ||
|
|
a24c3a8542 | ||
|
|
8f8059e3f3 | ||
|
|
24bb462199 | ||
|
|
38e914f171 | ||
|
|
4a02c54e8d | ||
|
|
5fe169438a | ||
|
|
a7ef6e851a | ||
|
|
4d57b9d0aa | ||
|
|
5a7452d9f6 | ||
|
|
3916887aff | ||
|
|
f84f59fa91 | ||
|
|
1032f8908e | ||
|
|
6c2e8fc608 | ||
|
|
012e527fb5 | ||
|
|
62198c9807 | ||
|
|
de95224d62 | ||
|
|
be374a0464 | ||
|
|
fe9b3186d7 | ||
|
|
8405ea6c53 | ||
|
|
4274d05e10 | ||
|
|
4e80ce1159 | ||
|
|
52f473f2af | ||
|
|
1d6ca51bf9 | ||
|
|
e662d0b3dd | ||
|
|
b910d557d1 | ||
|
|
a4ad0a9e97 | ||
|
|
07f67e7dd7 | ||
|
|
d6575773fb | ||
|
|
ac1303886e | ||
|
|
1569992184 | ||
|
|
55a1f1d746 | ||
|
|
ef7742a3cc | ||
|
|
ef48c2020b | ||
|
|
6dcb25073b | ||
|
|
4824b07ec8 | ||
|
|
a8f1228fb7 | ||
|
|
80e51d1d0f | ||
|
|
80e30638a5 | ||
|
|
dd2fc30364 | ||
|
|
a5865fb5fe | ||
|
|
aca2f28341 | ||
|
|
7a3f5f7ac9 | ||
|
|
1731710ef2 | ||
|
|
dc2a8f48bf | ||
|
|
5e16179bfa | ||
|
|
a7c1bc81b2 | ||
|
|
5f5ec8ef19 | ||
|
|
712ff56792 | ||
|
|
99af1f964c | ||
|
|
de5d1347e5 | ||
|
|
5e07fbde6d | ||
|
|
c523c7f3b3 | ||
|
|
6b3c6b0ec7 | ||
|
|
62b94ab065 | ||
|
|
49c7399599 | ||
|
|
5fa9297aba | ||
|
|
4ada31798b | ||
|
|
e78f953e90 | ||
|
|
af7a9ad8b5 | ||
|
|
35eae045a6 | ||
|
|
98a20ae058 | ||
|
|
df9ef6e13a | ||
|
|
10f5802069 | ||
|
|
780044219f | ||
|
|
d015c061e7 | ||
|
|
6f6326d433 | ||
|
|
9488e7ca13 | ||
|
|
71c11672c2 | ||
|
|
0acefa800e | ||
|
|
d45cee4712 | ||
|
|
c026aa05e2 | ||
|
|
50076c74fa | ||
|
|
1563d77c06 | ||
|
|
ed72ef8629 | ||
|
|
06c5996086 | ||
|
|
570ca857a0 | ||
|
|
f8f20b7afc | ||
|
|
f55ef7ff20 | ||
|
|
79220a74cf | ||
|
|
77111ef628 | ||
|
|
bf96063311 | ||
|
|
58a201fceb | ||
|
|
47cecb210b | ||
|
|
bfbf744b0a | ||
|
|
0cf56ac1de | ||
|
|
2880a718f4 | ||
|
|
da0dd0f7c6 | ||
|
|
c456d3e0ff | ||
|
|
59059736e6 | ||
|
|
f5cf2ab832 | ||
|
|
cc4ff2582d | ||
|
|
90f5fde3bb | ||
|
|
9fbe9f5132 | ||
|
|
f05661fa6c | ||
|
|
d6882c3378 | ||
|
|
e32cab937e | ||
|
|
14bb939977 | ||
|
|
13e830782d | ||
|
|
f39bb5e2d9 | ||
|
|
8b795e81b7 | ||
|
|
aef7eeda5a | ||
|
|
0641a6f8f1 | ||
|
|
4fdf7b706b | ||
|
|
0653b9420a | ||
|
|
27ede1ce37 | ||
|
|
a303fb9cba | ||
|
|
92af4e9c3e | ||
|
|
abc4f45fed | ||
|
|
e651f92bd9 | ||
|
|
b2d3d98d72 | ||
|
|
cb8b7f85af | ||
|
|
d30f347a0b | ||
|
|
5e9b1e7464 | ||
|
|
58085470c5 | ||
|
|
8f0de805d5 | ||
|
|
3f879a1b97 | ||
|
|
94270c3d98 | ||
|
|
bb8a689186 | ||
|
|
a7e73cdac8 | ||
|
|
d38c324340 | ||
|
|
fade38d522 | ||
|
|
858a7601aa | ||
|
|
37e3d3d1d1 | ||
|
|
ff67ab3c86 | ||
|
|
ad7faa8ad9 | ||
|
|
c927166a8a | ||
|
|
9d22fba842 | ||
|
|
3d5adf6c42 | ||
|
|
5ba862cbd7 | ||
|
|
6f20e056c9 | ||
|
|
878ab1a8bc | ||
|
|
4d17494371 | ||
|
|
65763b9522 | ||
|
|
52840d40de | ||
|
|
6892e7a805 | ||
|
|
24d0264f92 | ||
|
|
56c37e4e05 | ||
|
|
86c99102b5 | ||
|
|
de4a23ee1e | ||
|
|
6a9f7c186a | ||
|
|
eaed22a42b | ||
|
|
f47cf2320e | ||
|
|
eb100e57e2 | ||
|
|
948548c73f | ||
|
|
7495ae1e05 | ||
|
|
51ae17bd0a | ||
|
|
61d665ef7d | ||
|
|
5aaf19ffdb | ||
|
|
2eb672e380 | ||
|
|
4a59bf686b | ||
|
|
f98ab6f686 | ||
|
|
3600cd95cd | ||
|
|
f8bd79fbb2 | ||
|
|
4c403047eb | ||
|
|
25009de417 | ||
|
|
c4588654ec | ||
|
|
c1e5279272 | ||
|
|
cda8396690 | ||
|
|
c0f79d1e69 | ||
|
|
375a0fb7a2 | ||
|
|
2069114ef1 | ||
|
|
f6d9e8724d | ||
|
|
8e55438200 | ||
|
|
1ca6feb112 | ||
|
|
732ce8283f | ||
|
|
122bd3e07e | ||
|
|
0ac5cbb837 | ||
|
|
7f3d4812a8 | ||
|
|
e1fa11c94c | ||
|
|
c06c65acf1 | ||
|
|
a84fa0bc8f | ||
|
|
054648e02b | ||
|
|
9548041334 | ||
|
|
da306f2900 | ||
|
|
26587aea02 | ||
|
|
adc86e0f00 | ||
|
|
a9ed5f075e | ||
|
|
21e30c980e | ||
|
|
a657b2e55a | ||
|
|
ff8c55b8b6 | ||
|
|
eb36c5bca0 | ||
|
|
89173ce1ee | ||
|
|
5d115ba3e3 | ||
|
|
7e3adeb9c9 | ||
|
|
080cda86fa | ||
|
|
6274cbad52 | ||
|
|
85c4ad821d | ||
|
|
b758a2fea8 | ||
|
|
6619cc7ca4 | ||
|
|
961f7a8a62 | ||
|
|
905287901f | ||
|
|
669be7bf57 | ||
|
|
9b8eb2dc4c | ||
|
|
00ab7b196d | ||
|
|
f616be4bdd | ||
|
|
8ae9ce8523 | ||
|
|
6d2bbbd7e2 | ||
|
|
1453be83b2 | ||
|
|
8659131be2 | ||
|
|
0276ce322d | ||
|
|
b36c99a34b | ||
|
|
ad575f1485 | ||
|
|
a9162f1472 | ||
|
|
221e2554a9 | ||
|
|
04ec6c3695 | ||
|
|
b1594980fc | ||
|
|
024a8ef38d | ||
|
|
b281051421 | ||
|
|
aa1b275b51 | ||
|
|
c22ca68857 | ||
|
|
3804ce3fe3 | ||
|
|
0977f1db04 | ||
|
|
83c97934c9 | ||
|
|
44c9d74caa | ||
|
|
172f56754a | ||
|
|
dc184cc713 | ||
|
|
2c30088553 | ||
|
|
6f0c189afb | ||
|
|
0e2996c3e1 | ||
|
|
ce8040dd1f | ||
|
|
a8fd2d463d | ||
|
|
237813127c | ||
|
|
3e6259532f | ||
|
|
c015441130 | ||
|
|
9661455fee | ||
|
|
df983b4123 | ||
|
|
068d5429eb | ||
|
|
6c593fe849 | ||
|
|
6a7bdb2ec7 | ||
|
|
a4aead18dd | ||
|
|
d277154d9f | ||
|
|
d2662fb026 | ||
|
|
2f522ea705 | ||
|
|
cd68041312 | ||
|
|
9c2556f16d | ||
|
|
b80b938d3d | ||
|
|
0bd6278050 | ||
|
|
b2746f28db | ||
|
|
cfd3698b53 | ||
|
|
6b5150d30e | ||
|
|
b011adf94e | ||
|
|
d09b725710 | ||
|
|
2f1e3524df | ||
|
|
2de47cfa51 | ||
|
|
15a778075d | ||
|
|
2502191982 | ||
|
|
47af91d136 | ||
|
|
e249fe3a17 | ||
|
|
72838a07f3 | ||
|
|
c098acc659 | ||
|
|
15ee32b5bd | ||
|
|
5a059d9b09 | ||
|
|
77516dbdff | ||
|
|
835af9ad6a | ||
|
|
4c30db06c0 | ||
|
|
3aee12073e | ||
|
|
654fd78ee7 | ||
|
|
b8126d3a85 | ||
|
|
3054091688 | ||
|
|
6e0fd7ea5f | ||
|
|
bbb82029d2 | ||
|
|
716d7bcc92 | ||
|
|
e7a6bf0e19 | ||
|
|
27c17252e7 | ||
|
|
940254bec6 | ||
|
|
79952d52f1 | ||
|
|
e58545d3f6 | ||
|
|
b7c9643a05 | ||
|
|
c2be6c348a | ||
|
|
0161f81389 | ||
|
|
2a2df322dc | ||
|
|
b276b5fdce | ||
|
|
b5f7dabf10 | ||
|
|
307f8a07e0 | ||
|
|
3fe5e2becd | ||
|
|
e8a4acf517 | ||
|
|
9ba28c01e7 | ||
|
|
ff3b04f46d | ||
|
|
9f6f452b18 | ||
|
|
9b4e35841e | ||
|
|
927e260f5b | ||
|
|
949156f77c | ||
|
|
cc59fcac58 | ||
|
|
db624d8a8a | ||
|
|
ae90243352 | ||
|
|
ff58c7f699 | ||
|
|
bd9738f6f4 | ||
|
|
47e5c63290 | ||
|
|
2abdcac15c | ||
|
|
f0f12e4099 | ||
|
|
b1720317a4 | ||
|
|
d90f466b53 | ||
|
|
fec84a5efc | ||
|
|
1f3f869983 | ||
|
|
a6bd6f44bf | ||
|
|
78aac61fe1 | ||
|
|
8d735f0410 | ||
|
|
de014732c6 | ||
|
|
aae6511394 | ||
|
|
d973439b4f | ||
|
|
32adce2de8 | ||
|
|
2ac6378fea | ||
|
|
153b7df5fc | ||
|
|
9d9bdabf79 | ||
|
|
2f8eaeacf0 | ||
|
|
dc07a3cf32 | ||
|
|
b775e60d1b | ||
|
|
7290bccfd7 | ||
|
|
a1d884ec3f | ||
|
|
cc05d88618 | ||
|
|
2675fa53df | ||
|
|
59ee9198e2 | ||
|
|
5235936e7b | ||
|
|
03ab44ea10 | ||
|
|
b8c2d2b39b | ||
|
|
6ae7e71fbf | ||
|
|
c49740ed81 | ||
|
|
16c0a819a9 | ||
|
|
4a61fe73de | ||
|
|
a76feebe45 | ||
|
|
3a52eadeb1 | ||
|
|
dd56b7c385 | ||
|
|
f6f201085c | ||
|
|
daf09d9d4e | ||
|
|
511cdb2784 | ||
|
|
a567a9b777 | ||
|
|
05bc3af03d | ||
|
|
7a048d1702 | ||
|
|
8d7f9bcb8b | ||
|
|
9fd8b0f890 | ||
|
|
86873d0725 | ||
|
|
b22438b489 | ||
|
|
683b38a7ab | ||
|
|
d6b4fdd6d3 | ||
|
|
c996649954 | ||
|
|
d59ad77893 | ||
|
|
e637c20dee | ||
|
|
19dc588319 | ||
|
|
dc53ef2e71 | ||
|
|
e51d7f3c6d | ||
|
|
5a7e86e443 | ||
|
|
7f4edae006 | ||
|
|
2f4e1462e3 | ||
|
|
54f5d81a8c | ||
|
|
d33c27289a | ||
|
|
1675fdb499 | ||
|
|
9321109691 | ||
|
|
e6a4f939a3 | ||
|
|
c7ae214853 | ||
|
|
68a9cc047e | ||
|
|
1f2b25f852 | ||
|
|
20040c8857 | ||
|
|
ac64b0c11f | ||
|
|
ba47ce7ca8 | ||
|
|
be1ab4ea36 | ||
|
|
13cd9f3d04 | ||
|
|
8e1f82de5f | ||
|
|
8631ad3122 | ||
|
|
90e6aef9d7 | ||
|
|
698190fb72 | ||
|
|
27cfaa9404 | ||
|
|
9f296fe76d | ||
|
|
d0112adb08 | ||
|
|
75f4fe3595 | ||
|
|
211bfbc1e2 | ||
|
|
afaa1841fc | ||
|
|
027662c9c3 | ||
|
|
43e652321b | ||
|
|
83a2216d19 | ||
|
|
82ae568add | ||
|
|
2573003034 | ||
|
|
c33e873577 | ||
|
|
a1d03b8159 | ||
|
|
762530f6ab | ||
|
|
f53a3ecc69 | ||
|
|
1ed60fecee | ||
|
|
c1a12ea4e9 | ||
|
|
0efd235e36 | ||
|
|
c7be8c59f3 | ||
|
|
20bb3eb674 | ||
|
|
cde0e5883e | ||
|
|
0b43099621 | ||
|
|
386f36c3ae | ||
|
|
b391b2129e | ||
|
|
5478673bda | ||
|
|
6295048b3e | ||
|
|
4fa956aa27 | ||
|
|
21cce0e104 | ||
|
|
b14e72ddf7 | ||
|
|
7a34b6e18d | ||
|
|
ddc0e8eb45 | ||
|
|
7648ee6e54 | ||
|
|
2b86c912e3 | ||
|
|
342acedbec | ||
|
|
a83bf495b1 | ||
|
|
899829f1ac | ||
|
|
408a62115e | ||
|
|
430d0990aa | ||
|
|
47d33e7aaf | ||
|
|
12f40cba6d | ||
|
|
ecc0e9609a | ||
|
|
eb35a843c1 | ||
|
|
79289fe6c4 | ||
|
|
cb841adf86 | ||
|
|
724d82e6d2 | ||
|
|
0532910604 | ||
|
|
f4f5552975 | ||
|
|
3e2794548b | ||
|
|
f7b8ee168f | ||
|
|
e3297fe751 | ||
|
|
58ca741a1c | ||
|
|
14dbbc7bb4 | ||
|
|
df55c4032b | ||
|
|
3768155a20 | ||
|
|
2f3b9cadf4 | ||
|
|
2c79a6531a | ||
|
|
be5c856f4b | ||
|
|
712a333f08 | ||
|
|
b753e84c8c | ||
|
|
4b4acaadbb | ||
|
|
8a52f9b67d | ||
|
|
e372606281 | ||
|
|
c443d0a9da | ||
|
|
42c9ae9ea8 | ||
|
|
dac9bb4187 | ||
|
|
812d926f66 | ||
|
|
45831ea69f | ||
|
|
354e1d236b | ||
|
|
ac478039cf | ||
|
|
96f5799e6f | ||
|
|
e21479f696 | ||
|
|
25dc883e15 | ||
|
|
bfb1374ee3 | ||
|
|
cacd8f9792 | ||
|
|
3e9053a3c6 | ||
|
|
5fa357fec2 | ||
|
|
f109c3d696 | ||
|
|
b097ce7279 | ||
|
|
1297854935 | ||
|
|
0a1d0011f6 | ||
|
|
20db1be0a0 | ||
|
|
143f1d6144 | ||
|
|
358f6c9497 | ||
|
|
ca26544be8 | ||
|
|
5ceffddd5b | ||
|
|
8e3ddb96b3 | ||
|
|
377de36b35 | ||
|
|
4395e2f7ed | ||
|
|
1d0cc31b10 | ||
|
|
4b4b2ddcd4 | ||
|
|
3c9b5b786e | ||
|
|
08f1bea6ce | ||
|
|
a2cc5943e0 | ||
|
|
895ac6f0f7 | ||
|
|
759ca0253e | ||
|
|
0ca368c8d9 | ||
|
|
a467cc1b84 | ||
|
|
c65fd826a5 | ||
|
|
bd6f4e1b43 | ||
|
|
169520914f | ||
|
|
a163a0c446 | ||
|
|
295aeb0ed8 | ||
|
|
9b2fdad56c | ||
|
|
7a1184d3c5 | ||
|
|
b036244316 | ||
|
|
5ad5366e8a | ||
|
|
244677e524 | ||
|
|
f5a094a973 | ||
|
|
5681ebdb12 | ||
|
|
664fa5f08f | ||
|
|
14edec5eae | ||
|
|
6adfd2e739 | ||
|
|
34409f7a7d | ||
|
|
7e13d1052c | ||
|
|
eb1998c888 | ||
|
|
543252cbaf | ||
|
|
6df7c59876 | ||
|
|
f780e0afc3 | ||
|
|
310e8d3287 | ||
|
|
ba51bdf258 | ||
|
|
ef88b844fb | ||
|
|
67b96b0a26 | ||
|
|
562da30fb5 | ||
|
|
21175e8cf6 | ||
|
|
80d01f7158 | ||
|
|
90cac447e4 | ||
|
|
04bf5b0a8b | ||
|
|
d667c15b25 | ||
|
|
2123bf4b18 | ||
|
|
429a64f29e | ||
|
|
f39381dd6c | ||
|
|
0a9eb07f6f | ||
|
|
9c287e3fd7 |
3
.gitattributes
vendored
3
.gitattributes
vendored
@@ -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
2
.github/FUNDING.yml
vendored
Normal file
@@ -0,0 +1,2 @@
|
||||
|
||||
liberapay: dskoll
|
||||
7
.github/README.md
vendored
Normal file
7
.github/README.md
vendored
Normal 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
29
.github/workflows/github-action.yml
vendored
Normal 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 .
|
||||
37
.gitignore
vendored
37
.gitignore
vendored
@@ -1,16 +1,35 @@
|
||||
*.bak
|
||||
*.o
|
||||
*~
|
||||
.gitignore
|
||||
MYMETA.json
|
||||
MYMETA.yml
|
||||
Makefile
|
||||
TAGS
|
||||
autom4te.cache
|
||||
blib/
|
||||
config.log
|
||||
config.status
|
||||
src/Makefile
|
||||
www/Makefile
|
||||
*.o
|
||||
src/config.h
|
||||
src/remind
|
||||
man/rem.1
|
||||
man/rem2ps.1
|
||||
man/remind.1
|
||||
man/tkremind.1
|
||||
pm_to_blib
|
||||
rem2html/Makefile
|
||||
rem2html/rem2html
|
||||
rem2html/rem2html.1
|
||||
rem2pdf/Makefile.PL
|
||||
rem2pdf/Makefile.old
|
||||
rem2pdf/Makefile.top
|
||||
rem2pdf/bin/rem2pdf
|
||||
set-irc-topic
|
||||
src/*.tar.gz*
|
||||
tests/test.out
|
||||
.gitignore
|
||||
*~
|
||||
src/Makefile
|
||||
src/config.h
|
||||
src/rem2ps
|
||||
src/remind
|
||||
src/test-*.out
|
||||
src/version.h
|
||||
TAGS
|
||||
tests/test.out
|
||||
www/Makefile
|
||||
gmon.out
|
||||
|
||||
13
.gitlab-ci.yml
Normal file
13
.gitlab-ci.yml
Normal 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
|
||||
@@ -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-2020 Dianne Skoll, except where noted in
|
||||
2. REMIND is Copyright 1992-2024 Dianne Skoll, except where noted in
|
||||
individual files.
|
||||
|
||||
3. DISTRIBUTION AND USE
|
||||
@@ -16,7 +16,7 @@ individual files.
|
||||
Version 2, June 1991
|
||||
|
||||
Copyright (C) 1989, 1991 Free Software Foundation, Inc.
|
||||
675 Mass Ave, Cambridge, MA 02139, USA
|
||||
51 Franklin Street, Fifth Floor, Boston MA 02110-1301 USA
|
||||
Everyone is permitted to copy and distribute verbatim copies
|
||||
of this license document, but changing it is not allowed.
|
||||
|
||||
|
||||
38
Makefile
38
Makefile
@@ -1,4 +1,5 @@
|
||||
# Top-level Makefile for Remind.
|
||||
# SPDX-License-Identifier: GPL-2.0-only
|
||||
|
||||
all: src/Makefile
|
||||
@echo ""
|
||||
@@ -9,26 +10,41 @@ all: src/Makefile
|
||||
@echo "*******************"
|
||||
@echo ""
|
||||
@cd src && $(MAKE) all LANGDEF=$(LANGDEF)
|
||||
|
||||
@$(MAKE) -C rem2pdf -f Makefile.top
|
||||
install:
|
||||
@echo ""
|
||||
@echo "*********************"
|
||||
@echo "* *"
|
||||
@echo "* Installing REMIND *"
|
||||
@echo "* *"
|
||||
@echo "*********************"
|
||||
@echo "**********************************"
|
||||
@echo "* *"
|
||||
@echo "* Installing REMIND (unstripped) *"
|
||||
@echo "* *"
|
||||
@echo "**********************************"
|
||||
@echo ""
|
||||
@cd src && $(MAKE) install
|
||||
|
||||
@$(MAKE) -C src install
|
||||
@$(MAKE) -C rem2html install
|
||||
@$(MAKE) -C rem2pdf -f Makefile.top install INSTALL_BASE=$(INSTALL_BASE)
|
||||
clean:
|
||||
find . -name '*~' -exec rm {} \;
|
||||
cd src && $(MAKE) 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:
|
||||
@cd src && $(MAKE) -s test
|
||||
@$(MAKE) -C src -s test
|
||||
|
||||
distclean: clean
|
||||
rm -f config.cache config.log config.status src/Makefile src/config.h tests/test.out www/Makefile
|
||||
rm -f config.cache config.log config.status src/Makefile src/config.h tests/test.out www/Makefile rem2pdf/Makefile.top rem2pdf/Makefile.old rem2pdf/Makefile rem2pdf/Makefile.PL rem2pdf/bin/rem2pdf rem2html/rem2html
|
||||
|
||||
src/Makefile: src/Makefile.in
|
||||
./configure
|
||||
|
||||
40
README
40
README
@@ -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/
|
||||
|
||||
113
build.tk
Normal file → Executable file
113
build.tk
Normal file → Executable file
@@ -1,5 +1,6 @@
|
||||
#!/bin/sh
|
||||
# -*-Mode: TCL;-*-
|
||||
# SPDX-License-Identifier: GPL-2.0-only
|
||||
|
||||
#--------------------------------------------------------------
|
||||
# BUILD.TK
|
||||
@@ -26,17 +27,15 @@ exec wish "$0" "$@"
|
||||
proc SetConfigDefaults {} {
|
||||
global Config
|
||||
set Config(LAT_DEG) 45
|
||||
set Config(LAT_MIN) 24
|
||||
set Config(LAT_MIN) 25
|
||||
set Config(LAT_SEC) 14
|
||||
set Config(LON_DEG) 75
|
||||
set Config(LON_MIN) 39
|
||||
set Config(LON_MIN) 41
|
||||
set Config(LON_SEC) 23
|
||||
set Config(LOCATION) "Ottawa"
|
||||
set Config(DEFAULT_PAGE) "Letter"
|
||||
set Config(DATESEP) "-"
|
||||
set Config(TIMESEP) ":"
|
||||
set Config(ISOLATIN1) 0
|
||||
set Config(IBMEXTENDED) 0
|
||||
set Config(ISOLATIN2) 0
|
||||
set Config(IBM852) 0
|
||||
set Config(NORTHERN_HEMISPHERE) 1
|
||||
set Config(WESTERN_HEMISPHERE) 1
|
||||
set Config(LANGUAGE) "English"
|
||||
@@ -161,10 +160,14 @@ proc CreateLocationDialog { w } {
|
||||
-from 0 -to 89 -length 300 -variable Config(LAT_DEG)
|
||||
scale $w.latmin -label "Latitude (minutes)" -orient horizontal \
|
||||
-from 0 -to 59 -length 300 -variable Config(LAT_MIN)
|
||||
scale $w.latsec -label "Latitude (seconds)" -orient horizontal \
|
||||
-from 0 -to 59 -length 300 -variable Config(LAT_SEC)
|
||||
scale $w.londeg -label "Longitude (degrees)" -orient horizontal \
|
||||
-from 0 -to 179 -length 300 -variable Config(LON_DEG)
|
||||
scale $w.lonmin -label "Longtude (minutes)" -orient horizontal \
|
||||
-from 0 -to 59 -length 300 -variable Config(LON_MIN)
|
||||
scale $w.lonsec -label "Longitude (seconds)" -orient horizontal \
|
||||
-from 0 -to 59 -length 300 -variable Config(LON_SEC)
|
||||
|
||||
radiobutton $w.north -text "Northern Hemisphere" \
|
||||
-variable Config(NORTHERN_HEMISPHERE) -value 1
|
||||
@@ -180,13 +183,15 @@ proc CreateLocationDialog { w } {
|
||||
$w.location insert end $Config(LOCATION)
|
||||
grid $w.latdeg -
|
||||
grid $w.latmin -
|
||||
grid $w.latsec -
|
||||
grid $w.londeg -
|
||||
grid $w.lonmin -
|
||||
grid $w.lonsec -
|
||||
|
||||
grid $w.north $w.west
|
||||
grid $w.south $w.east
|
||||
grid $w.loclab -sticky e
|
||||
grid $w.location -sticky nsew -row 6 -column 1
|
||||
grid $w.loclab -sticky e
|
||||
grid $w.location -sticky nsew -row 8 -column 1
|
||||
}
|
||||
|
||||
#***********************************************************************
|
||||
@@ -233,19 +238,6 @@ proc CreateOptionsDialog { w } {
|
||||
grid configure $w.timelabel -row 2 -column 0 -sticky e
|
||||
grid configure $w.time -row 2 -column 1 -sticky nsew
|
||||
|
||||
label $w.charlabel -text "Character set: "
|
||||
menubutton $w.char -text "ISO 8859-1" -indicatoron 1 -relief raised \
|
||||
-menu $w.char.menu
|
||||
menu $w.char.menu -tearoff 0
|
||||
$w.char.menu add command -label "ISO 8859-1" -command "$w.char configure -text {ISO 8859-1}"
|
||||
$w.char.menu add command -label "ISO 8859-2" -command "$w.char configure -text {ISO 8859-2}"
|
||||
$w.char.menu add command -label "IBM Extended" -command "$w.char configure -text {IBM Extended}"
|
||||
$w.char.menu add command -label "IBM CPI-852" -command "$w.char configure -text {ISO 8859-2}"
|
||||
$w.char.menu add command -label "Plain ASCII" -command "$w.char configure -text {Plain ASCII}"
|
||||
|
||||
grid configure $w.charlabel -row 3 -column 0 -sticky e
|
||||
grid configure $w.char -row 3 -column 1 -sticky nsew
|
||||
|
||||
label $w.langlabel -text "Language: "
|
||||
menubutton $w.lang -text $Config(LANGUAGE) -indicatoron 1 -relief raised \
|
||||
-menu $w.lang.menu
|
||||
@@ -268,8 +260,8 @@ proc CreateOptionsDialog { w } {
|
||||
$w.lang.menu add command -label $lang -command [list $w.lang configure -text $lang]
|
||||
}
|
||||
|
||||
grid configure $w.langlabel -row 4 -column 0 -sticky e
|
||||
grid configure $w.lang -row 4 -column 1 -sticky nsew
|
||||
grid configure $w.langlabel -row 3 -column 0 -sticky e
|
||||
grid configure $w.lang -row 3 -column 1 -sticky nsew
|
||||
|
||||
}
|
||||
|
||||
@@ -301,9 +293,9 @@ proc BuildRemind {} {
|
||||
|
||||
.msgs insert end "\n>>> Creating src/custom.h...\n\n" green
|
||||
CreateCustomH
|
||||
.msgs insert end ">>> Calling `./configure'...\n\n" green
|
||||
.msgs insert end "\n>>> Calling `./configure'...\n\n" green
|
||||
CallConfigure
|
||||
.msgs insert end ">>> Calling `make'...\n\n" green
|
||||
.msgs insert end "\n>>> Calling `make'...\n\n" green
|
||||
CallMake
|
||||
.msgs insert end "\n----------------------------------------------\n\n"
|
||||
.msgs insert end "Remind" red
|
||||
@@ -364,7 +356,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
|
||||
@@ -423,15 +415,19 @@ proc CreateCustomH {} {
|
||||
# modify them willy-nilly
|
||||
set LAT_DEG $Config(LAT_DEG)
|
||||
set LAT_MIN $Config(LAT_MIN)
|
||||
set LAT_SEC $Config(LAT_SEC)
|
||||
set LON_DEG $Config(LON_DEG)
|
||||
set LON_MIN $Config(LON_MIN)
|
||||
set LON_SEC $Config(LON_SEC)
|
||||
if {!$Config(NORTHERN_HEMISPHERE)} {
|
||||
set LAT_DEG "-$LAT_DEG"
|
||||
set LAT_MIN "-$LAT_MIN"
|
||||
set LAT_SEC "-$LAT_SEC"
|
||||
}
|
||||
if {!$Config(WESTERN_HEMISPHERE)} {
|
||||
set LON_DEG "-$LON_DEG"
|
||||
set LON_MIN "-$LON_MIN"
|
||||
set LON_SEC "-$LON_SEC"
|
||||
}
|
||||
set Config(LOCATION) [$Loc.location get]
|
||||
|
||||
@@ -446,38 +442,17 @@ proc CreateCustomH {} {
|
||||
set Config(DATESEP) [$Options.date cget -text]
|
||||
set Config(TIMESEP) [$Options.time cget -text]
|
||||
|
||||
switch -- [$Options.char cget -text] {
|
||||
"ISO 8859-1" {
|
||||
set Config(ISOLATIN1) 1
|
||||
}
|
||||
"ISO 8859-2" {
|
||||
set Config(ISOLATIN2) 1
|
||||
}
|
||||
"IBM CPI-852" {
|
||||
set Config(IBM852) 1
|
||||
}
|
||||
"IBM Extended" {
|
||||
set Config(IBMEXTENDED) 1
|
||||
}
|
||||
}
|
||||
|
||||
while {[gets $in line] != -1} {
|
||||
switch -glob -- $line {
|
||||
"#define LAT_DEG *" {
|
||||
puts $out "#define LAT_DEG $LAT_DEG"
|
||||
.msgs insert end "#define LAT_DEG $LAT_DEG\n"
|
||||
"#define DEFAULT_LATITUDE *" {
|
||||
set lat [expr $LAT_DEG + ($LAT_MIN/60.0) + ($LAT_SEC/3600.0)];
|
||||
puts $out "#define DEFAULT_LATITUDE $lat"
|
||||
.msgs insert end "#define DEFAULT_LATITUDE $lat\n"
|
||||
}
|
||||
"#define LAT_MIN *" {
|
||||
puts $out "#define LAT_MIN $LAT_MIN"
|
||||
.msgs insert end "#define LAT_MIN $LAT_MIN\n"
|
||||
}
|
||||
"#define LON_DEG *" {
|
||||
puts $out "#define LON_DEG $LON_DEG"
|
||||
.msgs insert end "#define LON_DEG $LON_DEG\n"
|
||||
}
|
||||
"#define LON_MIN *" {
|
||||
puts $out "#define LON_MIN $LON_MIN"
|
||||
.msgs insert end "#define LON_MIN $LON_MIN\n"
|
||||
"#define DEFAULT_LONGITUDE *" {
|
||||
set lon [expr -1.0 * ($LON_DEG + ($LON_MIN/60.0) + ($LON_SEC/3600.0))]
|
||||
puts $out "#define DEFAULT_LONGITUDE $lon"
|
||||
.msgs insert end "#define DEFAULT_LONGITUDE $lon\n"
|
||||
}
|
||||
"#define LOCATION *" {
|
||||
puts $out "#define LOCATION \"$Config(LOCATION)\""
|
||||
@@ -495,22 +470,6 @@ proc CreateCustomH {} {
|
||||
puts $out "#define TIMESEP '$Config(TIMESEP)'"
|
||||
.msgs insert end "#define TIMESEP '$Config(TIMESEP)'\n"
|
||||
}
|
||||
"#define ISOLATIN1 *" {
|
||||
puts $out "#define ISOLATIN1 $Config(ISOLATIN1)"
|
||||
.msgs insert end "#define ISOLATIN1 $Config(ISOLATIN1)\n"
|
||||
}
|
||||
"#define ISOLATIN2 *" {
|
||||
puts $out "#define ISOLATIN2 $Config(ISOLATIN2)"
|
||||
.msgs insert end "#define ISOLATIN2 $Config(ISOLATIN2)\n"
|
||||
}
|
||||
"#define IBM852 *" {
|
||||
puts $out "#define IBM852 $Config(IBM852)"
|
||||
.msgs insert end "#define IBM852 $Config(IBM852)\n"
|
||||
}
|
||||
"#define IBMEXTENDED *" {
|
||||
puts $out "#define IBMEXTENDED $Config(IBMEXTENDED)"
|
||||
.msgs insert end "#define IBMEXTENDED $Config(IBMEXTENDED)\n"
|
||||
}
|
||||
default {
|
||||
puts $out $line
|
||||
}
|
||||
@@ -547,7 +506,13 @@ proc CallMake {} {
|
||||
"Icelandic" { set lang ICELANDIC }
|
||||
default { set lang ENGLISH }
|
||||
}
|
||||
RunCommand "make \"LANGDEF=-DLANG=$lang\""
|
||||
set nproc 0
|
||||
catch { set nproc [exec nproc] }
|
||||
if { $nproc != 0 } {
|
||||
RunCommand "make -j $nproc \"LANGDEF=-DLANG=$lang\""
|
||||
} else {
|
||||
RunCommand "make \"LANGDEF=-DLANG=$lang\""
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -806,14 +771,17 @@ proc SetConfigFromRemind {} {
|
||||
# Query Remind for the rest
|
||||
QueryRemind $rem LAT_DEG {$LatDeg}
|
||||
QueryRemind $rem LAT_MIN {$LatMin}
|
||||
QueryRemind $rem LAT_SEC {$LatSec}
|
||||
QueryRemind $rem LON_DEG {$LongDeg}
|
||||
QueryRemind $rem LON_MIN {$LongMin}
|
||||
QueryRemind $rem LON_SEC {$LongSec}
|
||||
QueryRemind $rem LOCATION {$Location}
|
||||
QueryRemind $rem DATESEP {$DateSep}
|
||||
QueryRemind $rem TIMESEP {$TimeSep}
|
||||
QueryRemind $rem LANGUAGE {language()}
|
||||
|
||||
set $Config(LAT_MIN) [expr abs($Config(LAT_MIN))]
|
||||
set $Config(LAT_SEC) [expr abs($Config(LAT_SEC))]
|
||||
if {$Config(LAT_DEG) >= 0} {
|
||||
set Config(NORTHERN_HEMISPHERE) 1
|
||||
} else {
|
||||
@@ -822,6 +790,7 @@ proc SetConfigFromRemind {} {
|
||||
}
|
||||
|
||||
set $Config(LON_MIN) [expr abs($Config(LON_MIN))]
|
||||
set $Config(LON_SEC) [expr abs($Config(LON_SEC))]
|
||||
if {$Config(LON_DEG) >= 0} {
|
||||
set Config(WESTERN_HEMISPHERE) 1
|
||||
} else {
|
||||
|
||||
96
configure.in
96
configure.in
@@ -1,6 +1,7 @@
|
||||
dnl Process this file with autoconf to produce a configure script.
|
||||
|
||||
AC_INIT(src/queue.c)
|
||||
AC_INIT
|
||||
AC_CONFIG_SRCDIR([src/queue.c])
|
||||
|
||||
cat <<'EOF'
|
||||
|
||||
@@ -12,69 +13,86 @@ cat <<'EOF'
|
||||
|
||||
EOF
|
||||
|
||||
AC_CONFIG_HEADER(src/config.h)
|
||||
AC_CONFIG_HEADERS([src/config.h])
|
||||
|
||||
if test "`uname -s`" = "Darwin" ; then
|
||||
trap 'echo Be patient...' INT TERM
|
||||
cat <<'EOF'
|
||||
AC_ARG_ENABLE(perl-build-artifacts,
|
||||
[ --disable-perl-build-artifacts
|
||||
Disable perllocal.pod and .packlist generation], ac_cv_perlartifacts=$enableval, ac_cv_perlartifacts=yes)
|
||||
|
||||
Please don't use Apple products. This script will continue in 30 seconds
|
||||
if you insist on compiling Remind on Mac OS X.
|
||||
|
||||
EOF
|
||||
for i in 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 ; do
|
||||
sleep 1
|
||||
done
|
||||
trap - INT
|
||||
trap - TERM
|
||||
fi
|
||||
|
||||
if uname -s | grep -i -q 'cygwin' ; then
|
||||
trap 'echo Be patient...' INT TERM
|
||||
cat <<'EOF'
|
||||
|
||||
Please don't use Microsoft products. This script will continue in 30
|
||||
seconds if you insist on compiling Remind on Cygwin.
|
||||
|
||||
EOF
|
||||
for i in 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 ; do
|
||||
sleep 1
|
||||
done
|
||||
trap - INT
|
||||
trap - TERM
|
||||
fi
|
||||
AH_BOTTOM([#include <custom.h>])
|
||||
|
||||
dnl Checks for programs.
|
||||
AC_PROG_CC
|
||||
AC_PROG_INSTALL
|
||||
AC_PROG_LN_S
|
||||
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)
|
||||
AC_CHECK_HEADERS_ONCE([sys/time.h])
|
||||
|
||||
dnl Integer sizes
|
||||
AC_CHECK_SIZEOF(unsigned short)
|
||||
AC_CHECK_SIZEOF(unsigned int)
|
||||
AC_CHECK_SIZEOF(unsigned long)
|
||||
AC_CHECK_SIZEOF(time_t)
|
||||
|
||||
dnl Checks for header files.
|
||||
AC_CHECK_HEADERS(sys/file.h glob.h wctype.h locale.h)
|
||||
AC_CHECK_HEADERS(sys/types.h glob.h wctype.h locale.h langinfo.h sys/inotify.h)
|
||||
|
||||
dnl Checks for typedefs, structures, and compiler characteristics.
|
||||
AC_STRUCT_TM
|
||||
|
||||
dnl Checks for library functions.
|
||||
AC_FUNC_UTIME_NULL
|
||||
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 -Werror -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 -Werror -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
|
||||
|
||||
AC_CHECK_FUNCS(setenv unsetenv glob mbstowcs setlocale)
|
||||
VERSION=03.03.05
|
||||
dnl If sizeof(time_t) is 4, try to get 64-bit time_t
|
||||
if test "$ac_cv_sizeof_time_t" = "4" ; then
|
||||
AC_MSG_NOTICE([time_t is 32-bits on this system; attempting to use 64-bit time_t])
|
||||
CFLAGS="$CFLAGS -D_TIME_BITS=64 -D_FILE_OFFSET_BITS=64"
|
||||
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 inotify_init1)
|
||||
|
||||
VERSION=04.03.01
|
||||
AC_SUBST(VERSION)
|
||||
AC_OUTPUT(src/Makefile www/Makefile src/version.h)
|
||||
AC_SUBST(PERL)
|
||||
AC_SUBST(PERLARTIFACTS)
|
||||
AC_SUBST(RELEASE_DATE)
|
||||
AC_CONFIG_FILES([src/Makefile www/Makefile src/version.h rem2html/Makefile rem2html/rem2html rem2pdf/Makefile.PL rem2pdf/Makefile.top rem2pdf/bin/rem2pdf man/rem.1 man/rem2ps.1 man/remind.1 man/tkremind.1])
|
||||
AC_OUTPUT
|
||||
chmod a+x rem2pdf/bin/rem2pdf
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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];
|
||||
|
||||
13
contrib/remind-conf-mode/README
Normal file
13
contrib/remind-conf-mode/README
Normal file
@@ -0,0 +1,13 @@
|
||||
Remind-conf-mode is a configuration mode designed to make it a little easier to configure remind using emacs.
|
||||
|
||||
It offers a vibrant colour syntax highlighting for those who like lots of colour, simple indentation and some hopefully useful functions for entering times and dates. Those functions have been exposed in a special menu for remind for those who have not turned off the emacs menu system.
|
||||
|
||||
Just copy remind-conf-mode.el to your elisp folder (whatever it is called) make sure it is in your path so emacs know where to look for it, and put (require 'remind-conf-mode) in your dotemacs file.
|
||||
|
||||
There are some more complex instructions in the file itself.
|
||||
|
||||
Have fun and if you can think of any improvements let me know, or fork it to your own git repository and experiment away.
|
||||
|
||||
The faux-locale branch has code for choosing the language you use remind in. Please try it out and let me know if there are any problems with it.
|
||||
|
||||
Shelagh
|
||||
674
contrib/remind-conf-mode/gpl.txt
Normal file
674
contrib/remind-conf-mode/gpl.txt
Normal file
@@ -0,0 +1,674 @@
|
||||
GNU GENERAL PUBLIC LICENSE
|
||||
Version 3, 29 June 2007
|
||||
|
||||
Copyright (C) 2007 Free Software Foundation, Inc. <http://fsf.org/>
|
||||
Everyone is permitted to copy and distribute verbatim copies
|
||||
of this license document, but changing it is not allowed.
|
||||
|
||||
Preamble
|
||||
|
||||
The GNU General Public License is a free, copyleft license for
|
||||
software and other kinds of works.
|
||||
|
||||
The licenses for most software and other practical works are designed
|
||||
to take away your freedom to share and change the works. By contrast,
|
||||
the GNU General Public License is intended to guarantee your freedom to
|
||||
share and change all versions of a program--to make sure it remains free
|
||||
software for all its users. We, the Free Software Foundation, use the
|
||||
GNU General Public License for most of our software; it applies also to
|
||||
any other work released this way by its authors. You can apply it to
|
||||
your programs, too.
|
||||
|
||||
When we speak of free software, we are referring to freedom, not
|
||||
price. Our General Public Licenses are designed to make sure that you
|
||||
have the freedom to distribute copies of free software (and charge for
|
||||
them if you wish), that you receive source code or can get it if you
|
||||
want it, that you can change the software or use pieces of it in new
|
||||
free programs, and that you know you can do these things.
|
||||
|
||||
To protect your rights, we need to prevent others from denying you
|
||||
these rights or asking you to surrender the rights. Therefore, you have
|
||||
certain responsibilities if you distribute copies of the software, or if
|
||||
you modify it: responsibilities to respect the freedom of others.
|
||||
|
||||
For example, if you distribute copies of such a program, whether
|
||||
gratis or for a fee, you must pass on to the recipients the same
|
||||
freedoms that you received. You must make sure that they, too, receive
|
||||
or can get the source code. And you must show them these terms so they
|
||||
know their rights.
|
||||
|
||||
Developers that use the GNU GPL protect your rights with two steps:
|
||||
(1) assert copyright on the software, and (2) offer you this License
|
||||
giving you legal permission to copy, distribute and/or modify it.
|
||||
|
||||
For the developers' and authors' protection, the GPL clearly explains
|
||||
that there is no warranty for this free software. For both users' and
|
||||
authors' sake, the GPL requires that modified versions be marked as
|
||||
changed, so that their problems will not be attributed erroneously to
|
||||
authors of previous versions.
|
||||
|
||||
Some devices are designed to deny users access to install or run
|
||||
modified versions of the software inside them, although the manufacturer
|
||||
can do so. This is fundamentally incompatible with the aim of
|
||||
protecting users' freedom to change the software. The systematic
|
||||
pattern of such abuse occurs in the area of products for individuals to
|
||||
use, which is precisely where it is most unacceptable. Therefore, we
|
||||
have designed this version of the GPL to prohibit the practice for those
|
||||
products. If such problems arise substantially in other domains, we
|
||||
stand ready to extend this provision to those domains in future versions
|
||||
of the GPL, as needed to protect the freedom of users.
|
||||
|
||||
Finally, every program is threatened constantly by software patents.
|
||||
States should not allow patents to restrict development and use of
|
||||
software on general-purpose computers, but in those that do, we wish to
|
||||
avoid the special danger that patents applied to a free program could
|
||||
make it effectively proprietary. To prevent this, the GPL assures that
|
||||
patents cannot be used to render the program non-free.
|
||||
|
||||
The precise terms and conditions for copying, distribution and
|
||||
modification follow.
|
||||
|
||||
TERMS AND CONDITIONS
|
||||
|
||||
0. Definitions.
|
||||
|
||||
"This License" refers to version 3 of the GNU General Public License.
|
||||
|
||||
"Copyright" also means copyright-like laws that apply to other kinds of
|
||||
works, such as semiconductor masks.
|
||||
|
||||
"The Program" refers to any copyrightable work licensed under this
|
||||
License. Each licensee is addressed as "you". "Licensees" and
|
||||
"recipients" may be individuals or organizations.
|
||||
|
||||
To "modify" a work means to copy from or adapt all or part of the work
|
||||
in a fashion requiring copyright permission, other than the making of an
|
||||
exact copy. The resulting work is called a "modified version" of the
|
||||
earlier work or a work "based on" the earlier work.
|
||||
|
||||
A "covered work" means either the unmodified Program or a work based
|
||||
on the Program.
|
||||
|
||||
To "propagate" a work means to do anything with it that, without
|
||||
permission, would make you directly or secondarily liable for
|
||||
infringement under applicable copyright law, except executing it on a
|
||||
computer or modifying a private copy. Propagation includes copying,
|
||||
distribution (with or without modification), making available to the
|
||||
public, and in some countries other activities as well.
|
||||
|
||||
To "convey" a work means any kind of propagation that enables other
|
||||
parties to make or receive copies. Mere interaction with a user through
|
||||
a computer network, with no transfer of a copy, is not conveying.
|
||||
|
||||
An interactive user interface displays "Appropriate Legal Notices"
|
||||
to the extent that it includes a convenient and prominently visible
|
||||
feature that (1) displays an appropriate copyright notice, and (2)
|
||||
tells the user that there is no warranty for the work (except to the
|
||||
extent that warranties are provided), that licensees may convey the
|
||||
work under this License, and how to view a copy of this License. If
|
||||
the interface presents a list of user commands or options, such as a
|
||||
menu, a prominent item in the list meets this criterion.
|
||||
|
||||
1. Source Code.
|
||||
|
||||
The "source code" for a work means the preferred form of the work
|
||||
for making modifications to it. "Object code" means any non-source
|
||||
form of a work.
|
||||
|
||||
A "Standard Interface" means an interface that either is an official
|
||||
standard defined by a recognized standards body, or, in the case of
|
||||
interfaces specified for a particular programming language, one that
|
||||
is widely used among developers working in that language.
|
||||
|
||||
The "System Libraries" of an executable work include anything, other
|
||||
than the work as a whole, that (a) is included in the normal form of
|
||||
packaging a Major Component, but which is not part of that Major
|
||||
Component, and (b) serves only to enable use of the work with that
|
||||
Major Component, or to implement a Standard Interface for which an
|
||||
implementation is available to the public in source code form. A
|
||||
"Major Component", in this context, means a major essential component
|
||||
(kernel, window system, and so on) of the specific operating system
|
||||
(if any) on which the executable work runs, or a compiler used to
|
||||
produce the work, or an object code interpreter used to run it.
|
||||
|
||||
The "Corresponding Source" for a work in object code form means all
|
||||
the source code needed to generate, install, and (for an executable
|
||||
work) run the object code and to modify the work, including scripts to
|
||||
control those activities. However, it does not include the work's
|
||||
System Libraries, or general-purpose tools or generally available free
|
||||
programs which are used unmodified in performing those activities but
|
||||
which are not part of the work. For example, Corresponding Source
|
||||
includes interface definition files associated with source files for
|
||||
the work, and the source code for shared libraries and dynamically
|
||||
linked subprograms that the work is specifically designed to require,
|
||||
such as by intimate data communication or control flow between those
|
||||
subprograms and other parts of the work.
|
||||
|
||||
The Corresponding Source need not include anything that users
|
||||
can regenerate automatically from other parts of the Corresponding
|
||||
Source.
|
||||
|
||||
The Corresponding Source for a work in source code form is that
|
||||
same work.
|
||||
|
||||
2. Basic Permissions.
|
||||
|
||||
All rights granted under this License are granted for the term of
|
||||
copyright on the Program, and are irrevocable provided the stated
|
||||
conditions are met. This License explicitly affirms your unlimited
|
||||
permission to run the unmodified Program. The output from running a
|
||||
covered work is covered by this License only if the output, given its
|
||||
content, constitutes a covered work. This License acknowledges your
|
||||
rights of fair use or other equivalent, as provided by copyright law.
|
||||
|
||||
You may make, run and propagate covered works that you do not
|
||||
convey, without conditions so long as your license otherwise remains
|
||||
in force. You may convey covered works to others for the sole purpose
|
||||
of having them make modifications exclusively for you, or provide you
|
||||
with facilities for running those works, provided that you comply with
|
||||
the terms of this License in conveying all material for which you do
|
||||
not control copyright. Those thus making or running the covered works
|
||||
for you must do so exclusively on your behalf, under your direction
|
||||
and control, on terms that prohibit them from making any copies of
|
||||
your copyrighted material outside their relationship with you.
|
||||
|
||||
Conveying under any other circumstances is permitted solely under
|
||||
the conditions stated below. Sublicensing is not allowed; section 10
|
||||
makes it unnecessary.
|
||||
|
||||
3. Protecting Users' Legal Rights From Anti-Circumvention Law.
|
||||
|
||||
No covered work shall be deemed part of an effective technological
|
||||
measure under any applicable law fulfilling obligations under article
|
||||
11 of the WIPO copyright treaty adopted on 20 December 1996, or
|
||||
similar laws prohibiting or restricting circumvention of such
|
||||
measures.
|
||||
|
||||
When you convey a covered work, you waive any legal power to forbid
|
||||
circumvention of technological measures to the extent such circumvention
|
||||
is effected by exercising rights under this License with respect to
|
||||
the covered work, and you disclaim any intention to limit operation or
|
||||
modification of the work as a means of enforcing, against the work's
|
||||
users, your or third parties' legal rights to forbid circumvention of
|
||||
technological measures.
|
||||
|
||||
4. Conveying Verbatim Copies.
|
||||
|
||||
You may convey verbatim copies of the Program's source code as you
|
||||
receive it, in any medium, provided that you conspicuously and
|
||||
appropriately publish on each copy an appropriate copyright notice;
|
||||
keep intact all notices stating that this License and any
|
||||
non-permissive terms added in accord with section 7 apply to the code;
|
||||
keep intact all notices of the absence of any warranty; and give all
|
||||
recipients a copy of this License along with the Program.
|
||||
|
||||
You may charge any price or no price for each copy that you convey,
|
||||
and you may offer support or warranty protection for a fee.
|
||||
|
||||
5. Conveying Modified Source Versions.
|
||||
|
||||
You may convey a work based on the Program, or the modifications to
|
||||
produce it from the Program, in the form of source code under the
|
||||
terms of section 4, provided that you also meet all of these conditions:
|
||||
|
||||
a) The work must carry prominent notices stating that you modified
|
||||
it, and giving a relevant date.
|
||||
|
||||
b) The work must carry prominent notices stating that it is
|
||||
released under this License and any conditions added under section
|
||||
7. This requirement modifies the requirement in section 4 to
|
||||
"keep intact all notices".
|
||||
|
||||
c) You must license the entire work, as a whole, under this
|
||||
License to anyone who comes into possession of a copy. This
|
||||
License will therefore apply, along with any applicable section 7
|
||||
additional terms, to the whole of the work, and all its parts,
|
||||
regardless of how they are packaged. This License gives no
|
||||
permission to license the work in any other way, but it does not
|
||||
invalidate such permission if you have separately received it.
|
||||
|
||||
d) If the work has interactive user interfaces, each must display
|
||||
Appropriate Legal Notices; however, if the Program has interactive
|
||||
interfaces that do not display Appropriate Legal Notices, your
|
||||
work need not make them do so.
|
||||
|
||||
A compilation of a covered work with other separate and independent
|
||||
works, which are not by their nature extensions of the covered work,
|
||||
and which are not combined with it such as to form a larger program,
|
||||
in or on a volume of a storage or distribution medium, is called an
|
||||
"aggregate" if the compilation and its resulting copyright are not
|
||||
used to limit the access or legal rights of the compilation's users
|
||||
beyond what the individual works permit. Inclusion of a covered work
|
||||
in an aggregate does not cause this License to apply to the other
|
||||
parts of the aggregate.
|
||||
|
||||
6. Conveying Non-Source Forms.
|
||||
|
||||
You may convey a covered work in object code form under the terms
|
||||
of sections 4 and 5, provided that you also convey the
|
||||
machine-readable Corresponding Source under the terms of this License,
|
||||
in one of these ways:
|
||||
|
||||
a) Convey the object code in, or embodied in, a physical product
|
||||
(including a physical distribution medium), accompanied by the
|
||||
Corresponding Source fixed on a durable physical medium
|
||||
customarily used for software interchange.
|
||||
|
||||
b) Convey the object code in, or embodied in, a physical product
|
||||
(including a physical distribution medium), accompanied by a
|
||||
written offer, valid for at least three years and valid for as
|
||||
long as you offer spare parts or customer support for that product
|
||||
model, to give anyone who possesses the object code either (1) a
|
||||
copy of the Corresponding Source for all the software in the
|
||||
product that is covered by this License, on a durable physical
|
||||
medium customarily used for software interchange, for a price no
|
||||
more than your reasonable cost of physically performing this
|
||||
conveying of source, or (2) access to copy the
|
||||
Corresponding Source from a network server at no charge.
|
||||
|
||||
c) Convey individual copies of the object code with a copy of the
|
||||
written offer to provide the Corresponding Source. This
|
||||
alternative is allowed only occasionally and noncommercially, and
|
||||
only if you received the object code with such an offer, in accord
|
||||
with subsection 6b.
|
||||
|
||||
d) Convey the object code by offering access from a designated
|
||||
place (gratis or for a charge), and offer equivalent access to the
|
||||
Corresponding Source in the same way through the same place at no
|
||||
further charge. You need not require recipients to copy the
|
||||
Corresponding Source along with the object code. If the place to
|
||||
copy the object code is a network server, the Corresponding Source
|
||||
may be on a different server (operated by you or a third party)
|
||||
that supports equivalent copying facilities, provided you maintain
|
||||
clear directions next to the object code saying where to find the
|
||||
Corresponding Source. Regardless of what server hosts the
|
||||
Corresponding Source, you remain obligated to ensure that it is
|
||||
available for as long as needed to satisfy these requirements.
|
||||
|
||||
e) Convey the object code using peer-to-peer transmission, provided
|
||||
you inform other peers where the object code and Corresponding
|
||||
Source of the work are being offered to the general public at no
|
||||
charge under subsection 6d.
|
||||
|
||||
A separable portion of the object code, whose source code is excluded
|
||||
from the Corresponding Source as a System Library, need not be
|
||||
included in conveying the object code work.
|
||||
|
||||
A "User Product" is either (1) a "consumer product", which means any
|
||||
tangible personal property which is normally used for personal, family,
|
||||
or household purposes, or (2) anything designed or sold for incorporation
|
||||
into a dwelling. In determining whether a product is a consumer product,
|
||||
doubtful cases shall be resolved in favor of coverage. For a particular
|
||||
product received by a particular user, "normally used" refers to a
|
||||
typical or common use of that class of product, regardless of the status
|
||||
of the particular user or of the way in which the particular user
|
||||
actually uses, or expects or is expected to use, the product. A product
|
||||
is a consumer product regardless of whether the product has substantial
|
||||
commercial, industrial or non-consumer uses, unless such uses represent
|
||||
the only significant mode of use of the product.
|
||||
|
||||
"Installation Information" for a User Product means any methods,
|
||||
procedures, authorization keys, or other information required to install
|
||||
and execute modified versions of a covered work in that User Product from
|
||||
a modified version of its Corresponding Source. The information must
|
||||
suffice to ensure that the continued functioning of the modified object
|
||||
code is in no case prevented or interfered with solely because
|
||||
modification has been made.
|
||||
|
||||
If you convey an object code work under this section in, or with, or
|
||||
specifically for use in, a User Product, and the conveying occurs as
|
||||
part of a transaction in which the right of possession and use of the
|
||||
User Product is transferred to the recipient in perpetuity or for a
|
||||
fixed term (regardless of how the transaction is characterized), the
|
||||
Corresponding Source conveyed under this section must be accompanied
|
||||
by the Installation Information. But this requirement does not apply
|
||||
if neither you nor any third party retains the ability to install
|
||||
modified object code on the User Product (for example, the work has
|
||||
been installed in ROM).
|
||||
|
||||
The requirement to provide Installation Information does not include a
|
||||
requirement to continue to provide support service, warranty, or updates
|
||||
for a work that has been modified or installed by the recipient, or for
|
||||
the User Product in which it has been modified or installed. Access to a
|
||||
network may be denied when the modification itself materially and
|
||||
adversely affects the operation of the network or violates the rules and
|
||||
protocols for communication across the network.
|
||||
|
||||
Corresponding Source conveyed, and Installation Information provided,
|
||||
in accord with this section must be in a format that is publicly
|
||||
documented (and with an implementation available to the public in
|
||||
source code form), and must require no special password or key for
|
||||
unpacking, reading or copying.
|
||||
|
||||
7. Additional Terms.
|
||||
|
||||
"Additional permissions" are terms that supplement the terms of this
|
||||
License by making exceptions from one or more of its conditions.
|
||||
Additional permissions that are applicable to the entire Program shall
|
||||
be treated as though they were included in this License, to the extent
|
||||
that they are valid under applicable law. If additional permissions
|
||||
apply only to part of the Program, that part may be used separately
|
||||
under those permissions, but the entire Program remains governed by
|
||||
this License without regard to the additional permissions.
|
||||
|
||||
When you convey a copy of a covered work, you may at your option
|
||||
remove any additional permissions from that copy, or from any part of
|
||||
it. (Additional permissions may be written to require their own
|
||||
removal in certain cases when you modify the work.) You may place
|
||||
additional permissions on material, added by you to a covered work,
|
||||
for which you have or can give appropriate copyright permission.
|
||||
|
||||
Notwithstanding any other provision of this License, for material you
|
||||
add to a covered work, you may (if authorized by the copyright holders of
|
||||
that material) supplement the terms of this License with terms:
|
||||
|
||||
a) Disclaiming warranty or limiting liability differently from the
|
||||
terms of sections 15 and 16 of this License; or
|
||||
|
||||
b) Requiring preservation of specified reasonable legal notices or
|
||||
author attributions in that material or in the Appropriate Legal
|
||||
Notices displayed by works containing it; or
|
||||
|
||||
c) Prohibiting misrepresentation of the origin of that material, or
|
||||
requiring that modified versions of such material be marked in
|
||||
reasonable ways as different from the original version; or
|
||||
|
||||
d) Limiting the use for publicity purposes of names of licensors or
|
||||
authors of the material; or
|
||||
|
||||
e) Declining to grant rights under trademark law for use of some
|
||||
trade names, trademarks, or service marks; or
|
||||
|
||||
f) Requiring indemnification of licensors and authors of that
|
||||
material by anyone who conveys the material (or modified versions of
|
||||
it) with contractual assumptions of liability to the recipient, for
|
||||
any liability that these contractual assumptions directly impose on
|
||||
those licensors and authors.
|
||||
|
||||
All other non-permissive additional terms are considered "further
|
||||
restrictions" within the meaning of section 10. If the Program as you
|
||||
received it, or any part of it, contains a notice stating that it is
|
||||
governed by this License along with a term that is a further
|
||||
restriction, you may remove that term. If a license document contains
|
||||
a further restriction but permits relicensing or conveying under this
|
||||
License, you may add to a covered work material governed by the terms
|
||||
of that license document, provided that the further restriction does
|
||||
not survive such relicensing or conveying.
|
||||
|
||||
If you add terms to a covered work in accord with this section, you
|
||||
must place, in the relevant source files, a statement of the
|
||||
additional terms that apply to those files, or a notice indicating
|
||||
where to find the applicable terms.
|
||||
|
||||
Additional terms, permissive or non-permissive, may be stated in the
|
||||
form of a separately written license, or stated as exceptions;
|
||||
the above requirements apply either way.
|
||||
|
||||
8. Termination.
|
||||
|
||||
You may not propagate or modify a covered work except as expressly
|
||||
provided under this License. Any attempt otherwise to propagate or
|
||||
modify it is void, and will automatically terminate your rights under
|
||||
this License (including any patent licenses granted under the third
|
||||
paragraph of section 11).
|
||||
|
||||
However, if you cease all violation of this License, then your
|
||||
license from a particular copyright holder is reinstated (a)
|
||||
provisionally, unless and until the copyright holder explicitly and
|
||||
finally terminates your license, and (b) permanently, if the copyright
|
||||
holder fails to notify you of the violation by some reasonable means
|
||||
prior to 60 days after the cessation.
|
||||
|
||||
Moreover, your license from a particular copyright holder is
|
||||
reinstated permanently if the copyright holder notifies you of the
|
||||
violation by some reasonable means, this is the first time you have
|
||||
received notice of violation of this License (for any work) from that
|
||||
copyright holder, and you cure the violation prior to 30 days after
|
||||
your receipt of the notice.
|
||||
|
||||
Termination of your rights under this section does not terminate the
|
||||
licenses of parties who have received copies or rights from you under
|
||||
this License. If your rights have been terminated and not permanently
|
||||
reinstated, you do not qualify to receive new licenses for the same
|
||||
material under section 10.
|
||||
|
||||
9. Acceptance Not Required for Having Copies.
|
||||
|
||||
You are not required to accept this License in order to receive or
|
||||
run a copy of the Program. Ancillary propagation of a covered work
|
||||
occurring solely as a consequence of using peer-to-peer transmission
|
||||
to receive a copy likewise does not require acceptance. However,
|
||||
nothing other than this License grants you permission to propagate or
|
||||
modify any covered work. These actions infringe copyright if you do
|
||||
not accept this License. Therefore, by modifying or propagating a
|
||||
covered work, you indicate your acceptance of this License to do so.
|
||||
|
||||
10. Automatic Licensing of Downstream Recipients.
|
||||
|
||||
Each time you convey a covered work, the recipient automatically
|
||||
receives a license from the original licensors, to run, modify and
|
||||
propagate that work, subject to this License. You are not responsible
|
||||
for enforcing compliance by third parties with this License.
|
||||
|
||||
An "entity transaction" is a transaction transferring control of an
|
||||
organization, or substantially all assets of one, or subdividing an
|
||||
organization, or merging organizations. If propagation of a covered
|
||||
work results from an entity transaction, each party to that
|
||||
transaction who receives a copy of the work also receives whatever
|
||||
licenses to the work the party's predecessor in interest had or could
|
||||
give under the previous paragraph, plus a right to possession of the
|
||||
Corresponding Source of the work from the predecessor in interest, if
|
||||
the predecessor has it or can get it with reasonable efforts.
|
||||
|
||||
You may not impose any further restrictions on the exercise of the
|
||||
rights granted or affirmed under this License. For example, you may
|
||||
not impose a license fee, royalty, or other charge for exercise of
|
||||
rights granted under this License, and you may not initiate litigation
|
||||
(including a cross-claim or counterclaim in a lawsuit) alleging that
|
||||
any patent claim is infringed by making, using, selling, offering for
|
||||
sale, or importing the Program or any portion of it.
|
||||
|
||||
11. Patents.
|
||||
|
||||
A "contributor" is a copyright holder who authorizes use under this
|
||||
License of the Program or a work on which the Program is based. The
|
||||
work thus licensed is called the contributor's "contributor version".
|
||||
|
||||
A contributor's "essential patent claims" are all patent claims
|
||||
owned or controlled by the contributor, whether already acquired or
|
||||
hereafter acquired, that would be infringed by some manner, permitted
|
||||
by this License, of making, using, or selling its contributor version,
|
||||
but do not include claims that would be infringed only as a
|
||||
consequence of further modification of the contributor version. For
|
||||
purposes of this definition, "control" includes the right to grant
|
||||
patent sublicenses in a manner consistent with the requirements of
|
||||
this License.
|
||||
|
||||
Each contributor grants you a non-exclusive, worldwide, royalty-free
|
||||
patent license under the contributor's essential patent claims, to
|
||||
make, use, sell, offer for sale, import and otherwise run, modify and
|
||||
propagate the contents of its contributor version.
|
||||
|
||||
In the following three paragraphs, a "patent license" is any express
|
||||
agreement or commitment, however denominated, not to enforce a patent
|
||||
(such as an express permission to practice a patent or covenant not to
|
||||
sue for patent infringement). To "grant" such a patent license to a
|
||||
party means to make such an agreement or commitment not to enforce a
|
||||
patent against the party.
|
||||
|
||||
If you convey a covered work, knowingly relying on a patent license,
|
||||
and the Corresponding Source of the work is not available for anyone
|
||||
to copy, free of charge and under the terms of this License, through a
|
||||
publicly available network server or other readily accessible means,
|
||||
then you must either (1) cause the Corresponding Source to be so
|
||||
available, or (2) arrange to deprive yourself of the benefit of the
|
||||
patent license for this particular work, or (3) arrange, in a manner
|
||||
consistent with the requirements of this License, to extend the patent
|
||||
license to downstream recipients. "Knowingly relying" means you have
|
||||
actual knowledge that, but for the patent license, your conveying the
|
||||
covered work in a country, or your recipient's use of the covered work
|
||||
in a country, would infringe one or more identifiable patents in that
|
||||
country that you have reason to believe are valid.
|
||||
|
||||
If, pursuant to or in connection with a single transaction or
|
||||
arrangement, you convey, or propagate by procuring conveyance of, a
|
||||
covered work, and grant a patent license to some of the parties
|
||||
receiving the covered work authorizing them to use, propagate, modify
|
||||
or convey a specific copy of the covered work, then the patent license
|
||||
you grant is automatically extended to all recipients of the covered
|
||||
work and works based on it.
|
||||
|
||||
A patent license is "discriminatory" if it does not include within
|
||||
the scope of its coverage, prohibits the exercise of, or is
|
||||
conditioned on the non-exercise of one or more of the rights that are
|
||||
specifically granted under this License. You may not convey a covered
|
||||
work if you are a party to an arrangement with a third party that is
|
||||
in the business of distributing software, under which you make payment
|
||||
to the third party based on the extent of your activity of conveying
|
||||
the work, and under which the third party grants, to any of the
|
||||
parties who would receive the covered work from you, a discriminatory
|
||||
patent license (a) in connection with copies of the covered work
|
||||
conveyed by you (or copies made from those copies), or (b) primarily
|
||||
for and in connection with specific products or compilations that
|
||||
contain the covered work, unless you entered into that arrangement,
|
||||
or that patent license was granted, prior to 28 March 2007.
|
||||
|
||||
Nothing in this License shall be construed as excluding or limiting
|
||||
any implied license or other defenses to infringement that may
|
||||
otherwise be available to you under applicable patent law.
|
||||
|
||||
12. No Surrender of Others' Freedom.
|
||||
|
||||
If conditions are imposed on you (whether by court order, agreement or
|
||||
otherwise) that contradict the conditions of this License, they do not
|
||||
excuse you from the conditions of this License. If you cannot convey a
|
||||
covered work so as to satisfy simultaneously your obligations under this
|
||||
License and any other pertinent obligations, then as a consequence you may
|
||||
not convey it at all. For example, if you agree to terms that obligate you
|
||||
to collect a royalty for further conveying from those to whom you convey
|
||||
the Program, the only way you could satisfy both those terms and this
|
||||
License would be to refrain entirely from conveying the Program.
|
||||
|
||||
13. Use with the GNU Affero General Public License.
|
||||
|
||||
Notwithstanding any other provision of this License, you have
|
||||
permission to link or combine any covered work with a work licensed
|
||||
under version 3 of the GNU Affero General Public License into a single
|
||||
combined work, and to convey the resulting work. The terms of this
|
||||
License will continue to apply to the part which is the covered work,
|
||||
but the special requirements of the GNU Affero General Public License,
|
||||
section 13, concerning interaction through a network will apply to the
|
||||
combination as such.
|
||||
|
||||
14. Revised Versions of this License.
|
||||
|
||||
The Free Software Foundation may publish revised and/or new versions of
|
||||
the GNU General Public License from time to time. Such new versions will
|
||||
be similar in spirit to the present version, but may differ in detail to
|
||||
address new problems or concerns.
|
||||
|
||||
Each version is given a distinguishing version number. If the
|
||||
Program specifies that a certain numbered version of the GNU General
|
||||
Public License "or any later version" applies to it, you have the
|
||||
option of following the terms and conditions either of that numbered
|
||||
version or of any later version published by the Free Software
|
||||
Foundation. If the Program does not specify a version number of the
|
||||
GNU General Public License, you may choose any version ever published
|
||||
by the Free Software Foundation.
|
||||
|
||||
If the Program specifies that a proxy can decide which future
|
||||
versions of the GNU General Public License can be used, that proxy's
|
||||
public statement of acceptance of a version permanently authorizes you
|
||||
to choose that version for the Program.
|
||||
|
||||
Later license versions may give you additional or different
|
||||
permissions. However, no additional obligations are imposed on any
|
||||
author or copyright holder as a result of your choosing to follow a
|
||||
later version.
|
||||
|
||||
15. Disclaimer of Warranty.
|
||||
|
||||
THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY
|
||||
APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT
|
||||
HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY
|
||||
OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO,
|
||||
THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
|
||||
PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM
|
||||
IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF
|
||||
ALL NECESSARY SERVICING, REPAIR OR CORRECTION.
|
||||
|
||||
16. Limitation of Liability.
|
||||
|
||||
IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
|
||||
WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS
|
||||
THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY
|
||||
GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE
|
||||
USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF
|
||||
DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD
|
||||
PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS),
|
||||
EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF
|
||||
SUCH DAMAGES.
|
||||
|
||||
17. Interpretation of Sections 15 and 16.
|
||||
|
||||
If the disclaimer of warranty and limitation of liability provided
|
||||
above cannot be given local legal effect according to their terms,
|
||||
reviewing courts shall apply local law that most closely approximates
|
||||
an absolute waiver of all civil liability in connection with the
|
||||
Program, unless a warranty or assumption of liability accompanies a
|
||||
copy of the Program in return for a fee.
|
||||
|
||||
END OF TERMS AND CONDITIONS
|
||||
|
||||
How to Apply These Terms to Your New Programs
|
||||
|
||||
If you develop a new program, and you want it to be of the greatest
|
||||
possible use to the public, the best way to achieve this is to make it
|
||||
free software which everyone can redistribute and change under these terms.
|
||||
|
||||
To do so, attach the following notices to the program. It is safest
|
||||
to attach them to the start of each source file to most effectively
|
||||
state the exclusion of warranty; and each file should have at least
|
||||
the "copyright" line and a pointer to where the full notice is found.
|
||||
|
||||
<one line to give the program's name and a brief idea of what it does.>
|
||||
Copyright (C) <year> <name of author>
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
Also add information on how to contact you by electronic and paper mail.
|
||||
|
||||
If the program does terminal interaction, make it output a short
|
||||
notice like this when it starts in an interactive mode:
|
||||
|
||||
<program> Copyright (C) <year> <name of author>
|
||||
This program comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
|
||||
This is free software, and you are welcome to redistribute it
|
||||
under certain conditions; type `show c' for details.
|
||||
|
||||
The hypothetical commands `show w' and `show c' should show the appropriate
|
||||
parts of the General Public License. Of course, your program's commands
|
||||
might be different; for a GUI interface, you would use an "about box".
|
||||
|
||||
You should also get your employer (if you work as a programmer) or school,
|
||||
if any, to sign a "copyright disclaimer" for the program, if necessary.
|
||||
For more information on this, and how to apply and follow the GNU GPL, see
|
||||
<http://www.gnu.org/licenses/>.
|
||||
|
||||
The GNU General Public License does not permit incorporating your program
|
||||
into proprietary programs. If your program is a subroutine library, you
|
||||
may consider it more useful to permit linking proprietary applications with
|
||||
the library. If this is what you want to do, use the GNU Lesser General
|
||||
Public License instead of this License. But first, please read
|
||||
<http://www.gnu.org/philosophy/why-not-lgpl.html>.
|
||||
@@ -1,11 +1,11 @@
|
||||
;;; remind-conf-mode.el --- A mode to help configure remind.
|
||||
|
||||
;; Copyright (C) 2008 Shelagh Manton <shelagh.manton@gmail.com>
|
||||
;; Copyright (C) 2008 - 2011 Shelagh Manton <shelagh.manton@gmail.com>
|
||||
|
||||
;; Author: Shelagh Manton <shelagh.manton@gmail.com> with help from
|
||||
;; Dianne Skoll
|
||||
;; Keywords: remind configure mode
|
||||
;; Version: .04
|
||||
;; Keywords: remind configure convenience
|
||||
;; 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
|
||||
@@ -19,8 +19,7 @@
|
||||
|
||||
;; You should have received a copy of the GNU General Public License
|
||||
;; along with this program; if not, write to the Free Software
|
||||
;; Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
|
||||
;; 02111-1307, USA.
|
||||
;; Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301 USA
|
||||
|
||||
;;; Commentary:
|
||||
|
||||
@@ -34,7 +33,7 @@
|
||||
|
||||
;; If you want to use the auto-complete stuff, you will need to download and install the
|
||||
;; auto-complete library from http://www.cx4a.org/pub/auto-complete.el and put
|
||||
;; (require 'auto-complete) in your emacs with
|
||||
;; (require 'auto-complete) in your Emacs with
|
||||
;; (add-hook 'remind-conf-mode-hook
|
||||
;; (lambda ()
|
||||
;; (make-local-variable 'ac-sources)
|
||||
@@ -42,10 +41,13 @@
|
||||
;; (auto-complete t)))
|
||||
;; in your .emacs file
|
||||
|
||||
;; PS. you could add ac-source-abbrev ac-source-words-in-buffer to have abbrevs and
|
||||
;; PS. you could add ac-source-abbrev ac-source-words-in-buffer to have abbrevs and
|
||||
;; other words in buffer auto-complete too
|
||||
|
||||
;;; History:
|
||||
;;Thu, Nov 26, 2009
|
||||
;; sorted out why the rem-save-file was not working. fixed.
|
||||
;;
|
||||
;; Thu, Feb 14, 2008
|
||||
;; Based mode on wpld-mode tutorial and sample-mode on emacs wiki.
|
||||
;; Ideas from mupad.el for font-lock styles.
|
||||
@@ -54,14 +56,14 @@
|
||||
;; Added a demo skeleton for people to copy for easy entry of coloured remind entries.
|
||||
;; tried to hook in the auto-complete library so that all known functions and keywords can be easily entered.
|
||||
;; EXPERIMENTAL, but seems to work well here (emacs cvs).
|
||||
;; Seems to work without case folding which is nice. wonder why it didn't yesterday?
|
||||
;; Seems to work without case folding which is nice.
|
||||
|
||||
;;; Code:
|
||||
|
||||
|
||||
(require 'font-lock); this goes in the define-derived-mode part.
|
||||
(when (featurep 'xemacs)
|
||||
(require 'overlay)) ;I wonder if this will help with font-lock and xemacs?
|
||||
(require 'overlay)) ;supposed to make it compatible with Xemacs.
|
||||
|
||||
|
||||
(defgroup remind-conf nil
|
||||
@@ -80,14 +82,14 @@
|
||||
remind-conf-mode-map)
|
||||
"Keymap for `remind-conf-mode'.")
|
||||
|
||||
(define-key remind-conf-mode-map "\C-cr" 'rem-skel)
|
||||
(define-key remind-conf-mode-map "\C-ct" 'rem-today)
|
||||
(define-key remind-conf-mode-map "\C-cd" 'rem-today-skel)
|
||||
(define-key remind-conf-mode-map "\C-cw" 'rem-week-away)
|
||||
(define-key remind-conf-mode-map "\C-cx" 'rem-tomorrow)
|
||||
(define-key remind-conf-mode-map "\C-ca" 'rem-days-away)
|
||||
(define-key remind-conf-mode-map "\C-c\C-r" 'rem-skel)
|
||||
(define-key remind-conf-mode-map "\C-c\C-t" 'rem-today)
|
||||
(define-key remind-conf-mode-map "\C-c\C-d" 'rem-today-skel)
|
||||
(define-key remind-conf-mode-map "\C-c\C-w" 'rem-week-away)
|
||||
(define-key remind-conf-mode-map "\C-c\C-W" 'rem-weeks-away)
|
||||
(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
|
||||
@@ -107,41 +109,72 @@
|
||||
|
||||
(defconst remind-keywords
|
||||
(sort
|
||||
(list "RUN" "REM" "ONCE" "SATISFY" "BEFORE" "UNSET" "OMIT"
|
||||
"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"
|
||||
"CLEAR-OMIT-CONTEXT" "POP-OMIT-CONTEXT" "SET" "ERRMSG" "FSET"
|
||||
"EXIT" "FLUSH" "PRESERVE" "MOON" "COLOR" "COLOUR")
|
||||
(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)))))
|
||||
|
||||
|
||||
(defconst remind-type-keywords
|
||||
(sort
|
||||
(list "INT" "STRING" "TIME" "DATE" "SHADE")
|
||||
(list "INT" "STRING" "TIME" "DATE" "SHADE" "DATETIME")
|
||||
#'(lambda (a b) (> (length a) (length b)))))
|
||||
|
||||
(defconst remind-builtin-variables
|
||||
(sort
|
||||
(list "$CalcUTC" "$CalMode" "$DefaultPrio" "$EndSent" "$EndSentIg" "$NumTrig"
|
||||
"$FirstIndent" "$FoldYear" "$FormWidth" "$MinsFromUTC" "$LatDeg" "$LatMin" "$LatSec"
|
||||
"$Location" "$LongDeg" "$LongMin" "$LongSec" "$MaxSatIter" "$SubsIndent")
|
||||
(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)))))
|
||||
|
||||
|
||||
(defconst remind-time-words
|
||||
(sort
|
||||
(list "Jan" "January" "Feb" "Mar" "Apr" "Jun" "Jul" "Aug" "Sept" "Sep" "Oct" "Nov" "Dec" "February" "March" "April" "May" "June" "July" "August" "September" "October" "November" "December" "Mon" "Monday" "Tue" "Tues" "Tuesday" "Wed" "Wednesday" "Thu" "Thursday" "Fri" "Friday" "Saturday" "Sat" "Sun" "Sunday")
|
||||
(list "Jan" "January" "Feb" "Mar" "Apr" "Jun" "Jul" "Aug" "Sept" "Sep" "Oct" "Nov" "Dec"
|
||||
"February" "March" "April" "May" "June" "July" "August" "September" "October"
|
||||
"November" "December" "Mon" "Monday" "Tue" "Tues" "Tuesday" "Wed" "Wednesday"
|
||||
"Thu" "Thursday" "Thurs" "Fri" "Friday" "Saturday" "Sat" "Sun" "Sunday")
|
||||
#'(lambda (a b) (> (length a) (length b)))))
|
||||
|
||||
|
||||
(defconst remind-builtin-functions
|
||||
(sort
|
||||
(list "abs" "access" "shell" "args" "asc" "baseyr" "char" "choose" "coerce" "date"
|
||||
"dawn" "today" "day" "daysinmon" "defined" "dosubst" "dusk" "easterdate" "easter"
|
||||
"filedir" "filename" "getenv" "hour" "iif" "trigger" "index" "isdst" "isleap"
|
||||
"isomitted" "hebdate" "hebday" "hebmon" "hebyear" "language" "ord" "thisyear"
|
||||
"sunrise" "sunset" "lower" "max" "min" "minute" "mon" "moondate" "moontime"
|
||||
"moonphase" "now" "ostype" "plural" "realnow" "realtoday" "sgn" "strlen" "psshade"
|
||||
"substr" "trigdate" "trigger" "trigtime" "trigvalid" "typeof" "upper" "psmoon"
|
||||
"value" "version" "wkday" "wkdaynum" "msgprefix" "msgsuffix" "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
|
||||
@@ -225,20 +258,40 @@
|
||||
:group 'remind-conf)
|
||||
|
||||
(defcustom rem-post-save-function ""
|
||||
"Name of shell function that can be run when you save and close a remind file.
|
||||
|
||||
If you put a & after the name of the function, it will run asyncronously. This might
|
||||
be useful if the process takes a long time."
|
||||
"Name of shell function that can be run when you save and close a remind file."
|
||||
:type 'string
|
||||
: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))
|
||||
@@ -247,29 +300,33 @@ be useful if the process takes a long time."
|
||||
(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.
|
||||
'("\\s-+\\([12][09][0-9][0-9][-/]\\(0[1-9]\\|1[0-2]\\)[-/]\\([12][0-9]\\|0[1-9]\\|3[01]\\)\\)@\\(2[0-4]\\|[01]?[0-9][.:][0-5][0-9]\\)\\s-+" . remind-time-face) ;;extended pseudo ISO time format
|
||||
'("\\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
|
||||
|
||||
(defcustom remind-conf-font-lock-keywords 'remind-conf-font-lock-keywords-3
|
||||
"Font-lock highlighting level for `remind-conf-mode'."
|
||||
:group 'remind-conf
|
||||
:type '(choice (const :tag "Barest minimum of highlighting." remind-conf-font-lock-keywords-1)
|
||||
(const :tag "Medium highlighting." remind-conf-font-lock-keywords-2)
|
||||
(const :tag "Highlighting deluxe." remind-conf-font-lock-keywords-3)))
|
||||
(const :tag "Fruit salad." remind-conf-font-lock-keywords-3)))
|
||||
|
||||
;;; Indentation (I'm sure this could be made more simple. But at least it works.)
|
||||
|
||||
@@ -289,8 +346,8 @@ be useful if the process takes a long time."
|
||||
(if (looking-at "^[ \t]*\\<\\(ENDIF\\|POP\\(?:-OMIT-CONTEXT\\)?\\)\\>")
|
||||
(progn
|
||||
(save-excursion
|
||||
(forward-line -1)
|
||||
(setq cur-indent (- (current-indentation) remind-indent-level))) ;note that not-indented is still t
|
||||
(forward-line -1)
|
||||
(setq cur-indent (- (current-indentation) remind-indent-level))) ;note that not-indented is still t
|
||||
(if (< cur-indent 0) (setq cur-indent 0)))
|
||||
(save-excursion
|
||||
(while not-indented
|
||||
@@ -313,14 +370,17 @@ be useful if the process takes a long time."
|
||||
;;; Convenience functions
|
||||
|
||||
(define-skeleton rem-skel
|
||||
"Skeleton to insert a rem line in a remind configuration file."
|
||||
nil
|
||||
"REM "(skeleton-read "Date? " )
|
||||
("Optional: How many days ahead? " " +" str )
|
||||
"Skeleton to insert a rem line in a remind configuration file.
|
||||
|
||||
If you don't want an optional feature just RET and move on."
|
||||
nil
|
||||
'(setq v1 (skeleton-read "How many days in future?: "))
|
||||
"REM " (rem-days-away (string-to-number v1))
|
||||
("Optional: How many days warning? " " +" str )
|
||||
resume:
|
||||
("Optional: At what time? Format eg 13:00. " " AT " str)
|
||||
resume:
|
||||
("Optional: How many minutes ahead? " " +" str )
|
||||
("Optional: How many minutes warning? " " +" str )
|
||||
resume:
|
||||
("Optional: At what priority? eg 0-9999" " PRIORITY " str )
|
||||
resume:
|
||||
@@ -333,7 +393,7 @@ be useful if the process takes a long time."
|
||||
"REM " (format-time-string "%d %b %Y")
|
||||
("Optional: At what time? Format eg 13:20. " " AT " str)
|
||||
resume:
|
||||
("Optional: How many minutes ahead? " " +" str )
|
||||
("Optional: How many minutes warning? " " +" str )
|
||||
resume:
|
||||
("Optional: At what priority? eg 0-9999" " PRIORITY " str )
|
||||
resume:
|
||||
@@ -351,9 +411,7 @@ be useful if the process takes a long time."
|
||||
(insert (format-time-string "%e %b %Y" (time-add (current-time) (days-to-time 1)))))
|
||||
|
||||
(defun rem-days-away (arg)
|
||||
"Insert a day N number of days in the future.
|
||||
|
||||
Takes a prefix argument, but defaults to 4."
|
||||
"Insert a day ARG number of days in the future."
|
||||
(interactive "nHow many Days?: ")
|
||||
(insert (format-time-string "%e %b %Y" (time-add (current-time) (days-to-time arg)))))
|
||||
|
||||
@@ -362,11 +420,10 @@ Takes a prefix argument, but defaults to 4."
|
||||
(interactive)
|
||||
(insert (format-time-string "%e %b %Y" (time-add (current-time) (days-to-time 7)))))
|
||||
|
||||
(setq skeleton-end-hook nil) ; so the skeletons will not automatically go to a new line.
|
||||
|
||||
;;; private function
|
||||
;; could make it useful for others. Put somethin like the following in your .emacs
|
||||
;(setq rem-post-save-function "~/bin/dailypic &")
|
||||
(defun rem-weeks-away (arg)
|
||||
"Insert a day ARG many weeks in future."
|
||||
(interactive "nHow many weeks?: ")
|
||||
(insert (format-time-string "%e %b %Y" (time-add (current-time) (days-to-time (* 7 arg))))))
|
||||
|
||||
(defun rem-save-file ()
|
||||
"Save the file and start the shell function in one go.
|
||||
@@ -374,7 +431,7 @@ Takes a prefix argument, but defaults to 4."
|
||||
This function will close the window after running. It needs the
|
||||
variable `rem-post-save-function' to be set. It will be most
|
||||
useful to people who have some sort of function they run to use
|
||||
remind data ie procucing calendars."
|
||||
remind data ie producing calendars."
|
||||
(interactive)
|
||||
(if (boundp 'rem-post-save-function)
|
||||
(progn (save-buffer)
|
||||
@@ -383,7 +440,9 @@ remind data ie procucing calendars."
|
||||
(error "`rem-post-save-function' variable is not set")))
|
||||
|
||||
(defun rem-setup-colors ()
|
||||
"Insert set of variables for coloured output in remind messages."
|
||||
"Insert set of variables for coloured output in remind messages.
|
||||
|
||||
You would only need to do this once in your main reminders file."
|
||||
(interactive)
|
||||
(find-file (expand-file-name "~/.reminders"))
|
||||
(goto-char 0) ;we do want it somewhere near the top of the file.
|
||||
@@ -410,25 +469,52 @@ SET BrWht Esc + \"[37;1m\" \n \n")))
|
||||
|
||||
;; So now you can do things like:
|
||||
|
||||
(define-skeleton birthcol
|
||||
(define-skeleton rem-birthday
|
||||
"Make birthdays magenta.
|
||||
Acts on the region or places point where it needs to be."
|
||||
nil
|
||||
"[Mag]" _ " [Nrm]")
|
||||
|
||||
(define-skeleton rem-urgent
|
||||
"Colour urgent notices red.
|
||||
Acts on the region or places point where it needs to be."
|
||||
nil
|
||||
"[Red]" _ " [Nrm]")
|
||||
|
||||
;; menu anyone?
|
||||
|
||||
(easy-menu-define remind-menu
|
||||
remind-conf-mode-map
|
||||
"Menu used in remind-conf-mode."
|
||||
(append '("Remind")
|
||||
'([ "Insert a reminder" rem-skel t])
|
||||
'([ "Insert todays date" rem-today t])
|
||||
'([ "Insert tomorrows date" rem-tomorrow t])
|
||||
'([ "How many days away?" rem-days-away t])
|
||||
'([ "A week away" rem-week-away t])
|
||||
'([ "How many weeks away?" rem-weeks-away t])
|
||||
'([ "Birthday color" rem-birthday t])
|
||||
'([ "Urgent color" rem-urgent t])
|
||||
'([ "Save the file and run a script" rem-save-file t])
|
||||
'("-----")
|
||||
'([ "Setting up the colors - once-off" rem-setup-colors t])
|
||||
))
|
||||
|
||||
|
||||
;; 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) "#")
|
||||
(set (make-local-variable 'comment-end) "\n")
|
||||
(set (make-local-variable 'comment-end-skip) "[ \t]*\\(\\s>\\||#\\)")
|
||||
(set (make-local-variable 'skeleton-end-hook) nil) ; so the skeletons will not automatically go to a new line.
|
||||
(set (make-local-variable 'fill-column) '100);cause I was having problems with autofill.
|
||||
(set (make-local-variable 'indent-line-function) 'remind-indent-line)
|
||||
(use-local-map remind-conf-mode-map)
|
||||
@@ -438,7 +524,5 @@ Acts on the region or places point where it needs to be."
|
||||
(provide 'remind-conf-mode)
|
||||
;;; remind-conf-mode.el ends here
|
||||
|
||||
;;; Indentation code
|
||||
;;; work out how to make the syntax highlighting work only before the (MSG|MSF)
|
||||
;;; keywords and not after.
|
||||
;;; for my own use. keymap to save file and do dailypic C-c C-c in time honoured tradition?
|
||||
;;; work out how to make the syntax highlighting work only before the
|
||||
;;; (MSG|MSF) keywords and not after.
|
||||
@@ -69,6 +69,8 @@ know! Here are the basic guidelines:
|
||||
|
||||
- You can test your language file with the script "tests/tstlang.rem"
|
||||
|
||||
- Your localized strings must be encoded using UTF-8.
|
||||
|
||||
RELEASE NOTES -- miscellaneous info that couldn't go anywhere else!
|
||||
|
||||
1. POPUP REMINDERS
|
||||
|
||||
887
docs/WHATSNEW
887
docs/WHATSNEW
@@ -1,5 +1,869 @@
|
||||
CHANGES TO REMIND
|
||||
|
||||
* VERSION 4.3 Patch 1 - 2024-02-29
|
||||
|
||||
- BUG FIX: tests: "make test" could fail because of a bad test. This
|
||||
has been fixed. There are no actual code changes to any of the programs
|
||||
in Remind compared to 04.03.00.
|
||||
|
||||
* VERSION 4.3 Patch 0 - 2024-02-29
|
||||
|
||||
- IMPROVEMENT: remind: If Remind is compiled on a system that supports
|
||||
inotify, then in server mode (-z0 or -zj) it monitors the reminders file
|
||||
and restarts itself if it detects a change, and also notifies the client.
|
||||
Moving inotify support directly into Remind means that tkremind no longer
|
||||
has to invoke a separate inotifywait process.
|
||||
|
||||
- IMPROVEMENT: remind: Set the CLOEXEC flag on files we open so we
|
||||
don't leak file descriptors to programs that we run. While I don't
|
||||
think there's a security issue here (any program you run can do
|
||||
anything as your userid anyway) it's best to be clean and tidy.
|
||||
|
||||
- IMPROVEMENT: remind: Add localization for the Catalan language, courtesy
|
||||
of Eloi Torrents.
|
||||
|
||||
- IMPROVEMENT: tkremind: Add a .desktop file and icon so TkRemind can be
|
||||
integrated into the desktop menu system, courtesy of Eloi Torrents.
|
||||
|
||||
- CHANGE: Add a new server mode with the "-zj" flag. This is just
|
||||
like "-z0" except it uses JSON messages to communicate with the
|
||||
client rather than an ad-hoc protocol. The "-z0" mode is still
|
||||
supported, but is deprecated.
|
||||
|
||||
- CHANGE: In server mode (-z0 or -zj) any RUN-type reminders, or message
|
||||
commands of the "-kcommand" type are run with standard input and standard
|
||||
output connected to /dev/null. NOTE INCOMPATIBILITY: If you previously
|
||||
relied on RUN-type reminders to pop up reminders in TkRemind, they no
|
||||
longer do. If you want this, you'll have to get the command that you
|
||||
run to pop up its own window with "xmessage" or something similar.
|
||||
|
||||
- IMPROVEMENT: tkremind: Make the "Go to date..." dialog non-modal.
|
||||
|
||||
- CHANGE: remind: Allow the argument to easterdate() and
|
||||
orthodoxeaster() to be omitted, in which case it defaults to
|
||||
today().
|
||||
|
||||
- BUG FIX: Miscellaneous man page fixes.
|
||||
|
||||
- BUG FIX: Fix a leap-year edge-case. The reminder: REM 29 MSG whatever
|
||||
was not triggered on Feb 29 of leap years.
|
||||
|
||||
- BUG FIX: rem2html: Make the version of rem2html track the version of
|
||||
Remind. Noted by Ian! D. Allen.
|
||||
|
||||
* VERSION 4.2 Patch 9 - 2024-02-04
|
||||
|
||||
- CHANGE: remind: Do not attempt to guess terminal background color on
|
||||
startup. Only obtain it as needed. This can prevent mojibake from
|
||||
appearing on terminals that don't support the color query escape
|
||||
sequence.
|
||||
|
||||
- IMPROVEMENT: remind: Add new system variables $NumFullOmits,
|
||||
$MaxFullOmits, $NumPartialOmits and $MaxPartialOmits.
|
||||
|
||||
- IMPROVEMENT: remind: Issue a warning if someone OMITs every possible date.
|
||||
|
||||
- IMPROVEMENT: remind: In several error messages complaining about limits
|
||||
being exceeded, include the actual limit in the error message. Clarify
|
||||
the man page regarding limits on the number of OMITs.
|
||||
|
||||
- MINOR NEW FEATURE: remind: The expression STRING * INT or INT * STRING
|
||||
is now accepted and yields a string that is INT concatenations of the
|
||||
original STRING. In this case, INT must be non-negative and the total
|
||||
string length can't exceed $MaxStringLen.
|
||||
|
||||
- DOCUMENTATION: Add "Astronomical Algorithms" by Jean Meeus to bibliography.
|
||||
|
||||
- DOCUMENTATION FIX: Update address of the Free Software Foundation in the
|
||||
license file.
|
||||
|
||||
- DOCUMENTATION: Note that rem2ps is deprecated and will not received any
|
||||
new features. Further development will happen on rem2pdf.
|
||||
|
||||
- BUG FIX: Preserve the filename() and priority context for queued reminders.
|
||||
Previously, the filename information was lost and the priority was
|
||||
coming from uninitialized memory (yikes!). bug found by Alexander
|
||||
Möller.
|
||||
|
||||
- BUG FIX: build.tk: Various minor improvements.
|
||||
|
||||
- BUG FIX: remind: In server mode, if we de-queue a reminder without
|
||||
triggering it, issue a "NOTE queued %d" message to update the
|
||||
client's notion of the queue size.
|
||||
|
||||
- BUG FIX: tkremind: Fix typo found by Lorenzo Bazzanini.
|
||||
|
||||
* VERSION 4.2 Patch 8 - 2023-12-14
|
||||
|
||||
- NEW FEATURE: Add the $MaxLateMinutes system variable. This suppresses
|
||||
a queued time reminder if the current time is more than $MaxLateMinutes
|
||||
past the trigger time. (This typically only occurs if the computer
|
||||
has been suspended/hibernated and then resumed.)
|
||||
|
||||
- IMPROVEMENT: tkremind: If an error occurs during printing, catch it
|
||||
and change the Queue... button to Errors... (the same way errors in
|
||||
reminder files are handled.)
|
||||
|
||||
- IMPROVEMENT: rem2html: add the --utf8 flag to set the HTML charset to
|
||||
UTF-8.
|
||||
|
||||
- MINOR IMPROVEMENTS: Refactor some of the C code; use symbolic exit
|
||||
statuses and file descriptors for stdin/stdout/stderr where possible.
|
||||
|
||||
- BUG FIX: configure.in: Use better option detection so we don't use the
|
||||
unsupported option -ffat-lto-objects if compiling with clang instead of gcc.
|
||||
|
||||
- BUG FIXES: Many fixes to man pages, some by Jochen Sprickerhof
|
||||
|
||||
- MINOR BUG FIX: If Remind puts itself in the background, only close
|
||||
stdout/stderr if they are not associated with a terminal. If
|
||||
we close a descriptor, dup /dev/null onto it.
|
||||
|
||||
- MINOR BUG FIX: Catch SIGCONT when running in daemon/background mode.
|
||||
This forces the select() call to be interrupted so we can update the
|
||||
sleep time. This really only matters if the computer or the background
|
||||
Remind process is suspended and then resumed.
|
||||
|
||||
* VERSION 4.2 Patch 7 - 2023-10-09
|
||||
|
||||
- IMPROVEMENT: remind: On 32-bit systems, attempt to use a 64-bit time_t
|
||||
if the C library supports that. This lets Remind work properly with
|
||||
dates after 2038 in the few cases it has to call mktime() internally.
|
||||
|
||||
- MINOR NEW FEATURE: remind: Attempt to obtain the terminal background
|
||||
color using an OSC sequence. This normally only happens if standard
|
||||
output is a terminal, but can be forced with the '-@..,t' option.
|
||||
|
||||
- MINOR NEW FEATURE: remind: Add "--version" long option to print out
|
||||
Remind's version and exit.
|
||||
|
||||
- MINOR IMPROVEMENT: tkremind: Use a higher-resolution PNG image for
|
||||
the icon.
|
||||
|
||||
- MINOR IMPROVEMENT: remind-conf-mode.el: Update highlighting rules
|
||||
courtesy of Bill Benedetto
|
||||
|
||||
- MINOR CHANGE: Make AT optional. If we encounter a TIME in a REM
|
||||
command, implicitly begin an AT clause.
|
||||
|
||||
- DOCUMENTATION: Many minor fixes and improvements courtesy of Dan Jacobson.
|
||||
|
||||
- BUG FIX: Make "-w0" set the calendar width based on standard output
|
||||
rather than setting it to zero and causing an infinite loop.
|
||||
|
||||
* VERSION 4.2 Patch 6 - 2023-09-12
|
||||
|
||||
- NEW FEATURE: remind: The "nonomitted()" function takes an optional
|
||||
extra INT argument called "step". See man page for details. Also
|
||||
allows the "start" argument to be greater than the "end" argument,
|
||||
in which case they are effectively swapped.
|
||||
|
||||
- NEW FEATURE: remind: The "slide()" function takes an optional extra
|
||||
INT argument called "step", similar to "nonomitted()". See man page
|
||||
for details.
|
||||
|
||||
- NEW FEATURE: remind: Added the $ParseUntriggered system variable;
|
||||
see the man page for details. You almost certainly will never need
|
||||
to use this.
|
||||
|
||||
- NEW FILE: holidays/ie.rem: Added Irish holidays, courtesy of
|
||||
Amy de Buitléir.
|
||||
|
||||
- CHANGE: remind: The "-tn" option sets all REM statement deltas to
|
||||
++n rather than adding n to any existing REM statement's delta.
|
||||
Additionally, the corresponding system variable $DeltaOffset has
|
||||
been renamed to $DeltaOverride.
|
||||
|
||||
- NEW OPTION: remind: Add the "-tz" option to explicitly set all
|
||||
REM statement deltas to zero.
|
||||
|
||||
- DOCUMENTATION FIX: remind: various documentation improvements.
|
||||
|
||||
- BUG FIX: Correct some errors in Italian localization, courtesy of
|
||||
Emanuele Torre
|
||||
|
||||
* VERSION 4.2 Patch 5 - 2023-04-11
|
||||
|
||||
- MINOR IMPROVEMENT: remind: If someone uses OMIT yyyy-mm-dd UNTIL yyyy-mm-dd
|
||||
give a better error message suggesting THROUGH instead of UNTIL.
|
||||
|
||||
- BUG FIX: remind: The fix for the combination of ADDOMIT and SATISFY that
|
||||
appeared in version 04.02.00 was not complete; the bug has finally been
|
||||
properly fixed.
|
||||
|
||||
- BUG FIX: remind: Remove an unnecessary #include <sys/file.h>.
|
||||
Nothing needed that and it broke compilation on FreeBSD.
|
||||
|
||||
* VERSION 4.2 Patch 4 - 2023-03-15
|
||||
|
||||
- NEW FEATURE: Remind: Add "htmlescape" and "htmlstriptags" built-in
|
||||
functions.
|
||||
|
||||
- NEW FEATURE: Rem2PDF: Add the "--wrap, -y" option to ensure that no
|
||||
printed calendar takes up more than 5 rows. If a calendar would normally
|
||||
require 6 rows, wrap it so the last day or two appear on the first
|
||||
row instead of on a sixth row.
|
||||
|
||||
- NEW FEATURE: Remind: Improve the -k option to allow specification of
|
||||
separate commands for immediately-issued vs. queued reminders. For
|
||||
example:
|
||||
|
||||
remind '-kcmd1 %s' '-k:cmd2 %s' ...
|
||||
|
||||
will use "cmd1" for immediately-issued reminders and "cmd2" for queued
|
||||
ones. If you only use '-k:cmd2 %s' then immediately-issued reminders
|
||||
are simply printed as usual rather than being passed to a command.
|
||||
|
||||
- IMPROVEMENT: Remind: Make "SPECIAL MSG" the same as just "MSG" and
|
||||
the same for MSF, RUN, PS and PSFILE. This effectively lets you use
|
||||
expression-pasting to determine the type of a REM command; see the
|
||||
remind(1) man page for details.
|
||||
|
||||
- MINOR IMPROVEMENT: If "make test" fails, output up to 200 lines of diff
|
||||
so we can see immediately what failed.
|
||||
|
||||
- DOCUMENTATION FIX: Fix some typos; fix TkRemind syntax description.
|
||||
|
||||
- TEST FIX: Make tests run reliably regardless of local machine's time zone.
|
||||
|
||||
- BUG FIX: TkRemind: Don't crash if local installation of Tk lacks the
|
||||
-underlinefg configuration option.
|
||||
|
||||
- BUG FIX: examples/defs.rem: Fix up US Thanksgiving example.
|
||||
|
||||
- BUG FIX: include/holidays/us.rem: Add logic for US holidays that are
|
||||
observed on a Friday if the holiday is a Saturday, or on a Monday if the
|
||||
holiday is a Sunday.
|
||||
|
||||
- BUG FIX: TkRemind: Don't cut off MOON text at the first white-space
|
||||
character.
|
||||
|
||||
- BUG FIX: Remind: prevent functions defined on the command-line (as in
|
||||
remind '-if(x)=whatever') from segfaulting.
|
||||
|
||||
* VERSION 4.2 Patch 3 - 2023-02-10
|
||||
|
||||
- NEW FEATURE: Remind: add the orthodoxeaster() function to return the
|
||||
date of Orthodox Easter.
|
||||
|
||||
- IMPROVEMENT: Add Greek language support courtesy of JeiEl.
|
||||
|
||||
- IMPROVEMENT: Add Greek holiday file courtesy of JeiEl.
|
||||
|
||||
- IMPROVEMENT: Fix the Perl code (rem2pdf, rem2html) to silence Perl::Critic
|
||||
warnings
|
||||
|
||||
- IMPROVEMENT: Many internal code tweaks to eliminate many cppcheck
|
||||
static analysis warnings.
|
||||
|
||||
- DOCUMENTATION IMPROVEMENT: Clarify the distinction between a "time"
|
||||
and a "duration" as suggested by Ian! D. Allen.
|
||||
|
||||
- BUG FIX: Remind: Fix incorrect interaction between sortbanner() and
|
||||
MSF-type reminders. Bug found by Tim Chase.
|
||||
|
||||
- BUG FIX: examples/defs.rem: Fix the calculation of US Tax Day as per
|
||||
Tavis Ormandy and Tim Chase. Also fixed in include/holidays/us.rem
|
||||
|
||||
- BUG FIX: Remind: Add missing #include <fcntl.h> to funcs.c
|
||||
|
||||
- BUG FIX: Remind: Fix undefined integer-overflow behavior in built-in abs()
|
||||
function. Pointed out on IRC by "ubitux".
|
||||
|
||||
* VERSION 4.2 Patch 2 - 2023-01-01
|
||||
|
||||
- NEW FEATURE: Remind: Add the NOQUEUE modifier to the REM statement for
|
||||
explicitly telling Remind not to queue a timed reminder.
|
||||
|
||||
- NEW FEATURE: Remind: Add soleq() function to return the DATETIME of
|
||||
solstices and equinoxes. See $SysInclude/seasons.rem for an example
|
||||
of how to use the function.
|
||||
|
||||
- MINOR IMPROVEMENT: Update examples/astro to include solstices and equinoxes.
|
||||
|
||||
- BUG FIX: TkRemind: Provide better error indication if showing today's
|
||||
reminders fails on startup.
|
||||
|
||||
- BUG FIX: Remind: Refuse to read world-writable directories.
|
||||
|
||||
- BUG FIX: Tests depended on the actual date of the test run. This has
|
||||
been fixed.
|
||||
|
||||
- INTERNAL CHANGE: Remind: Change inappropriately-named "Julian" variables
|
||||
to "DSE" (= Days Since Epoch) since they weren't really holding true
|
||||
Julian dates.
|
||||
|
||||
- INTERNAL CHANGE: Add "SPDX-License-Identifier" tags to most files.
|
||||
|
||||
* 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 command-line option 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
|
||||
can handle UTF-8 encoding, you can enjoy full Unicode support in Remind.
|
||||
|
||||
- NEW FEATURE: Added a rem2pdf Remind-to-PDF converter. It can handle
|
||||
the full UTF-8 character set and features a new PANGO special reminder
|
||||
type that lets you format the text in the PDF calendar (by changing the
|
||||
font size, color, underlining, etc.)
|
||||
|
||||
rem2pdf requires the Pango and Cairo Perl modules. On Debian or
|
||||
Debian-derived systems, these may be installed with:
|
||||
|
||||
apt install libpango-perl libcairo-perl
|
||||
|
||||
Unlike rem2ps, the default font in rem2pdf is "Sans" rather than
|
||||
"Helvetica", as Sans seems to be typeset better by the Pango library.
|
||||
|
||||
- NEW FEATURE: remind: New system variables $Sunday through $Saturday
|
||||
and $January through $December let you set weekday and month names
|
||||
to whatever you like, permitting you to produce calendars in your
|
||||
local language, even if it's not one of the languages Remind supports
|
||||
by default.
|
||||
|
||||
- NEW FEATURE: tkremind: If rem2pdf installed, TkRemind offers you the
|
||||
choice of PDF or PostScript output in the Print dialog.
|
||||
|
||||
- CHANGE: remind: Increase the number of allowed "full OMITs" from 500
|
||||
to 1000.
|
||||
|
||||
- CHANGE: Remove the annoying code that slowed compilation and running
|
||||
on Windows and Mac OS X. I believe the point has been made and free
|
||||
OSes have enough of a critical mass that the annoyances are
|
||||
counter-productive.
|
||||
|
||||
- CLEANUP: remind: C source code: Replace the LAT_DEG, LAT_MIN,
|
||||
LAT_SEC and LON_DEG, LON_MIN, LON_SEC macros with DEFAULT_LATITUDE
|
||||
and DEFAULT_LONGITUDE.
|
||||
|
||||
- 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.
|
||||
|
||||
- BUG FIX: rem2html: Document how to highlight today with a red border
|
||||
|
||||
- BUG FIX: rem2html: Generate and install a man page for rem2html
|
||||
|
||||
- BUG FIX: remind: Get rid of LAT_DEG/LAT_MIN/LAT_SEC and
|
||||
LON_DEG/LON_MIN/LON_SEC macros in favour of DEFAULT_LATITUDE and
|
||||
DEFAULT_LONGITUDE.
|
||||
|
||||
- IMPROVEMENT: All localized languages now use UTF-8 exclusively.
|
||||
Support for old character encodings like ISO-8859-1 and ISO-8859-2
|
||||
has been dropped since modern UNIXes have pretty much standardized
|
||||
on UTF-8.
|
||||
|
||||
- CHANGE: remind: Non-English versions of remind *no longer* accept
|
||||
non-English month- and weekday-names in trigger specifications. This
|
||||
was a misfeature. NOTE INCOMPATIBILITY.
|
||||
|
||||
* VERSION 3.3 Patch 12 - 2022-01-24
|
||||
|
||||
- UPDATE: rem2html: Use JSON::MaybeXS instead of JSON::Any, since JSON::Any
|
||||
is deprecated. NOTE INCOMPATIBILITY: If you don't have JSON::MaybeXS
|
||||
installed, you'll need to install it before trying to install or update
|
||||
rem2html
|
||||
|
||||
- NEW FEATURE: Add a DO command. This is just like INCLUDE, but relative
|
||||
paths are interpreted relative to the directory containing the current
|
||||
file. That is:
|
||||
|
||||
DO somefile.rem
|
||||
|
||||
is equivalent to:
|
||||
|
||||
INCLUDE [filedir()]/somefile.rem
|
||||
|
||||
- NEW FEATURE: Add the $DefaultTDelta system variable and associated
|
||||
-tt[N] command-line option to set a default time delta for timed
|
||||
reminder without an explicit +N delta.
|
||||
|
||||
- IMPROVEMENT: TkRemind: Store .tkremindrc in $XDG_CONFIG_HOME/tkremindrc
|
||||
or $HOME/.config/tkremindrc as per the XDG Base Directory Specification.
|
||||
|
||||
- BUG FIX: remind: Make the shell() built-in function respect
|
||||
$MaxStringLen
|
||||
|
||||
- BUG FIX: Use size_t to track the size of dynamic buffers rather than int.
|
||||
This permits Remind to read in files with lines longer than 1GB and to
|
||||
consume more than 1GB of output from the shell() command, both of which
|
||||
will surely be massively useful. (The old limit was 1GB rather than 2GB
|
||||
because of details of the dynamic buffer resizing algorithm.)
|
||||
|
||||
* VERSION 3.3 Patch 11 - 2021-12-30
|
||||
|
||||
- IMPROVEMENT: TkRemind: Save the print dialog settings so they persist.
|
||||
|
||||
- IMPROVEMENT: TkRemind: Show queue in sorted order.
|
||||
|
||||
- IMPROVEMENT: TkRemind: Pass "-r" flag to inotifywait
|
||||
|
||||
- IMPROVEMENT: TkRemind: Draw moon phases with Tk canvas items rather than
|
||||
using PNG images. This lets them change color along with other TkRemind
|
||||
preferences.
|
||||
|
||||
- IMPROVEMENT: TkRemind: Underline editable reminders when the pointer enters
|
||||
them; fire up the editor with either Button-1 or Button-3 for
|
||||
non-TkRemind-generated reminders.
|
||||
|
||||
- NEW FUNCTION: Remind: Add the isany() built-in function.
|
||||
|
||||
- IMPROVEMENT: rem2html: Add class names indicating number of rows in calendar
|
||||
|
||||
- IMPROVEMENT: remind: In -z0 mode, sleep with higher precision to ensure we
|
||||
wake as close to possible to each 1-minute boundary.
|
||||
|
||||
- IMPROVEMENT: rem2html: Coalesce table.rem-cal CSS into one block. Thanks
|
||||
to Ian! D. Allen for pointing this out.
|
||||
|
||||
- IMPROVEMENT: examples/defs.rem: Modernize the examples and get rid of some
|
||||
cruft.
|
||||
|
||||
- CHANGE: Add $Latitude and $Longitude system variables. Deprecate
|
||||
$LatDeg, $LatMin, $LatSec, $LongDeg, $LongMin and $LongSec.
|
||||
|
||||
- CHANGE: Test: Add "dump $" to test.rem.
|
||||
|
||||
* VERSION 3.3 Patch 10 - 2021-11-30
|
||||
|
||||
- IMPROVEMENT: TkRemind: Apply window and text colors to all GUI elements
|
||||
including buttons and status labels.
|
||||
|
||||
- NEW FEATURE: The new ADDOMIT keyword can shorten reminder files.
|
||||
The command:
|
||||
|
||||
REM ...whatever... ADDOMIT MSG Foo
|
||||
|
||||
behaves identically to:
|
||||
|
||||
REM ...whatever... SATISFY 1
|
||||
IF trigvalid()
|
||||
OMIT [trigdate()] MSG Foo
|
||||
ENDIF
|
||||
|
||||
For example, Labour Day can be displayed and omitted as follows:
|
||||
|
||||
REM Mon 1 Sep SCANFROM -7 ADDOMIT MSG Labour Day
|
||||
|
||||
- UPDATE: Update contrib/remind-conf-mode to latest release
|
||||
|
||||
- CHANGE: The parser does not auto-convert numbers 90-99 to 1990-1999. This
|
||||
was messing up things like "DURATION 90". It also means you can no longer
|
||||
abbreviate the years 1990-1999 as 90-99.
|
||||
|
||||
- BUG FIX: Various documentation fixes
|
||||
|
||||
- BUG FIX: When switching users with the "-u" option, call initgroups()
|
||||
to properly set group membership list.
|
||||
|
||||
* VERSION 3.3 Patch 9 - 2021-10-14
|
||||
|
||||
- NEW FEATURE: Add "-+username" option to tell Remind to trust files owned by
|
||||
"username" and allow RUN directives in them. Idea courtesy of Ian! D. Allen
|
||||
|
||||
- NEW FEATURE: Add "-u+username" variant to tell Remind to switch users to
|
||||
"username" without disabling RUN directives. Idea courtesy of Ian! D. Allen
|
||||
|
||||
- CHANGE: rem2html: rem2html has been moved out of the www/ directory into
|
||||
its own rem2html/ directory. If your system has the prerequisites
|
||||
(namely Perl, Getopt::Long and JSON::Any) then rem2html will be installed
|
||||
by "make install".
|
||||
|
||||
- CHANGE: Remove "cm2rem". It was about 20 years obsolete.
|
||||
|
||||
- CHANGE: rem2html: Use inline data: URL images for moon images by default,
|
||||
thus producing a completely stand-alone HTML file.
|
||||
|
||||
- CHANGE: Remove unnecessary spaces from "remind -pp" JSON output.
|
||||
|
||||
- DOCUMENTATION FIX: Various man page fixes and tweaks.
|
||||
|
||||
- BUG FIX: rem2html: Tweak the default CSS stylesheet; more rational
|
||||
handling of rem2html command-line options.
|
||||
|
||||
- BUG FIX: remind: "remind -c" would sometimes highlight *two* days as
|
||||
"today"; this has been fixed.
|
||||
|
||||
- BUG FIX: Add a missing #ifdef...#endif and remove a C99-ism. This once again
|
||||
allows Remind to be compiled with some very old C compilers.
|
||||
|
||||
* VERSION 3.3 Patch 8 - 2021-09-13
|
||||
|
||||
- NEW FEATURE: remind: Add INCLUDECMD command
|
||||
|
||||
- NEW FEATURE: remind: Add shellescape() built-in function
|
||||
|
||||
- BUG FIX: tkremind: TkRemind would sometimes fill in incorrect initial
|
||||
values for the reminder-editing form if you clicked on a TkRemind-created
|
||||
reminder to edit it. This has been fixed.
|
||||
|
||||
- BUG FIX: tkremind: Get back better error messages from Remind if you
|
||||
try to create a reminder with an invalid date specification.
|
||||
|
||||
- BUG FIX: remind: Catch integer overflow if we try to evaluate $IntMin * -1
|
||||
|
||||
- DOC UPDATES: remind: Minor man page fixes
|
||||
|
||||
* VERSION 3.3 Patch 7 - 2021-05-10
|
||||
|
||||
- MINOR FIX: Refuse to run "make test" as root --- it would fail
|
||||
anyway with an obscure message.
|
||||
|
||||
- BUG FIX: Remind would sometimes compute incorrect trigger date for:
|
||||
REM Tue 29 Feb MSG ...
|
||||
|
||||
- BUG FIX: Remind would sometimes compute incorrect trigger date for
|
||||
a date spec like: Tue 31 2021 MSG ...
|
||||
|
||||
* VERSION 3.3 Patch 6 - 2021-03-30
|
||||
|
||||
- test/test.rem: Change local to en_US.utf-8 only if current locale
|
||||
is not a UTF-8 locale.
|
||||
|
||||
- MINOR CHANGE: Remind's arithmetic operators (+, -, *, /) give errors
|
||||
on overflow rather than silently giving the wrong answer.
|
||||
|
||||
- MINOR CHANGE: Add $IntMin and $IntMax system variables.
|
||||
|
||||
- DOCUMENTATION FIX: Document that TkRemind now requires Tcl/Tk version
|
||||
8.5 or newer.
|
||||
|
||||
* VERSION 3.3 Patch 5 - 2021-01-21
|
||||
|
||||
- NEW FEATURE: tkremind: Add ability to change fonts and colors from
|
||||
@@ -51,7 +915,7 @@ CHANGES TO REMIND
|
||||
When you print from TkRemind, we also invoke Remind with "-itkprint=1"
|
||||
so you can detect that PostScript is being generated.
|
||||
|
||||
- CHANGE: The maxmimum length of a variable name has been increased from
|
||||
- CHANGE: The maximum length of a variable name has been increased from
|
||||
16 characters to 64 characters. Modern computers have plenty of memory.
|
||||
|
||||
- BUG FIXES: Minor documentation updates, typo fixes, clarifications, etc.
|
||||
@@ -229,7 +1093,7 @@ CHANGES TO REMIND
|
||||
|
||||
- BUG FIX: Make parser reject an AT followed by more than one time.
|
||||
|
||||
- BUG FIX: Make parser reject epeated delta or *repeat values.
|
||||
- BUG FIX: Make parser reject repeated delta or *repeat values.
|
||||
|
||||
* Version 3.1 Patch 14 - 2015-04-24
|
||||
|
||||
@@ -420,7 +1284,7 @@ CHANGES TO REMIND
|
||||
|
||||
* Version 3.1 Patch 4 - 2008-02-03
|
||||
|
||||
- ENHANCMENT: tkremind respects the "-b1" option and operates in 24-hour
|
||||
- ENHANCEMENT: tkremind respects the "-b1" option and operates in 24-hour
|
||||
clock mode if the option is supplied.
|
||||
|
||||
- ENHANCEMENT: tkremind has been tweaked to look better with Tcl/Tk 8.5.
|
||||
@@ -559,7 +1423,7 @@ CHANGES TO REMIND
|
||||
|
||||
- The SPECIAL COLOR reminder type has been hacked to behave more like
|
||||
a MSG type. It sorts properly and is emitted as a normal reminder
|
||||
in non-calendar mode. Simlarly, SPECIAL HTML sorts with -g as well.
|
||||
in non-calendar mode. Similarly, SPECIAL HTML sorts with -g as well.
|
||||
|
||||
+ MINOR ENHANCEMENTS
|
||||
|
||||
@@ -647,7 +1511,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
|
||||
|
||||
@@ -794,7 +1658,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.
|
||||
@@ -1324,7 +2188,7 @@ CHANGES TO REMIND
|
||||
of Mikko Silvonen.
|
||||
|
||||
- Changed the date conversion routines to greatly speed up conversion from
|
||||
Julian to yyyy/mm/dd form.
|
||||
Days-since-epoch to yyyy/mm/dd form.
|
||||
|
||||
+ BUG FIXES:
|
||||
|
||||
@@ -1385,7 +2249,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.
|
||||
@@ -1458,7 +2322,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()."
|
||||
|
||||
@@ -1495,7 +2359,7 @@ CHANGES TO REMIND
|
||||
|
||||
- Improved debugging of reminder scripts
|
||||
|
||||
- Took out the "purge" option - it is in general too dificult to tell when
|
||||
- Took out the "purge" option - it is in general too difficult to tell when
|
||||
a reminder has expired for good, so now it's up to you to do this
|
||||
by hand.
|
||||
|
||||
@@ -1600,6 +2464,3 @@ CHANGES TO REMIND
|
||||
* Version 1.0
|
||||
|
||||
- never publicly released.
|
||||
|
||||
|
||||
|
||||
|
||||
19
examples/alignment.rem
Normal file
19
examples/alignment.rem
Normal file
@@ -0,0 +1,19 @@
|
||||
# Demo the columns() function
|
||||
#
|
||||
# Run as: remind -@2 alignment.rem
|
||||
# SPDX-License-Identifier: GPL-2.0-only
|
||||
|
||||
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("")]
|
||||
36
examples/ansitext
Executable file
36
examples/ansitext
Executable file
@@ -0,0 +1,36 @@
|
||||
#!/bin/sh
|
||||
#
|
||||
# A little demo script that displays ANSI text attributes
|
||||
# Not all attributes work on all terminals... your mileage may vary.
|
||||
# SPDX-License-Identifier: GPL-2.0-only
|
||||
|
||||
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
|
||||
69
examples/astro
Executable file
69
examples/astro
Executable file
@@ -0,0 +1,69 @@
|
||||
#!/bin/sh
|
||||
#
|
||||
# A little demo script that displays astronomical events
|
||||
#
|
||||
# Best used in a UTF-8 environment.
|
||||
# SPDX-License-Identifier: GPL-2.0-only
|
||||
|
||||
# Set this variable to 1 if your terminal has a dark background or 0 if
|
||||
# it: light.
|
||||
|
||||
# Set your latitude and longitude correctly for Sunrise/Sunset/Equinox/Solstice
|
||||
#
|
||||
# The values below are for Ottawa, Ontario, Canada
|
||||
latitude="45.420556"
|
||||
longitude="-75.689722"
|
||||
|
||||
remind -g "-i\$Latitude=\"$latitude\"" "-i\$Longitude=\"$longitude\"" -q -@2 - "$@" <<'EOF'
|
||||
SET $AddBlankLines 0
|
||||
BANNER %
|
||||
|
||||
INCLUDE [$SysInclude]/ansitext.rem
|
||||
|
||||
MSG Today is [ansi_bold][$T][ansi_normal], being the [ord($T-date(year($T),1,1)+1)] day of [year($T)].%_
|
||||
|
||||
IF $TerminalBackground == 0
|
||||
SPECIAL COLOR 255 255 0 Sunrise: 🌅 [sunrise()] today and [sunrise($T+1)] tomorrow
|
||||
SPECIAL COLOR 255 128 0 Sunset: 🌇 [sunset()] today and [sunset($T+1)] tomorrow%_
|
||||
ELSE
|
||||
SPECIAL COLOR 128 128 0 Sunrise: 🌅 [sunrise()] today and [sunrise($T+1)] tomorrow
|
||||
SPECIAL COLOR 128 32 0 Sunset: 🌇 [sunset()] today and [sunset($T+1)] tomorrow%_
|
||||
|
||||
ENDIF
|
||||
EOF
|
||||
|
||||
remind -g "-i\$Latitude=\"$latitude\"" "-i\$Longitude=\"$longitude\"" -q -@2 - "$@" <<'EOF'
|
||||
SET $AddBlankLines 0
|
||||
BANNER %
|
||||
IF $TerminalBackground == 0
|
||||
REM [moondatetime(0)] +60 SPECIAL COLOR 255 255 0 New moon: 🌑 [$T] %3 (%b)
|
||||
REM [moondatetime(1)] +60 SPECIAL COLOR 255 255 128 First Quarter: 🌓 [$T] %3 (%b)
|
||||
REM [moondatetime(2)] +60 SPECIAL COLOR 255 255 255 Full moon: 🌕 [$T] %3 (%b)
|
||||
REM [moondatetime(3)] +60 SPECIAL COLOR 255 255 128 Last Quarter: 🌗 [$T] %3 (%b)
|
||||
ELSE
|
||||
REM [moondatetime(0)] +60 SPECIAL COLOR 128 128 0 New moon: 🌑 [$T] %3 (%b)
|
||||
REM [moondatetime(1)] +60 SPECIAL COLOR 128 128 64 First Quarter: 🌓 [$T] %3 (%b)
|
||||
REM [moondatetime(2)] +60 SPECIAL COLOR 0 0 0 Full moon: 🌕 [$T] %3 (%b)
|
||||
REM [moondatetime(3)] +60 SPECIAL COLOR 128 128 64 Last Quarter: 🌗 [$T] %3 (%b)
|
||||
ENDIF
|
||||
EOF
|
||||
|
||||
echo ""
|
||||
|
||||
remind -g "-i\$Latitude=\"$latitude\"" "-i\$Longitude=\"$longitude\"" -q -@2 - "$@" <<'EOF'
|
||||
SET $AddBlankLines 0
|
||||
BANNER %
|
||||
|
||||
IF $LatDeg >= 0
|
||||
REM [soleq(0)] +366 MSG Next Vernal Equinox: 🌼 [$T] %3 (%b)
|
||||
REM [soleq(1)] +366 MSG Next Summer Solstice: 😎 [$T] %3 (%b)
|
||||
REM [soleq(2)] +366 MSG Next Autumnal Equinox: 🍂 [$T] %3 (%b)
|
||||
REM [soleq(3)] +366 MSG Next Winter Solstice: ❄️ [$T] %3 (%b)
|
||||
ELSE
|
||||
REM [soleq(0)] +366 MSG Next Autumnal Equinox: 🍂 [$T] %3 (%b)
|
||||
REM [soleq(1)] +366 MSG Next Winter Solstice: ❄️ [$T] %3 (%b)
|
||||
REM [soleq(2)] +366 MSG Next Vernal Equinox: 🌼 [$T] %3 (%b)
|
||||
REM [soleq(3)] +366 MSG Next Summer Solstice: 😎 [$T] %3 (%b)
|
||||
ENDIF
|
||||
|
||||
EOF
|
||||
@@ -14,10 +14,10 @@
|
||||
# "#USHOLS" for U.S. holidays #
|
||||
# "#JHOLS" for Jewish holidays #
|
||||
# "#PSSTUFF" for nifty PostScript examples #
|
||||
# "#COLORS" for examples of ANSI color escape sequences. #
|
||||
# #
|
||||
# This file is part of REMIND. #
|
||||
# Copyright (C) 1992-2018 Dianne Skoll #
|
||||
# Copyright (C) 1992-2024 Dianne Skoll #
|
||||
# SPDX-License-Identifier: GPL-2.0-only
|
||||
# #
|
||||
#############################################################################
|
||||
|
||||
@@ -26,75 +26,22 @@ RUN OFF
|
||||
################################################
|
||||
# Ensure required version of remind is used... #
|
||||
################################################
|
||||
IF version() < "03.01.09"
|
||||
ERRMSG This file requires at least version 03.01.09 of Remind.%
|
||||
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
|
||||
SET Week_4 22
|
||||
FSET _last(mo) "1 " + MON((mo%12)+1) + " --7"
|
||||
|
||||
# Handy function to provide SCANFROM dates...
|
||||
FSET _back(days) $U-days
|
||||
|
||||
#################################################################
|
||||
# Function that removes a single leading zero from a string... #
|
||||
@@ -123,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 [_back(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
|
||||
|
||||
##########################################################################
|
||||
# #
|
||||
@@ -205,6 +125,8 @@ REM Sat Sun SPECIAL SHADE 220
|
||||
# The following holidays were provided by Dave Rickel #
|
||||
# Modified by D. Skoll to give safe OMITs for moveable holidays #
|
||||
# #
|
||||
# NOTE: See include/holidays/us.rem for more up-to-date definitions #
|
||||
# #
|
||||
#############################################################################
|
||||
|
||||
SET SaveTrig $NumTrig
|
||||
@@ -217,64 +139,90 @@ REM [easter+39] MSG %"Ascension Day%"
|
||||
REM [easter+49] MSG %"Pentecost%"
|
||||
|
||||
# Some holidays are omitted, some are not. You may want to change
|
||||
# which ones are omitted - use the general forms shown below.
|
||||
# You'll need the _back() function and the Week_n variables defined
|
||||
# way up in the file.
|
||||
# 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%"
|
||||
REM Feb 2 MSG %"Ground Hog Day%"
|
||||
REM Feb 14 MSG %"Valentine's%" Day
|
||||
REM Mon Feb [Week_3] SCANFROM [_back(7)] SATISFY 1
|
||||
OMIT [$T] MSG %"President's Day%"
|
||||
REM Mar 17 MSG %"St. Patrick's%" 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 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 [_back(7)] SATISFY 1
|
||||
OMIT [$T] MSG %"Memorial Day%"
|
||||
REM Jun 14 MSG %"Flag Day%"
|
||||
REM Sun Jun [Week_3] MSG %"Father's Day%"
|
||||
REM Mon Sep [Week_1] SCANFROM [_back(7)] SATISFY 1
|
||||
OMIT [$T] MSG %"Labor Day%"
|
||||
REM Mon Oct [Week_2] MSG %"Columbus Day%"
|
||||
REM Nov 11 MSG %"Veterans Day%"
|
||||
REM Apr 1 MSG %"April Fool's%" Day
|
||||
|
||||
REM Oct 30 MSG %"Mischief Night%"
|
||||
REM Oct 31 MSG %"Halloween%"
|
||||
REM Tue Nov 2 SCANFROM [_back(7)] \
|
||||
SATISFY [($Ty % 4) == 0] \
|
||||
MSG %"Election%" Day
|
||||
REM Thu Nov [Week_4] SCANFROM [_back(7)] SATISFY 1
|
||||
OMIT [$T] MSG %"Thanksgiving%" Day
|
||||
REM Fri Nov [Week_4+1] SCANFROM [_back(7)] SATISFY 1
|
||||
OMIT [$T] MSG %"Thanksgiving%" (cont.)
|
||||
OMIT Dec 24 MSG %"Christmas Eve%"
|
||||
OMIT Dec 25 MSG %"Christmas%" Day
|
||||
# US Tax Day
|
||||
PUSH-OMIT-CONTEXT
|
||||
# Normal case: 16 April falls Mon-Fri
|
||||
REM 16 Apr SCANFROM -7 ADDOMIT SATISFY [$Tw >= 1 && $Tw <= 5] MSG Emancipation Day
|
||||
|
||||
# 16 April falls on Saturday: Observe on the 15th
|
||||
REM 15 Apr SCANFROM -7 ADDOMIT SATISFY [$Tw == 5] MSG Emancipation Day (observed)
|
||||
|
||||
# 16 April falls on Sunday: Observe on the 17th
|
||||
REM 17 Apr SCANFROM -7 ADDOMIT SATISFY [$Tw == 1] MSG Emancipation Day (observed)
|
||||
|
||||
# If you live in Maine or Massachussetts, uncomment the next line
|
||||
# REM Third Monday in April SCANFROM -7 ADDOMIT MSG Patriots Day
|
||||
|
||||
REM Apr 15 OMIT Sat Sun AFTER MSG Tax Day
|
||||
POP-OMIT-CONTEXT
|
||||
|
||||
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 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 Fri Nov [Week_4+1] SCANFROM -7 ADDOMIT MSG %"Thanksgiving (cont.)%"
|
||||
OMIT Dec 24 MSG %"Christmas Eve%"
|
||||
OMIT Dec 25 MSG %"Christmas%" Day
|
||||
|
||||
##########################################################################
|
||||
# #
|
||||
# If any US holidays were triggered above, shade in the calendar #
|
||||
# entry in PostScript. This is not quite correct, as it blots out any #
|
||||
# other PostScript stuff above. I was too lazy to do it properly :-) #
|
||||
# entry in PostScript. #
|
||||
# #
|
||||
##########################################################################
|
||||
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
|
||||
##########################################################################
|
||||
# #
|
||||
@@ -291,10 +239,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.
|
||||
@@ -495,48 +443,10 @@ REM Friday CAL Candle lighting at [sunset($T)-18]
|
||||
REM Saturday CAL Havdalah at [sunset($T)+42]
|
||||
|
||||
#COLORS
|
||||
##########################################################################
|
||||
# #
|
||||
# This contains sample ANSI escape sequences for coloring messages. #
|
||||
# It should work on an IBM PC with the ANSI.SYS driver, and on #
|
||||
# other terminals which use the ANSI sequences. #
|
||||
# #
|
||||
# This information was provided by Gail Gurman.
|
||||
# #
|
||||
##########################################################################
|
||||
# Colors - use Nrm to reset to normal text.
|
||||
SET Esc CHAR(27)
|
||||
|
||||
SET Nrm Esc + "[0m"
|
||||
SET Blk Esc + "[0;30m"
|
||||
SET Red Esc + "[0;31m"
|
||||
SET Grn Esc + "[0;32m"
|
||||
SET Ylw Esc + "[0;33m"
|
||||
SET Blu Esc + "[0;34m"
|
||||
SET Mag Esc + "[0;35m"
|
||||
SET Cyn Esc + "[0;36m"
|
||||
SET Wht Esc + "[0;37m"
|
||||
SET Gry Esc + "[30;1m"
|
||||
SET BrRed Esc + "[31;1m"
|
||||
SET BrGrn Esc + "[32;1m"
|
||||
SET BrYlw Esc + "[33;1m"
|
||||
SET BrBlu Esc + "[34;1m"
|
||||
SET BrMag Esc + "[35;1m"
|
||||
SET BrCyn Esc + "[36;1m"
|
||||
SET BrWht Esc + "[37;1m"
|
||||
|
||||
# Examples
|
||||
REM MSG A [Blu]blue[Nrm] reminder.
|
||||
REM MSG [Red]%"A red reminder%" safe to use in the calendar mode.[Nrm]
|
||||
|
||||
# Here is an example of how to use msgprefix() and msgsuffix(). These
|
||||
# will highlight priority-0 reminders in bright red,
|
||||
# priority-2500 in red, and priority-7500 in blue. All others
|
||||
# will be in the normal colors
|
||||
FSET msgprefix(x) iif(x==0, BrRed, x==2500, Red, x==7500, Blu, Nrm)
|
||||
|
||||
# Don't forget to return to normal color set at the end of reminder!
|
||||
FSET msgsuffix(x) Nrm
|
||||
REM 1 SPECIAL COLOR 0 0 255 A blue reminder.
|
||||
REM 2 SPECIAL COLOR 255 0 0 %"A red reminder%" safe to use in the calendar mode.
|
||||
|
||||
# The next examples are great for putting right at the end of the reminder
|
||||
# file. They make queued reminders more eye-catching when they pop up.
|
||||
|
||||
@@ -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
|
||||
|
||||
35
include/ansitext.rem
Normal file
35
include/ansitext.rem
Normal file
@@ -0,0 +1,35 @@
|
||||
# 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-2024 by Dianne Skoll
|
||||
# SPDX-License-Identifier: GPL-2.0-only
|
||||
|
||||
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!
|
||||
30
include/holidays/ca.rem
Normal file
30
include/holidays/ca.rem
Normal file
@@ -0,0 +1,30 @@
|
||||
# Canadian holidays
|
||||
# SPDX-License-Identifier: GPL-2.0-only
|
||||
|
||||
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
20
include/holidays/fr.rem
Normal 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%"
|
||||
39
include/holidays/gr.rem
Normal file
39
include/holidays/gr.rem
Normal file
@@ -0,0 +1,39 @@
|
||||
# Greek national holidays
|
||||
# ΑΡΓΙΕΣ (για όλους)
|
||||
|
||||
# fixed
|
||||
REM 1 Jan MSG ΠΡΩΤΟΧΡΟΝΙΑ
|
||||
REM 6 Jan MSG ΤΑ ΦΩΤΑ/ ΘΕΟΦΑΝΕΙΑ
|
||||
REM 25 Mar MSG η 25η Μαρτίου
|
||||
REM 15 Aug MSG 15Αύγουστος
|
||||
REM 28 Oct MSG ΟΧΙ
|
||||
REM 25 Dec MSG ΧΡΙΣΤΟΥΓΕΝΝΑ
|
||||
REM 26 Dec MSG ΧΡΙΣΤΟΥΓΕΝΝΑ2
|
||||
|
||||
REM [orthodoxeaster($Uy)+1] ΔΕΥΤΕΡΑ ΤΟΥ ΠΑΣΧΑ
|
||||
|
||||
|
||||
# May first is a national holiday except if Sunday, day of great week (week before easter) or Monday after easter, then
|
||||
# minister decides moving that holiday. Here is a likely assumption of how this day might be moved.
|
||||
# Uncomment following lines to enable.
|
||||
|
||||
set PM date($Uy,5,1)
|
||||
# IF PM>=orthodoxeaster($Uy)-7 && PM<=orthodoxeaster($Uy)+1
|
||||
# IF PM<orthodoxeaster($Uy)-3
|
||||
# REM orthodoxeaster($Uy) -8 MSG πιθανόν ΕΡΓΑΤΙΚΗ Πρωτομαγιά
|
||||
# ELSE
|
||||
# REM [plusfunc(2)] MSG πιθανόν ΕΡΓΑΤΙΚΗ Πρωτομαγιά
|
||||
# ENDIF
|
||||
# ENDIF
|
||||
# REM [PM] OMIT Sun AFTER MSG Πρωτομαγιά
|
||||
|
||||
REM 1 May MSG Πρωτομαγιά
|
||||
# end of May 1 speculations
|
||||
|
||||
# The following are main national holidays per custom (observed by most but not all)
|
||||
REM [orthodoxeaster($Uy)] -48 MSG Καθαρά Δευτέρα
|
||||
REM [orthodoxeaster($Uy)] -2 MSG Μεγάλη Παρασκευή
|
||||
REM [orthodoxeaster($Uy)] -1 MSG Μεγάλο Σάββατο
|
||||
REM [orthodoxeaster($Uy)+50] MSG Αγίου Πνεύματος
|
||||
|
||||
|
||||
42
include/holidays/ie.rem
Normal file
42
include/holidays/ie.rem
Normal file
@@ -0,0 +1,42 @@
|
||||
;
|
||||
; Irish Holidays
|
||||
;
|
||||
; The dates for the Public ("bank") holidays are taken from the following site:
|
||||
; https://www.citizensinformation.ie/en/employment/employment-rights-and-conditions/leave-and-holidays/public-holidays/
|
||||
;
|
||||
; This file was derived from:
|
||||
; https://github.com/mhwombat/dotWombat/blob/master/.config/remind/IrishHolidays.rem
|
||||
; by Amy de Buitléir.
|
||||
|
||||
; fixed dates
|
||||
OMIT 31 December MSG New Year's Eve (Oíche Chinn Bliana) Public Holiday
|
||||
OMIT 1 January MSG New Year's Day (Lá Caille, Lá Bliana Nua) Public Holiday
|
||||
OMIT 17 March MSG Saint Patrick's Day (Lá Fhéile Pádraig) Public Holiday
|
||||
OMIT 24 December MSG Christmas Eve (Oíche Nollag) Public Holiday
|
||||
OMIT 25 December MSG Christmas Day (Lá Nollag) Public Holiday
|
||||
OMIT 26 December MSG Saint Stephen's Day, Wren Day (Lá Fhéile Stiofáin, Lá an Dreoilín) Public Holiday
|
||||
|
||||
; moving dates
|
||||
|
||||
; First Monday in May
|
||||
REM Monday 1 May SCANFROM -7 ADDOMIT MSG May Day (Lá Bealtaine) Public Holiday
|
||||
|
||||
; First Monday in June
|
||||
REM Monday 1 June SCANFROM -7 ADDOMIT MSG June Public Holiday
|
||||
|
||||
; First Monday in August
|
||||
REM Monday 1 August SCANFROM -7 ADDOMIT MSG August Public Holiday
|
||||
|
||||
; Last Monday in October
|
||||
REM Monday 1 -7 November SCANFROM -7 ADDOMIT MSG October Public Holiday
|
||||
|
||||
; Easter
|
||||
SET easter easterdate(today())
|
||||
REM [TRIGGER(easter-2)] MSG Good Friday (Aoine an Chéasta)
|
||||
REM [TRIGGER(easter)] MSG Easter Sunday (Domhnach Cásca)
|
||||
OMIT [TRIGGER(easter+1)] MSG Easter Monday (Luan Cásca) Public Holiday
|
||||
|
||||
; St. Brigid's Day
|
||||
REM 1 February MSG Saint Brigid's Day (Lá Fhéile Bríde or Imbolc)
|
||||
; The public holiday is the first Monday in February, or 1 February if the date falls on a Friday
|
||||
REM February SCANFROM -7 ADDOMIT SATISFY [($Td==1 && $Tw==5) || ($Td<8 && $Tw==1 && $Td!=4)] MSG Public Holiday
|
||||
112
include/holidays/jewish.rem
Normal file
112
include/holidays/jewish.rem
Normal file
@@ -0,0 +1,112 @@
|
||||
# Major Jewish Holidays
|
||||
# SPDX-License-Identifier: GPL-2.0-only
|
||||
|
||||
# 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
|
||||
|
||||
82
include/holidays/us.rem
Normal file
82
include/holidays/us.rem
Normal file
@@ -0,0 +1,82 @@
|
||||
# US holidays
|
||||
# This file is part of REMIND.
|
||||
# Copyright (C) 1992-2024 Dianne Skoll
|
||||
# SPDX-License-Identifier: GPL-2.0-only
|
||||
|
||||
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 31 Dec SCANFROM -7 ADDOMIT SATISFY [$Tw==5] MSG New Year's Day (observed)
|
||||
REM 2 Jan SCANFROM -7 ADDOMIT SATISFY [$Tw==1] MSG New Year's Day (observed)
|
||||
|
||||
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
|
||||
|
||||
PUSH-OMIT-CONTEXT
|
||||
# Normal case: 16 April falls Mon-Fri
|
||||
REM 16 Apr SCANFROM -7 ADDOMIT SATISFY [$Tw >= 1 && $Tw <= 5] MSG Emancipation Day
|
||||
|
||||
# 16 April falls on Saturday: Observe on the 15th
|
||||
REM 15 Apr SCANFROM -7 ADDOMIT SATISFY [$Tw == 5] MSG Emancipation Day (observed)
|
||||
|
||||
# 16 April falls on Sunday: Observe on the 17th
|
||||
REM 17 Apr SCANFROM -7 ADDOMIT SATISFY [$Tw == 1] MSG Emancipation Day (observed)
|
||||
|
||||
# If you live in Maine or Massachussetts, uncomment the next line
|
||||
# REM Third Monday in April SCANFROM -7 ADDOMIT MSG Patriots Day
|
||||
|
||||
REM Apr 15 OMIT Sat Sun AFTER MSG %"Income tax%" due
|
||||
POP-OMIT-CONTEXT
|
||||
|
||||
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
|
||||
|
||||
OMIT 19 June MSG Juneteenth
|
||||
REM 18 June SCANFROM -7 ADDOMIT SATISFY [$Tw==5] MSG Juneteenth (observed)
|
||||
REM 20 June SCANFROM -7 ADDOMIT SATISFY [$Tw==1] MSG Juneteenth (observed)
|
||||
|
||||
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
|
||||
|
||||
OMIT 11 Nov MSG Veterans Day
|
||||
REM 10 Nov SCANFROM -7 ADDOMIT SATISFY [$Tw==5] MSG Veterans Day (observed)
|
||||
REM 12 Nov SCANFROM -7 ADDOMIT SATISFY [$Tw==1] MSG Veterans Day (observed)
|
||||
|
||||
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
|
||||
REM 24 Dec SCANFROM -7 ADDOMIT SATISFY [$Tw==5] MSG Christmas (observed)
|
||||
REM 26 Dec SCANFROM -7 ADDOMIT SATISFY [$Tw==1] MSG Christmas (observed)
|
||||
24
include/lang/auto.rem
Normal file
24
include/lang/auto.rem
Normal file
@@ -0,0 +1,24 @@
|
||||
# SPDX-License-Identifier: GPL-2.0-only
|
||||
SET autolang getenv("REMIND_LANG")
|
||||
|
||||
IF autolang == ""
|
||||
SET autolang getenv("LC_ALL")
|
||||
ENDIF
|
||||
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
|
||||
53
include/lang/ca.rem
Normal file
53
include/lang/ca.rem
Normal file
@@ -0,0 +1,53 @@
|
||||
# Support for the Catalan language.
|
||||
# This file is part of REMIND.
|
||||
# REMIND is Copyright (C) 1992-2024 by Dianne Skoll
|
||||
# This file was created by Eloi Torrents <eloitor@disroot.org>
|
||||
|
||||
SET $Monday "dilluns"
|
||||
SET $Tuesday "dimarts"
|
||||
SET $Wednesday "dimecres"
|
||||
SET $Thursday "dijous"
|
||||
SET $Friday "divendres"
|
||||
SET $Saturday "dissabte"
|
||||
SET $Sunday "diumenge"
|
||||
|
||||
SET $January "gener"
|
||||
SET $February "febrer"
|
||||
SET $March "març"
|
||||
SET $April "abril"
|
||||
SET $May "maig"
|
||||
SET $June "juny"
|
||||
SET $July "juliol"
|
||||
SET $August "agost"
|
||||
SET $September "setembre"
|
||||
SET $October "octubre"
|
||||
SET $November "novembre"
|
||||
SET $December "desembre"
|
||||
|
||||
SET $Today "avui"
|
||||
SET $Tomorrow "demà"
|
||||
FSET subst_bx(a,d,t) iif(d==today()+2, "demà passat", "d'aquí " + (d-today()) + " dies")
|
||||
|
||||
# 1 d'abril vs 1 de maig.
|
||||
FSET subst_sx(a,d,t) iif(isany(substr(mon(d), 1, 1), "a", "o") , "d'", "de")
|
||||
FSET subst_ordinal(d) ""
|
||||
|
||||
BANNER Agenda pel %w, %d %s %m de %y%o:
|
||||
|
||||
SET $Am "am"
|
||||
SET $Pm "pm"
|
||||
|
||||
SET $Ago "fa"
|
||||
SET $Fromnow "des d'avui"
|
||||
SET $On "el dia"
|
||||
SET $Now "ara"
|
||||
SET $At "a les"
|
||||
|
||||
SET $Minute "minut"
|
||||
SET $Mplu "s"
|
||||
SET $Hour "hora"
|
||||
FSET subst_hours(h) iif(h==1, "1 hora", h + " hores")
|
||||
|
||||
SET $Is "és"
|
||||
SET $Was "va ser"
|
||||
SET $And "i"
|
||||
69
include/lang/da.rem
Normal file
69
include/lang/da.rem
Normal file
@@ -0,0 +1,69 @@
|
||||
# Support for the Danish language.
|
||||
# This file is part of REMIND.
|
||||
# REMIND is Copyright (C) 1992-2024 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
89
include/lang/de.rem
Normal file
@@ -0,0 +1,89 @@
|
||||
# Support for the German language.
|
||||
# This file is part of REMIND.
|
||||
# REMIND is Copyright (C) 1992-2024 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
4
include/lang/en.rem
Normal file
@@ -0,0 +1,4 @@
|
||||
# Support for the English language.
|
||||
# This file is part of REMIND.
|
||||
# REMIND is Copyright (C) 1992-2024 by Dianne Skoll
|
||||
# Nothing to do for English since it is the default.
|
||||
48
include/lang/es.rem
Normal file
48
include/lang/es.rem
Normal file
@@ -0,0 +1,48 @@
|
||||
# Support for the Spanish language.
|
||||
# This file is part of REMIND.
|
||||
# REMIND is Copyright (C) 1992-2024 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
94
include/lang/fi.rem
Normal file
@@ -0,0 +1,94 @@
|
||||
# Support for the Finnish language.
|
||||
# This file is part of REMIND.
|
||||
# REMIND is Copyright (C) 1992-2024 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
62
include/lang/fr.rem
Normal file
@@ -0,0 +1,62 @@
|
||||
# Support for the French language.
|
||||
# This file is part of REMIND.
|
||||
# REMIND is Copyright (C) 1992-2024 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))
|
||||
83
include/lang/gr.rem
Normal file
83
include/lang/gr.rem
Normal file
@@ -0,0 +1,83 @@
|
||||
# Support for the Hellenic (Greek) language.
|
||||
# This file is part of REMIND.
|
||||
# REMIND is Copyright (C) 1992-2024 by Dianne Skoll
|
||||
# This file is derived from a translation by jarlaxl lamat (jarlaxl@freemail.gr)
|
||||
|
||||
SET $Sunday "Κυριακή"
|
||||
SET $Monday "Δευτέρα"
|
||||
SET $Tuesday "Τρίτη"
|
||||
SET $Wednesday "Τετάρτη"
|
||||
SET $Thursday "Πέμπτη"
|
||||
SET $Friday "Παρασκευή"
|
||||
SET $Saturday "Σάββατο"
|
||||
|
||||
SET $January "Ιανουάρ."
|
||||
SET $February "Φεβρουάρ."
|
||||
SET $March "Μάρτ."
|
||||
SET $April "Απρίλ."
|
||||
SET $May "Μαι."
|
||||
SET $June "Ιούν."
|
||||
SET $July "Ιούλ."
|
||||
SET $August "Αυγουστ."
|
||||
SET $September "Σεπτέμβρ."
|
||||
SET $October "Οκτώβρ."
|
||||
SET $November "Νοέμβρ."
|
||||
SET $December "Δεκέμβρ."
|
||||
|
||||
SET $Today "σήμερα"
|
||||
SET $Tomorrow "αύριο"
|
||||
|
||||
BANNER Υπενθυμίσεις: %w, %d %m, %y%o:
|
||||
|
||||
SET $Am "πμ"
|
||||
SET $Pm "μμ"
|
||||
|
||||
SET $Ago "πριν"
|
||||
SET $Fromnow "από τώρα"
|
||||
|
||||
SET $On "την"
|
||||
|
||||
SET $Now "τώρα"
|
||||
SET $At "στις"
|
||||
SET $Minute "λεπτά"
|
||||
SET $Hour "ώρες"
|
||||
SET $Is "είναι"
|
||||
SET $Was "ήταν"
|
||||
SET $And "και"
|
||||
SET $Hplu ""
|
||||
SET $Mplu ""
|
||||
|
||||
FSET subst_bx(a, d, t) "σε " + (d - today()) + " ημέρες"
|
||||
FSET subst_ordinal(d) "."
|
||||
FSET subst_a_alt(d) wkday(d) + ", " + 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_g_alt(d) wkday(d) + ", " + 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)
|
||||
|
||||
# Localization of various astronomical events
|
||||
|
||||
# Perihelion
|
||||
SET earthseasons_Perihelion_str "Περιήλιον"
|
||||
|
||||
# Vernal equinox
|
||||
SET earthseasons_EquinoxMar_str "Εαρινή ισημερία"
|
||||
|
||||
# Summer solstice
|
||||
SET earthseasons_SolsticeJun_str "Θερινό ηλιοστάσιο"
|
||||
|
||||
# Aphelion
|
||||
SET earthseasons_Aphelion_str "Αφήλιον"
|
||||
|
||||
# Autumnal Equinox
|
||||
SET earthseasons_EquinoxSep_str "Φθινοπωρινή ισημερία"
|
||||
|
||||
# Winter Solstice
|
||||
SET earthseasons_SolsticeDec_str "Χειμερινό ηλιοστάσιο"
|
||||
|
||||
# Daylight saving time starts
|
||||
SET daylightST_starts_str "Έναρξη θέρους"
|
||||
|
||||
# Daylight saving time ends
|
||||
SET daylightST_ends_str "Τέλος θέρους"
|
||||
51
include/lang/is.rem
Normal file
51
include/lang/is.rem
Normal file
@@ -0,0 +1,51 @@
|
||||
# Support for the Icelanding language.
|
||||
# This file is part of REMIND.
|
||||
# REMIND is Copyright (C) 1992-2024 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
67
include/lang/it.rem
Normal file
@@ -0,0 +1,67 @@
|
||||
# Support for the Italian language.
|
||||
# This file is part of REMIND.
|
||||
# REMIND is Copyright (C) 1992-2024 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
56
include/lang/nl.rem
Normal file
@@ -0,0 +1,56 @@
|
||||
# Support for the Dutch language.
|
||||
# This file is part of REMIND.
|
||||
# REMIND is Copyright (C) 1992-2024 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
58
include/lang/no.rem
Normal file
@@ -0,0 +1,58 @@
|
||||
# Support for the Norwegian language.
|
||||
# This file is part of REMIND.
|
||||
# REMIND is Copyright (C) 1992-2024 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
69
include/lang/pl.rem
Normal file
@@ -0,0 +1,69 @@
|
||||
# Support for the Polish language.
|
||||
# This file is part of REMIND.
|
||||
# REMIND is Copyright (C) 1992-2024 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
69
include/lang/pt.rem
Normal file
@@ -0,0 +1,69 @@
|
||||
# Support for the (Brazilian) Portuguese language.
|
||||
# This file is part of REMIND.
|
||||
# REMIND is Copyright (C) 1992-2024 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
68
include/lang/ro.rem
Normal file
@@ -0,0 +1,68 @@
|
||||
# Support for the Romanian language.
|
||||
# This file is part of REMIND.
|
||||
# REMIND is Copyright (C) 1992-2024 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")
|
||||
16
include/seasons.rem
Normal file
16
include/seasons.rem
Normal file
@@ -0,0 +1,16 @@
|
||||
# Equinoxes and solstices
|
||||
# SPDX-License-Identifier: GPL-2.0-only
|
||||
|
||||
IF $LatDeg >= 0
|
||||
# Northern Hemisphere
|
||||
REM NOQUEUE [soleq(0)] MSG %"Vernal Equinox%" is %3.
|
||||
REM NOQUEUE [soleq(1)] MSG %"Summer Solstice%" is %3.
|
||||
REM NOQUEUE [soleq(2)] MSG %"Autumnal Equinox%" is %3.
|
||||
REM NOQUEUE [soleq(3)] MSG %"Winter Solstice%" is %3.
|
||||
ELSE
|
||||
# Southern Hemisphere
|
||||
REM NOQUEUE [soleq(0)] MSG %"Autumnal Equinox%" is %3.
|
||||
REM NOQUEUE [soleq(1)] MSG %"Winter Solstice%" is %3.
|
||||
REM NOQUEUE [soleq(2)] MSG %"Vernal Equinox%" is %3.
|
||||
REM NOQUEUE [soleq(3)] MSG %"Summer Solstice%" is %3.
|
||||
ENDIF
|
||||
2
include/site/README
Normal file
2
include/site/README
Normal file
@@ -0,0 +1,2 @@
|
||||
This directory is for system administrators to install site-wide
|
||||
Remind scripts that are useful to their user-base.
|
||||
25
man/cm2rem.1
25
man/cm2rem.1
@@ -1,25 +0,0 @@
|
||||
.TH CM2REM 1 "18 October 1999"
|
||||
.UC 4
|
||||
.SH NAME
|
||||
cm2rem.tcl \- Convert Sun's "cm" input file to Remind format
|
||||
.SH SYNOPSIS
|
||||
.B cm2rem.tcl < cm_file > remind_file
|
||||
.SH DESCRIPTION
|
||||
\fBcm2rem.tcl\fR reads the Sun calendar manager data file and converts
|
||||
it into a \fBRemind\fR script. Note that \fBcm2rem.tcl\fR can convert
|
||||
\fIonly\fR version 3 calendar manager files. If you are using version 4
|
||||
files, there should be a system utility to convert them to version 3 files.
|
||||
.SH AUTHOR
|
||||
\fBcm2rem.tcl\fR was written by Dianne Skoll <dianne@skoll.ca>.
|
||||
.SH BUGS
|
||||
Not all of the Sun calendar manager options are respected. In particular,
|
||||
nothing is done for e-mail actions. Also, the resulting Remind script
|
||||
is not editable with \fBTkRemind\fR; you can only edit it with a text
|
||||
editor.
|
||||
.PP
|
||||
\fBcm2rem.tcl\fR requires Tcl/Tk version 8.0 or higher. The
|
||||
\fBtclsh\fR interpreter must be on your \fBpath\fR.
|
||||
|
||||
.SH SEE ALSO
|
||||
\fBremind(1)\fR, \fBtkremind(1)\fR
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
.TH REM 1 "1 January 2020"
|
||||
.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
|
||||
\fBremind\fR(1)
|
||||
@@ -1,22 +1,29 @@
|
||||
.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
|
||||
.SH SYNOPSIS
|
||||
.B rem2ps [\fIoptions\fR]
|
||||
.SH DESCRIPTION
|
||||
\fBRem2ps\fR reads the standard input, which should be the results of
|
||||
\fBrem2ps\fR reads the standard input, which should be the results of
|
||||
running \fBRemind\fR with the \fB\-p\fR or \fB\-pp\fR option. It
|
||||
emits PostScript code (which draws a calendar) to the standard output.
|
||||
.PP
|
||||
See the section "Rem2PS Input Format" for details about the \fB\-p\fR
|
||||
Although \fBrem2ps\fR will be maintained, no new features will be added
|
||||
to it. Instead, all new development will continue on \fBrem2pdf\fR.
|
||||
.PP
|
||||
See the section "REM2PS INPUT FORMAT" for details about the \fB\-p\fR
|
||||
data. This may be useful if you wish to create other \fBRemind\fR
|
||||
back-ends.
|
||||
.PP
|
||||
Note that \fBrem2ps\fR does not handle UTF-8 input. If you need to
|
||||
render characters outside the ASCII character set, see
|
||||
\fBrem2pdf\fR instead.
|
||||
|
||||
.SH OPTIONS
|
||||
.TP
|
||||
.B \-v
|
||||
Be more verbose. This causes \fBRem2ps\fR to print progress messages
|
||||
Be more verbose. This causes \fBrem2ps\fR to print progress messages
|
||||
to the standard error stream. Normally, it is silent.
|
||||
.TP
|
||||
.B \-p file
|
||||
@@ -61,7 +68,9 @@ there is room and otherwise follows \fIn\fR=2 yields the same results as
|
||||
.TP
|
||||
.B \-i
|
||||
Use ISO 8859-1 standard encoding for the PostScript fonts. If you do
|
||||
not use this option, the default encoding is used.
|
||||
not use this option, the default encoding is used. If you use this option,
|
||||
you probably also need to convert Remind's output (typically UTF-8)
|
||||
to ISO-8859-1 using \fBiconv\fR(1).
|
||||
.TP
|
||||
.B \-e
|
||||
Make the calendar fill the entire page. By default, the calendar is
|
||||
@@ -127,7 +136,7 @@ numbers.
|
||||
|
||||
.PP
|
||||
Type "rem2ps \-m help" for a list of available media. Note that the media
|
||||
type (and all \fBRem2ps\fR options) are case-sensitive. If you don't use
|
||||
type (and all \fBrem2ps\fR options) are case-sensitive. If you don't use
|
||||
the \fB\-m\fR option, the media defaults to a compiled-in default - this
|
||||
is usually Letter for North America and A4 for Europe. The "\-m help"
|
||||
option will display the compiled-in default.
|
||||
@@ -187,8 +196,8 @@ for good output:
|
||||
rem2ps \-ol 72 \-sh 12
|
||||
.fi
|
||||
.SH USAGE
|
||||
To use \fBRem2ps\fR, you should pipe the output of \fBRemind\fR with the \fB\-p\fR
|
||||
option to \fBRem2ps\fR, and then send the result to a printer. This is most easily
|
||||
To use \fBrem2ps\fR, you should pipe the output of \fBRemind\fR with the \fB\-p\fR
|
||||
option to \fBrem2ps\fR, and then send the result to a printer. This is most easily
|
||||
illustrated with examples:
|
||||
.PP
|
||||
.nf
|
||||
@@ -222,10 +231,10 @@ calendar entries. This border is normally blank space.
|
||||
.TP
|
||||
BoxWidth and BoxHeight
|
||||
The width and height of the calendar box, from center-to-center of the
|
||||
black gridlines.
|
||||
black grid lines.
|
||||
.TP
|
||||
InBoxHeight
|
||||
The height from the center of the bottom black gridline to the top
|
||||
The height from the center of the bottom black grid line to the top
|
||||
of the regular calendar entry area. The space from here to the top
|
||||
of the box is used only to draw the day number.
|
||||
.TP
|
||||
@@ -254,7 +263,7 @@ PostScript files. Always test your PostScript thoroughly with a PostScript
|
||||
viewer before sending it to the printer. You should not use any document
|
||||
structuring comments in your PostScript code.
|
||||
.PP
|
||||
In addition, prior to drawing a calendar page, \fBRem2ps\fR emits
|
||||
In addition, prior to drawing a calendar page, \fBrem2ps\fR emits
|
||||
the following PostScript code:
|
||||
.PP
|
||||
.nf
|
||||
@@ -314,14 +323,14 @@ For an example, create a file called "myprolog" whose contents are:
|
||||
} bind def
|
||||
.fi
|
||||
.PP
|
||||
Use that file with the \fBRem2ps\fR \fB\-p\fR option to create calendars
|
||||
with the year and month in large grey letters in the background of the
|
||||
Use that file with the \fBrem2ps\fR \fB\-p\fR option to create calendars
|
||||
with the year and month in large gray letters in the background of the
|
||||
calendar.
|
||||
.PP
|
||||
.SH REM2PS INPUT FORMAT (-P OPTION)
|
||||
The \fB\-p\fR option is an older, simpler interchange format used by
|
||||
\fBRemind\fR to communicate with back-ends. New back-ends are
|
||||
encoraged to support the new \fB\-pp\fR format preferably, though they
|
||||
encouraged to support the new \fB\-pp\fR format preferably, though they
|
||||
are encouraged to support the older \fB\-p\fR format as well if the
|
||||
older format contains enough information for them to work properly.
|
||||
.PP
|
||||
@@ -340,6 +349,10 @@ month (0 = Sunday, 1 = Monday, 6 = Saturday.) And \fImonday_first\fR is
|
||||
1 if the \fB\-m\fR flag was supplied to \fBRemind\fR, or 0 if it was not.
|
||||
All this information is supplied so back-ends don't need any date calculation
|
||||
facilities.
|
||||
|
||||
Note that all spaces in \fImonth_name\fR will be replaced with
|
||||
underscores. Back-ends should undo this replacement.
|
||||
|
||||
.TP
|
||||
\fIsun mon tue wed thu fri sat\fR
|
||||
This line consists of
|
||||
@@ -347,6 +360,9 @@ space-separated names of days in whatever language \fBRemind\fR was
|
||||
compiled for. This information can be used by back-ends to annotate
|
||||
calendars, and means they don't have to be created for a specific
|
||||
language.
|
||||
|
||||
Note that all spaces in day names will be replaced with
|
||||
underscores. Back-ends should undo this replacement.
|
||||
.TP
|
||||
\fInext_mon next_days\fR
|
||||
The name of the next month and the number of days in it.
|
||||
@@ -367,7 +383,7 @@ been set to "-". The consistent use of "/" is designed to ease parsing.
|
||||
.PP
|
||||
\fIspecial\fR is a string used
|
||||
for "out-of-band" communication with back-ends. If the reminder
|
||||
is a normal reminder, \fIspecial\fR is "*". The \fBRem2PS\fR
|
||||
is a normal reminder, \fIspecial\fR is "*". The \fBrem2ps\fR
|
||||
back-end understands the specials \fBPostScript\fR and \fBPSFile\fR.
|
||||
Other back-ends may understand other specials. A back end should
|
||||
\fIsilently ignore\fR a reminder with a special it doesn't understand.
|
||||
@@ -445,7 +461,7 @@ JSON object. The keys that may be present in the JSON object are as
|
||||
follows:
|
||||
.TP
|
||||
.B date \fIYYYY-MM-DD\fR
|
||||
The \fbdate\fR key will \fIalways\fR be present; it is the trigger date
|
||||
The \fBdate\fR key will \fIalways\fR be present; it is the trigger date
|
||||
of the reminder expressed as a string in the format \fIYYYY-MM-DD\fR
|
||||
.TP
|
||||
.B filename \fIf\fR
|
||||
@@ -475,7 +491,7 @@ present and the value will be the type of SPECIAL (such as SHADE, COLOR,
|
||||
MOON, etc.)
|
||||
.TP
|
||||
.B tags \fIdata\fR
|
||||
If any TAG clauses are present, the \fBtag\fR key will be present and consist
|
||||
If any TAG clauses are present, the \fBtags\fR key will be present and consist
|
||||
of a comma-separated list of tags.
|
||||
.TP
|
||||
.B time \fIt\fR
|
||||
@@ -573,6 +589,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
|
||||
@@ -649,17 +677,20 @@ is desired.
|
||||
|
||||
|
||||
.SH AUTHOR
|
||||
Rem2PS was written by Dianne Skoll <dianne@skoll.ca>
|
||||
rem2ps was written by Dianne Skoll <dianne@skoll.ca>
|
||||
.SH BUGS
|
||||
All \fBRem2ps\fR options are case-sensitive, unlike \fBRemind\fR.
|
||||
All \fBrem2ps\fR options are case-sensitive, unlike \fBRemind\fR.
|
||||
Any time you supply
|
||||
a font name or size, line thickness, or border width, it is treated as a
|
||||
string and sent straight to the PostScript interpreter. Thus, if you
|
||||
supply invalid fonts or sizes, \fBRem2ps\fR will not complain, but the
|
||||
supply invalid fonts or sizes, \fBrem2ps\fR will not complain, but the
|
||||
resulting PostScript output will probably not work.
|
||||
.PP
|
||||
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,
|
||||
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
|
||||
\fBremind\fR, \fBrem2pdf\fR, \fBrem2html\fR, \fBtkremind\fR.
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -1,9 +1,9 @@
|
||||
.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
|
||||
.SH SYNOPSIS
|
||||
.B tkremind \fR[\fIoptions\fR] [\fIread_file\fR] [\fIwrite_file\fR] [\fIconfig_file\fR]
|
||||
.B tkremind \fR[\fIoptions\fR] [\fIread_file\fR [\fIwrite_file\fR [\fIconfig_file\fR]]]
|
||||
.SH DESCRIPTION
|
||||
\fBTkRemind\fR is a graphical front-end to the \fBRemind\fR program.
|
||||
It provides a friendly graphical interface which allows you to view
|
||||
@@ -13,16 +13,18 @@ Although not all of \fBRemind\fR's features are available with \fBTkRemind\fR,
|
||||
it creates. This allows you to learn \fBRemind\fR's syntax and then add
|
||||
extra features as you become a more sophisticated \fBRemind\fR programmer.
|
||||
|
||||
\fBTkRemind\fR is written in Tcl, and requires version 8.0
|
||||
(or higher). It also requires a \fBwish\fR binary.
|
||||
\fBTkRemind\fR is written in Tcl, and requires version 8.5 (or higher)
|
||||
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
|
||||
@@ -42,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
|
||||
@@ -113,6 +121,8 @@ edit the reminder, thereby gaining access to advanced features of
|
||||
To print the current month's calendar, click \fBPrint...\fR on the
|
||||
main calendar window. This brings up the print dialog. Printing
|
||||
either produces a PostScript file or sends PostScript to a UNIX command.
|
||||
(If you have \fBrem2pdf\fR installed, you can choose to produce
|
||||
PDF output rather than PostScript.)
|
||||
|
||||
Select the print destination by choosing either \fBTo file:\fR or
|
||||
\fBTo command:\fR in the print dialog. Press \fBBrowse...\fR to bring
|
||||
@@ -129,12 +139,13 @@ the directory.
|
||||
Select the appropriate paper size and orientation. Activate
|
||||
\fBFill page\fR if you want the calendar to fill the page. This should
|
||||
be the normal case unless you have many reminders in a particular
|
||||
day. (See the \fBRem2PS\fR documentation.)
|
||||
day. (See the \fBRem2PS\fR or \fBrem2pdf\fR documentation.)
|
||||
|
||||
Finally, click \fBPrint\fR to print or \fBCancel\fR to cancel. Note
|
||||
that during printing, \fBRemind\fR is called with the
|
||||
\fB-itkremind=1\fR option and also an additional \fB-itkprint=1\fR
|
||||
option.
|
||||
option. If you are producing PDF output, then the option \fB-itkpdf=1\fR
|
||||
is also supplied to \fBRemind\fR.
|
||||
|
||||
|
||||
.SH EDITING REMINDERS
|
||||
@@ -162,7 +173,18 @@ it with \fBTkRemind\fR.
|
||||
If you have set the "text editor" option correctly, right-clicking
|
||||
on a reminder will bring up a text editor on the file containing
|
||||
the reminder. The cursor will be positioned on the line that
|
||||
generated the reminder.
|
||||
generated the reminder. In addition, if you have a reminder that
|
||||
is editable with an editor but was not created using \fBTkRemind\fR,
|
||||
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
|
||||
|
||||
@@ -170,7 +192,7 @@ If you create "timed" reminders, \fBTkRemind\fR will queue them in
|
||||
the background and pop up boxes as they are triggered. Additionally,
|
||||
if you created the reminder using \fBTkRemind\fR, you will be given the
|
||||
option of "turning off" the reminder for the rest of the day.
|
||||
\fBTkRemind\fR achieves queueing of background reminders by running
|
||||
\fBTkRemind\fR achieves queuing of background reminders by running
|
||||
\fBRemind\fR in \fIserver mode\fR, described later.
|
||||
|
||||
.SH OPTIONS
|
||||
@@ -258,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
|
||||
@@ -277,6 +299,19 @@ Next Month
|
||||
.B Home
|
||||
Today
|
||||
|
||||
.SH IMMEDIATE UPDATES
|
||||
|
||||
If you are running \fBTkRemind\fR on Linux and \fBRemind\fR has been
|
||||
compiled with \fBinotify\fR(7) support, 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,
|
||||
@@ -307,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
|
||||
@@ -318,79 +352,125 @@ 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
|
||||
\fBTkRemind\fR. This mode is called \fIserver mode\fR and is
|
||||
selected by supplying the \fB\-z0\fR option to \fBRemind\fR.
|
||||
selected by supplying the \fB\-zj\fR option to \fBRemind\fR.
|
||||
|
||||
In server mode, \fBRemind\fR operates similar to daemon mode, except
|
||||
it reads commands (one per line)
|
||||
from standard input and writes status lines to standard output.
|
||||
it reads commands (one per line) from standard input and writes status
|
||||
lines to standard output. Each status line is a JSON object.
|
||||
|
||||
The commands accepted in server mode are:
|
||||
|
||||
.TP
|
||||
EXIT
|
||||
Terminate the \fBRemind\fR process. EOF on standard input does the
|
||||
same thing.
|
||||
same thing. \fBRemind\fR exits immediately without printing
|
||||
a JSON status line.
|
||||
|
||||
.TP
|
||||
STATUS
|
||||
Return the number of queued reminders.
|
||||
Return the number of queued reminders. The JSON object looks
|
||||
something like this:
|
||||
.nf
|
||||
|
||||
{"response":"queued","nqueued":n,"command":"STATUS"}
|
||||
|
||||
.fi
|
||||
where \fIn\fR is the number of reminders queued.
|
||||
|
||||
.TP
|
||||
QUEUE or JSONQUEUE
|
||||
Returns the contents of the queue. The JSON object looks something
|
||||
like this:
|
||||
.nf
|
||||
|
||||
{"response":"queue","queue":[ ... ],"command":"QUEUE"}
|
||||
|
||||
.fi
|
||||
The value of the \fBqueue\fR key is an array of JSON objects, each
|
||||
representing a queued reminder.
|
||||
|
||||
.TP
|
||||
REREAD
|
||||
Re-read the reminder file
|
||||
Re-read the reminder file. Returns the following status line:
|
||||
|
||||
.nf
|
||||
|
||||
{"response":"reread","command":"REREAD"}
|
||||
|
||||
.fi
|
||||
|
||||
.PP
|
||||
The status lines written are as follows:
|
||||
Additional status lines written are as follows:
|
||||
|
||||
.TP
|
||||
NOTE reminder \fItime\fR \fItag\fR
|
||||
Signifies the beginning of a timed reminder whose trigger time is
|
||||
\fItime\fR with tag \fItag\fR. If the reminder has no tag, an
|
||||
asterisk is supplied for \fItag\fR. All lines following this line
|
||||
are the body of the reminder, until the line \fBNOTE endreminder\fR
|
||||
is transmitted.
|
||||
.nf
|
||||
|
||||
{"response":"reminder","ttime":tt,"now":now,"tags":tags,"body":body}
|
||||
|
||||
.fi
|
||||
In this line, \fItt\fR is the trigger time of the reminder (expressed
|
||||
as a string), \fInow\fR is the current time, \fItags\fR (if present)
|
||||
is the tag or tags associated with the reminder, and \fIbody\fR is
|
||||
the body of the reminder. This response causes \fBTkRemind\fR to
|
||||
pop up a reminder notification.
|
||||
|
||||
.TP
|
||||
NOTE newdate
|
||||
.nf
|
||||
|
||||
{"response":"newdate"}
|
||||
|
||||
.fi
|
||||
|
||||
This line is emitted whenever \fBRemind\fR has detected a rollover of
|
||||
the system date. The front-end program should redraw its calendar
|
||||
or take whatever other action is needed.
|
||||
|
||||
.TP
|
||||
NOTE reread
|
||||
This line is emitted whenever the number of reminders in \fBRemind\fR's
|
||||
queue changes because of a date rollover or a \fBREREAD\fR command.
|
||||
The front-end should issue a \fBSTATUS\fR command in response to this
|
||||
message.
|
||||
.nf
|
||||
|
||||
.TP
|
||||
NOTE queued \fIn\fR
|
||||
This line is emitted in response to a \fBSTATUS\fR command. The number
|
||||
\fIn\fR is the number of reminders in the queue.
|
||||
{"response":"reread","command":"inotify"}
|
||||
|
||||
.fi
|
||||
|
||||
If \fBRemind\fR was compiled with support for \fBinotify\fR(7), then
|
||||
if it detects a change to the top-level reminder file or directory,
|
||||
it issues the above response. The front-end should redraw its
|
||||
calendar since this response indicates that a change has been made
|
||||
to the reminder file or directory.
|
||||
|
||||
.PP
|
||||
Please note that \fBRemind\fR can write a status message \fIat any time\fR
|
||||
and not just in response to a command sent to its standard input. Therefore,
|
||||
a program that runs \fBRemind\fR in server mode must be prepared to handle
|
||||
asynchronous status messages.
|
||||
|
||||
.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-2024 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
|
||||
remind, rem2ps
|
||||
\fBremind\fR, \fBrem2ps\fR, \fBrem2pdf\fR, \fBrem2html\fR
|
||||
|
||||
30
rem2html/Makefile.in
Normal file
30
rem2html/Makefile.in
Normal file
@@ -0,0 +1,30 @@
|
||||
# Set by configure - don't touch.
|
||||
srcdir=@srcdir@
|
||||
prefix=@prefix@
|
||||
exec_prefix=@exec_prefix@
|
||||
mandir=@mandir@
|
||||
bindir=@bindir@
|
||||
datadir=@datadir@
|
||||
datarootdir=@datarootdir@
|
||||
PERL=@PERL@
|
||||
PERLMODS_NEEDED=JSON::MaybeXS Getopt::Long
|
||||
all:
|
||||
true
|
||||
|
||||
install:
|
||||
@if test "$(PERL)" = "" ; then \
|
||||
echo "Not installing rem2html; Perl is required"; exit 0; fi; \
|
||||
for m in $(PERLMODS_NEEDED) ; \
|
||||
do \
|
||||
$(PERL) -M$$m -e 1 > /dev/null 2>&1; \
|
||||
if test $$? != 0 ; then echo "Not installing rem2html; missing $$m"; exit 0; fi; \
|
||||
done; \
|
||||
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;
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
12
rem2html/README.rem2html
Normal file
12
rem2html/README.rem2html
Normal file
@@ -0,0 +1,12 @@
|
||||
REM2HTML
|
||||
--------
|
||||
|
||||
rem2html is a Perl script that transforms the output of `remind -pp
|
||||
...' to HTML. Type `perl rem2html --help' for usage information.
|
||||
|
||||
rem2html requires the Perl modules `JSON::Any' and `Getopt::Long'. It
|
||||
will not be installed unless you have those modules as well as Perl
|
||||
itself.
|
||||
|
||||
--
|
||||
Dianne Skoll
|
||||
@@ -1,14 +1,16 @@
|
||||
#!/usr/bin/perl
|
||||
#!perl
|
||||
# SPDX-License-Identifier: GPL-2.0-only
|
||||
|
||||
use strict;
|
||||
use warnings;
|
||||
|
||||
use Getopt::Long;
|
||||
use JSON::Any;
|
||||
use JSON::MaybeXS;
|
||||
use Encode;
|
||||
|
||||
my %Options;
|
||||
|
||||
my $rem2html_version = '2.1';
|
||||
my $rem2html_version = '@VERSION@';
|
||||
|
||||
my($days, $shades, $moons, $classes, $Month, $Year, $Numdays, $Firstwkday, $Mondayfirst, $weeks,
|
||||
@Daynames, $Nextmon, $Nextlen, $Prevmon, $Prevlen);
|
||||
@@ -16,15 +18,20 @@ my($days, $shades, $moons, $classes, $Month, $Year, $Numdays, $Firstwkday, $Mond
|
||||
my $TIDY_PROGNAME = $0;
|
||||
$TIDY_PROGNAME =~ s|^.*/||;
|
||||
|
||||
# rem2html -- convert the output of "remind -p" to HTML
|
||||
# rem2html -- convert the output of "remind -pp" to HTML
|
||||
|
||||
=head1 NAME
|
||||
|
||||
rem2html - Convert the output of "remind -p" to HTML
|
||||
rem2html - Convert the output of "remind -pp" to HTML
|
||||
|
||||
=head1 SYNOPSIS
|
||||
|
||||
remind -p ... | rem2html [options]
|
||||
remind -pp ... | rem2html [options]
|
||||
|
||||
You can also use the old interchange format as below, but the -pp
|
||||
version is preferred.
|
||||
|
||||
remind -p ... | rem2html [options]
|
||||
|
||||
=head1 OPTIONS
|
||||
|
||||
@@ -38,6 +45,11 @@ Print usage information
|
||||
|
||||
Print version
|
||||
|
||||
=item --utf8
|
||||
|
||||
Assume standard input is encoded in UTF-8; write UTF-8 data to standard
|
||||
output.
|
||||
|
||||
=item --backurl I<url>
|
||||
|
||||
When producing the small calendar for the previous month, make the
|
||||
@@ -50,13 +62,21 @@ month name a link to I<url>.
|
||||
|
||||
=item --imgbase I<url>
|
||||
|
||||
When creating URLs for images and the stylesheet, use
|
||||
I<url> as the base URL.
|
||||
When creating URLs for the stylesheet or external images, use I<url>
|
||||
as the base URL.
|
||||
|
||||
=item --pngs
|
||||
|
||||
Normally, rem2html uses inline "data:" URLs for the moon phase images,
|
||||
yielding a standalone HTML file. The C<--pngs> option makes it use
|
||||
external images named firstquarter.png, fullmoon.png, lastquarter.png
|
||||
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 I<not> interpreted relative to B<imgbase>.
|
||||
I<url.css> is interpreted relative to B<imgbase> I<unless> it starts
|
||||
with a "/".
|
||||
|
||||
=item --nostyle
|
||||
|
||||
@@ -83,11 +103,47 @@ Insert I<html_text> right before the E<lt>/bodyE<gt> tag.
|
||||
|
||||
=back
|
||||
|
||||
=head1 SPECIALS SUPPORTED
|
||||
|
||||
The rem2html back-end supports the following SPECIAL reminders:
|
||||
|
||||
=over
|
||||
|
||||
=item HTML
|
||||
|
||||
Add an HTML reminder to the calendar. All HTML tags are available.
|
||||
|
||||
=item HTMLCLASS
|
||||
|
||||
Add a CSS class to the box representing the trigger date. See
|
||||
"HIGHLIGHTING TODAY" for an example
|
||||
|
||||
=item WEEK, MOON, SHARE, COLOR
|
||||
|
||||
The standard SPECIALs supported by all back-ends
|
||||
|
||||
=back
|
||||
|
||||
=head1 HIGHLIGHTING TODAY
|
||||
|
||||
Older versions of rem2html used to highlight today's date with a red outline.
|
||||
The current version does not do that by default. If you wish to highlight
|
||||
today's date, add the following reminder to your reminders file:
|
||||
|
||||
REM [realtoday()] SPECIAL HTMLCLASS rem-today
|
||||
|
||||
=head1 AUTHOR
|
||||
|
||||
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>
|
||||
=cut
|
||||
|
||||
sub usage
|
||||
@@ -97,19 +153,22 @@ sub usage
|
||||
$exit_status = 1;
|
||||
}
|
||||
print STDERR <<"EOM";
|
||||
$TIDY_PROGNAME: Produce an HTML calendar from the output of "remind -p"
|
||||
$TIDY_PROGNAME: Produce an HTML calendar from the output of "remind -pp"
|
||||
|
||||
Usage: remind -p ... | rem2html [options]
|
||||
Usage: remind -pp ... | rem2html [options]
|
||||
|
||||
Options:
|
||||
|
||||
--help, -h Print usage information
|
||||
--utf8 Assume UTF-8 input and write UTF-8 output
|
||||
--man Show man page (requires "perldoc")
|
||||
--version Print version
|
||||
--backurl url Make the title on the previous month's small calendar
|
||||
entry a link to <url>
|
||||
--forwurl url Same as --backurl, but for the next month's small calendar
|
||||
--imgbase url Base URL of images and default stylesheet file
|
||||
--pngs Use external .PNG images for moon phases rater than
|
||||
inline data: URLs
|
||||
--stylesheet url.css URL of CSS stylesheet. If specified, imgbase is NOT
|
||||
prepended to url.css
|
||||
--nostyle Produce basic HTML that does not use a CSS stylesheet
|
||||
@@ -121,11 +180,32 @@ EOM
|
||||
exit($exit_status);
|
||||
}
|
||||
|
||||
sub smoosh
|
||||
{
|
||||
my ($first, $second) = @_;
|
||||
return $second unless defined ($first);
|
||||
return $second if $first eq '';
|
||||
return $second if ($second =~ m|^/|); # Absolute path given for second
|
||||
|
||||
# Squash multiple slashes
|
||||
$first =~ s|/+|/|g;
|
||||
|
||||
# Special case
|
||||
return "/$second" if ($first eq '/');
|
||||
|
||||
# Delete trailing slash
|
||||
$first =~ s|/$||;
|
||||
|
||||
return "$first/$second";
|
||||
}
|
||||
|
||||
sub parse_options
|
||||
{
|
||||
local $SIG{__WARN__} = sub { print STDERR "$TIDY_PROGNAME: $_[0]\n"; };
|
||||
if (!GetOptions(\%Options, "help|h",
|
||||
"man",
|
||||
"utf8",
|
||||
"pngs",
|
||||
"version",
|
||||
"stylesheet=s",
|
||||
"nostyle",
|
||||
@@ -138,45 +218,49 @@ sub parse_options
|
||||
"tableonly")) {
|
||||
usage(1);
|
||||
}
|
||||
$Options{'title'} ||= 'HTML Calendar';
|
||||
$Options{title} ||= 'HTML Calendar';
|
||||
|
||||
# Fix up imgbase
|
||||
my $imgbase = '%IMAGEBASE%';
|
||||
if ($imgbase ne '%' . 'IMAGEBASE' . '%') {
|
||||
$Options{'imgbase'} ||= $imgbase;
|
||||
} else {
|
||||
$Options{'imgbase'} ||= '';
|
||||
my $stylesheet = $Options{stylesheet};
|
||||
if ($stylesheet) {
|
||||
$Options{stylesheet} = smoosh($Options{imgbase}, $stylesheet);
|
||||
}
|
||||
if ($Options{utf8}) {
|
||||
binmode(STDIN, ':encoding(UTF-8)');
|
||||
binmode(STDOUT, ':encoding(UTF-8)');
|
||||
}
|
||||
|
||||
$Options{'imgbase'} =~ s|/+$||;
|
||||
my $stylesheet = $Options{'imgbase'};
|
||||
$stylesheet .= '/' if ($stylesheet ne '');
|
||||
$stylesheet .= 'rem-default.css';
|
||||
$Options{'stylesheet'} ||= $stylesheet;
|
||||
}
|
||||
|
||||
sub start_output
|
||||
{
|
||||
return if ($Options{'tableonly'});
|
||||
return if ($Options{tableonly});
|
||||
|
||||
print("<html>\n<head>\n<title>" . $Options{'title'} . "</title>\n");
|
||||
if (!$Options{'nostyle'}) {
|
||||
if ($Options{'stylesheet'}) {
|
||||
print('<link rel="stylesheet" type="text/css" href="' .
|
||||
$Options{'stylesheet'} . '">' . "\n");
|
||||
}
|
||||
print("<html>\n<head>\n");
|
||||
if ($Options{utf8}) {
|
||||
print '<meta charset="UTF-8">' . "\n";
|
||||
}
|
||||
|
||||
print("<title>" . $Options{title} . "</title>\n");
|
||||
if (!$Options{nostyle}) {
|
||||
if ($Options{stylesheet}) {
|
||||
print('<link rel="stylesheet" type="text/css" href="' .
|
||||
$Options{stylesheet} . '">' . "\n");
|
||||
} else {
|
||||
print("<style>\n");
|
||||
print default_stylesheet();
|
||||
print("</style>\n");
|
||||
}
|
||||
}
|
||||
print("</head>\n<body>\n");
|
||||
if ($Options{'prologue'}) {
|
||||
print $Options{'prologue'} . "\n";
|
||||
if ($Options{prologue}) {
|
||||
print $Options{prologue} . "\n";
|
||||
}
|
||||
}
|
||||
|
||||
sub end_output
|
||||
{
|
||||
return if ($Options{'tableonly'});
|
||||
if ($Options{'epilogue'}) {
|
||||
print $Options{'epilogue'} . "\n";
|
||||
return if ($Options{tableonly});
|
||||
if ($Options{epilogue}) {
|
||||
print $Options{epilogue} . "\n";
|
||||
}
|
||||
print("</body>\n</html>\n");
|
||||
}
|
||||
@@ -202,27 +286,34 @@ sub parse_input
|
||||
chomp($line);
|
||||
($Month, $Year, $Numdays, $Firstwkday, $Mondayfirst) = split(' ', $line);
|
||||
|
||||
$Month =~ s/_/ /g;
|
||||
# Day names
|
||||
$line = <STDIN>;
|
||||
return 0 unless $line;
|
||||
chomp($line);
|
||||
@Daynames = split(' ', $line);
|
||||
|
||||
for (my $i=0; $i<7; $i++) {
|
||||
$Daynames[$i] =~ s/_/ /g;
|
||||
}
|
||||
|
||||
# Prevmon prevlen
|
||||
$line = <STDIN>;
|
||||
return 0 unless $line;
|
||||
chomp($line);
|
||||
($Prevmon, $Prevlen) = split(' ', $line);
|
||||
$Prevmon =~ s/_/ /g;
|
||||
|
||||
# Nextmon nextlen
|
||||
$line = <STDIN>;
|
||||
return 0 unless $line;
|
||||
chomp($line);
|
||||
($Nextmon, $Nextlen) = split(' ', $line);
|
||||
$Nextmon =~ s/_/ /g;
|
||||
|
||||
$found_data = 1;
|
||||
my $class;
|
||||
if ($Options{'nostyle'}) {
|
||||
if ($Options{nostyle}) {
|
||||
$class = '';
|
||||
} else {
|
||||
$class = ' class="rem-entry"';
|
||||
@@ -236,7 +327,12 @@ sub parse_input
|
||||
($y, $m, $d, $special, $tag, $duration, $time, $body) =
|
||||
($1, $2, $3, $4, $5, $6, $7, $8);
|
||||
} elsif (/\{/) {
|
||||
my $obj = JSON::Any->jsonToObj($_);
|
||||
my $obj;
|
||||
if ($Options{utf8}) {
|
||||
$obj = decode_json(encode('UTF-8', $_, Encode::FB_DEFAULT));
|
||||
} else {
|
||||
$obj = decode_json($_);
|
||||
}
|
||||
next unless ($obj->{date} =~ /^(\d+)-(\d+)-(\d+)$/);
|
||||
$y = $1;
|
||||
$m = $2;
|
||||
@@ -301,7 +397,7 @@ sub small_calendar
|
||||
}
|
||||
}
|
||||
|
||||
if ($Options{'nostyle'}) {
|
||||
if ($Options{nostyle}) {
|
||||
print "<td width=\"14%\">\n";
|
||||
print "<table border=\"0\">\n";
|
||||
print "<caption>";
|
||||
@@ -316,7 +412,7 @@ sub small_calendar
|
||||
print "</caption>\n";
|
||||
|
||||
my $class;
|
||||
if ($Options{'nostyle'}) {
|
||||
if ($Options{nostyle}) {
|
||||
print '<tr>';
|
||||
$class = ' align="right"';
|
||||
} else {
|
||||
@@ -338,7 +434,7 @@ sub small_calendar
|
||||
if ($col == 0) {
|
||||
print("<tr>\n");
|
||||
}
|
||||
if ($Options{'nostyle'}) {
|
||||
if ($Options{nostyle}) {
|
||||
print("<td align=\"right\" width=\"14%\"> </td>");
|
||||
} else {
|
||||
print("<td class=\"rem-sc-empty-cell\"> </td>");
|
||||
@@ -350,7 +446,7 @@ sub small_calendar
|
||||
print("<tr>\n");
|
||||
}
|
||||
$col++;
|
||||
if ($Options{'nostyle'}) {
|
||||
if ($Options{nostyle}) {
|
||||
print("<td align=\"right\" width=\"14%\">$day</td>");
|
||||
} else {
|
||||
print("<td class=\"rem-sc-cell\">$day</td>");
|
||||
@@ -362,7 +458,7 @@ sub small_calendar
|
||||
}
|
||||
if ($col) {
|
||||
while ($col < 7) {
|
||||
if ($Options{'nostyle'}) {
|
||||
if ($Options{nostyle}) {
|
||||
print("<td align=\"right\" width=\"14%\"> </td>");
|
||||
} else {
|
||||
print("<td class=\"rem-sc-empty-cell\"> </td>");
|
||||
@@ -389,9 +485,17 @@ sub output_calendar
|
||||
# Last column
|
||||
my $last_col = ($first_col + $Numdays - 1) % 7;
|
||||
|
||||
# Figure out how many rows
|
||||
my $number_of_rows = int(($first_col + $Numdays ) / 7 + 0.999);
|
||||
|
||||
# Add a row for small calendars if necessary
|
||||
if ($first_col == 0 && $last_col == 6) {
|
||||
$number_of_rows++;
|
||||
}
|
||||
|
||||
# Start the table
|
||||
my $class;
|
||||
if ($Options{'nostyle'}) {
|
||||
if ($Options{nostyle}) {
|
||||
print '<table width="100%" border="1" cellspacing=\"0\"><caption>' .
|
||||
$Month . ' ' . $Year . '</caption>' . "\n";
|
||||
print '<tr>';
|
||||
@@ -415,26 +519,26 @@ sub output_calendar
|
||||
|
||||
# Start the calendar rows
|
||||
my $col = 0;
|
||||
if ($Options{'nostyle'}) {
|
||||
if ($Options{nostyle}) {
|
||||
print "<tr>\n";
|
||||
} else {
|
||||
print "<tr class=\"rem-cal-row\">\n";
|
||||
print "<tr class=\"rem-cal-row rem-cal-row-$number_of_rows-rows\">\n";
|
||||
}
|
||||
if ($first_col > 0) {
|
||||
small_calendar($Prevmon, $Prevlen, $Options{'backurl'},
|
||||
small_calendar($Prevmon, $Prevlen, $Options{backurl},
|
||||
($Firstwkday - $Prevlen + 35) % 7);
|
||||
$col++;
|
||||
}
|
||||
|
||||
if ($last_col == 6 && $first_col > 0) {
|
||||
small_calendar($Nextmon, $Nextlen, $Options{'forwurl'},
|
||||
small_calendar($Nextmon, $Nextlen, $Options{forwurl},
|
||||
($Firstwkday + $Numdays) % 7);
|
||||
$col++;
|
||||
}
|
||||
if ($Options{'nostyle'}) {
|
||||
if ($Options{nostyle}) {
|
||||
$class = ' width="14%"';
|
||||
} else {
|
||||
$class = ' class="rem-empty"';
|
||||
$class = ' class="rem-empty rem-empty-$number_of_rows-rows"';
|
||||
}
|
||||
while ($col < $first_col) {
|
||||
print("<td$class> </td>\n");
|
||||
@@ -442,16 +546,16 @@ sub output_calendar
|
||||
}
|
||||
|
||||
for (my $day=1; $day<=$Numdays; $day++) {
|
||||
draw_day_cell($day);
|
||||
draw_day_cell($day, $number_of_rows);
|
||||
$col++;
|
||||
if ($col == 7) {
|
||||
$col = 0;
|
||||
print "</tr>\n";
|
||||
if ($day < $Numdays) {
|
||||
if ($Options{'nostyle'}) {
|
||||
if ($Options{nostyle}) {
|
||||
print "<tr>\n";
|
||||
} else {
|
||||
print "<tr class=\"rem-cal-row\">\n";
|
||||
print "<tr class=\"rem-cal-row rem-cal-row-$number_of_rows-rows\">\n";
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -461,13 +565,13 @@ sub output_calendar
|
||||
while ($col < 7) {
|
||||
if ($col == 5) {
|
||||
if ($first_col == 0) {
|
||||
small_calendar($Prevmon, $Prevlen, $Options{'backurl'},
|
||||
small_calendar($Prevmon, $Prevlen, $Options{backurl},
|
||||
($Firstwkday - $Prevlen + 35) % 7);
|
||||
} else {
|
||||
print("<td$class> </td>\n");
|
||||
}
|
||||
} elsif ($col == 6) {
|
||||
small_calendar($Nextmon, $Nextlen, $Options{'forwurl'},
|
||||
small_calendar($Nextmon, $Nextlen, $Options{forwurl},
|
||||
($Firstwkday + $Numdays) % 7);
|
||||
} else {
|
||||
print("<td$class> </td>\n");
|
||||
@@ -479,17 +583,17 @@ sub output_calendar
|
||||
|
||||
# Add a row for small calendars if they were not yet done!
|
||||
if ($first_col == 0 && $last_col == 6) {
|
||||
if ($Options{'nostyle'}) {
|
||||
if ($Options{nostyle}) {
|
||||
print "<tr>\n";
|
||||
} else {
|
||||
print "<tr class=\"rem-cal-row\">\n";
|
||||
print "<tr class=\"rem-cal-row rem-cal-row-$number_of_rows-rows\">\n";
|
||||
}
|
||||
small_calendar($Prevmon, $Prevlen, $Options{'backurl'},
|
||||
small_calendar($Prevmon, $Prevlen, $Options{backurl},
|
||||
($Firstwkday - $Prevlen + 35) % 7);
|
||||
for (my $i=0; $i<5; $i++) {
|
||||
print("<td$class> </td>\n");
|
||||
}
|
||||
small_calendar($Nextmon, $Nextlen, $Options{'forwurl'},
|
||||
small_calendar($Nextmon, $Nextlen, $Options{forwurl},
|
||||
($Firstwkday + $Numdays) % 7);
|
||||
print("</tr>\n");
|
||||
}
|
||||
@@ -499,17 +603,17 @@ sub output_calendar
|
||||
|
||||
sub draw_day_cell
|
||||
{
|
||||
my($day) = @_;
|
||||
my($day, $number_of_rows) = @_;
|
||||
my $shade = $shades->[$day];
|
||||
my $week = '';
|
||||
if (exists($weeks->{$day})) {
|
||||
$week = ' ' . $weeks->{$day};
|
||||
}
|
||||
my $class;
|
||||
if ($Options{'nostyle'}) {
|
||||
if ($Options{nostyle}) {
|
||||
$class = $classes->[$day] || '';
|
||||
} else {
|
||||
$class = $classes->[$day] || "rem-cell";
|
||||
$class = $classes->[$day] || "rem-cell rem-cell-$number_of_rows-rows";
|
||||
}
|
||||
if ($shade) {
|
||||
$shade = " style=\"background: $shade;\"";
|
||||
@@ -532,33 +636,46 @@ sub draw_day_cell
|
||||
my $alt;
|
||||
my $title;
|
||||
if ($phase == 0) {
|
||||
$img = 'newmoon.png';
|
||||
if ($Options{pngs}) {
|
||||
$img = smoosh($Options{imgbase}, 'newmoon.png');
|
||||
} else {
|
||||
$img = 'data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAABHNCSVQICAgIfAhkiAAAAAlwSFlzAAAGQAAABkABchkaRQAAABl0RVh0U29mdHdhcmUAd3d3Lmlua3NjYXBlLm9yZ5vuPBoAAAC6SURBVDiNpdNNbsIwFATgL0HKolchHKBX6yFaBOEyoPYUabvOIVKJRaCL2JX5TRNGGvnJ8ozGz89cYoElPvET+BX2yivn/1Bggw5HHMKa1h2qcPZC/JEIhvh+brIZIY6sorhMYo9hh3KGFzzfa84NZNjDt9OG/ZcH1BlaPE1IAG0+URhxzNGESKPFaHJs9Q0Ziww7HnvGeXSrJhis0jiFfjwnj3I0WRv+TKtr4hQl3lDrZ6QN9Wt654hfWfGDmBpUwDkAAAAASUVORK5CYII=';
|
||||
}
|
||||
$title = 'New Moon';
|
||||
$alt = 'new';
|
||||
} elsif ($phase == 1) {
|
||||
$img = 'firstquarter.png';
|
||||
if ($Options{pngs}) {
|
||||
$img = smoosh($Options{imgbase}, 'firstquarter.png');
|
||||
} else {
|
||||
$img = 'data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAABHNCSVQICAgIfAhkiAAAAAlwSFlzAAAGQAAABkABchkaRQAAABl0RVh0U29mdHdhcmUAd3d3Lmlua3NjYXBlLm9yZ5vuPBoAAADfSURBVDiNndM9TsNAFATgzy5yjZSAE85JBygETgENUPF3iBCitHAFQkcIhZ/Ryn9gRlrZmp2Z3ef3TBOHOMULPrDBMrhpi/4HI5xjix2+4nmJRbx/Yh7ahvkpRPVV4QDXwT3UQy46zGkAZDgK/iytefvHgCrkJsqZUH6cLnNbABSxd5Jhhf1IbkMXv8Qux7hH1Ic1xvk/jBWy6gavumvtwx7ectwZXkKh7MA95XgObeOtpI2U4zl0kGbpxgiPvwQUcXLrKFchc82f6Ur0PK49azOnmOI4TBu84zm4SV38DeIVYkrYJyNbAAAAAElFTkSuQmCC';
|
||||
}
|
||||
$title = 'First Quarter';
|
||||
$alt = '1st';
|
||||
} elsif ($phase == 2) {
|
||||
$img = 'fullmoon.png';
|
||||
if ($Options{pngs}) {
|
||||
$img = smoosh($Options{imgbase}, 'fullmoon.png');
|
||||
} else {
|
||||
$img = 'data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAABHNCSVQICAgIfAhkiAAAAAlwSFlzAAAGQAAABkABchkaRQAAABl0RVh0U29mdHdhcmUAd3d3Lmlua3NjYXBlLm9yZ5vuPBoAAADlSURBVDiNrdNBUsJAEAXQlyw4hq4hwWPqTixET6ELkZ16CcAq7oFLqXExjaYgQVNlV/Viev7/6XT/4TjGuME7PiLXUatb8N8xwB12SFjiIXIZtU/MAntEfgvQE4YtHxhiHpjXQ5H7uLhEcaLLAleBvd0Xx9Ha/BdyU+Q5OBV5OKmj7a4YBWdSyNPe4aKHAHkzqcQZNj3JgnNexqE8heyIAulffuFF3kTfIVbBVeu/xoXGGsn2TLJJ/mqkafNiINszySYZdbS90GHlvcgsWktY4TFy7ecxTdvIzahxHQLbyFXUqkPwF2ASRNYgB/PXAAAAAElFTkSuQmCC';
|
||||
}
|
||||
$alt = 'full';
|
||||
$title = 'Full Moon';
|
||||
} else {
|
||||
$img = 'lastquarter.png';
|
||||
if ($Options{pngs}) {
|
||||
$img = smoosh($Options{imgbase}, 'lastquarter.png');
|
||||
} else {
|
||||
$img = 'data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAABHNCSVQICAgIfAhkiAAAAAlwSFlzAAAGQAAABkABchkaRQAAABl0RVh0U29mdHdhcmUAd3d3Lmlua3NjYXBlLm9yZ5vuPBoAAADmSURBVDiNndMxTsNAEIXhzy5yCyQ6FAgcE7oQheQWUAAl5BIkREoZrgB0GFNkHBl7bURGsryaee/3jHeXdpxjghU+8InXyI0S+n0MMEeBEi+4jfV3vAvMQtsyL0J0j2GtViaeRRMyj8IlsgY8BSijE2Kur/hy09wHKMJrEolhwtwHKDHOsI4OLnoAXfl1jiNsOkR9keE4P8D4q4scbzg5xIxtjie709f1E7siC+9+Gx/8fxvPKtEsklcJSBdgWhcN8ByFR5z+AWgd5QpyE+OUWOJO+zJNU+Z6jHAdgHe7K73CuD5zFT9nCmRDIssCaAAAAABJRU5ErkJggg==';
|
||||
}
|
||||
$alt = 'last';
|
||||
$title = 'Last Quarter';
|
||||
}
|
||||
if ($Options{'imgbase'}) {
|
||||
$img = $Options{'imgbase'} . '/' . $img;
|
||||
}
|
||||
if ($Options{'nostyle'}) {
|
||||
if ($Options{nostyle}) {
|
||||
print("<div style=\"float: left\"><img border=\"0\" width=\"16\" height=\"16\" alt=\"$alt\" title=\"$title\" src=\"$img\">$msg</div>");
|
||||
} else {
|
||||
print("<div class=\"rem-moon\"><img width=\"16\" height=\"16\" alt=\"$alt\" title=\"$title\" src=\"$img\">$msg</div>");
|
||||
}
|
||||
}
|
||||
|
||||
if ($Options{'nostyle'}) {
|
||||
if ($Options{nostyle}) {
|
||||
print "<div style=\"float: right\">$day$week</div>\n";
|
||||
print "<p> </p>\n";
|
||||
} else {
|
||||
@@ -581,18 +698,18 @@ sub escape_html
|
||||
}
|
||||
|
||||
parse_options();
|
||||
if ($Options{'help'}) {
|
||||
if ($Options{help}) {
|
||||
usage(0);
|
||||
exit(0);
|
||||
} elsif ($Options{'man'}) {
|
||||
} elsif ($Options{man}) {
|
||||
system("perldoc $0");
|
||||
exit(0);
|
||||
} elsif ($Options{'version'}) {
|
||||
} elsif ($Options{version}) {
|
||||
print "rem2html version $rem2html_version.\n";
|
||||
exit(0);
|
||||
}
|
||||
|
||||
if (-t STDIN) {
|
||||
if (-t STDIN) { ## no critic
|
||||
print STDERR "$TIDY_PROGNAME: Input should not come from a terminal.\n\n";
|
||||
usage(1);
|
||||
}
|
||||
@@ -612,3 +729,81 @@ if ($found_something) {
|
||||
exit(1);
|
||||
}
|
||||
|
||||
sub default_stylesheet
|
||||
{
|
||||
return <<'EOF';
|
||||
table.rem-cal {
|
||||
font-family: helvetica, arial, sans-serif;
|
||||
font-size: 12pt;
|
||||
}
|
||||
|
||||
table.rem-sc-table {
|
||||
font-family: helvetica, arial, sans-serif;
|
||||
font-size: 10pt;
|
||||
width: 95%;
|
||||
float: left;
|
||||
}
|
||||
|
||||
caption.rem-cal-caption {
|
||||
font-size: 14pt;
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
th.rem-cal-hdr {
|
||||
width: 14%;
|
||||
border-style: solid;
|
||||
border-width: 1px;
|
||||
vertical-align: top;
|
||||
}
|
||||
td.rem-empty, td.rem-cell, td.rem-small-calendar {
|
||||
width: 14%;
|
||||
height: 7em;
|
||||
border-style: solid;
|
||||
border-width: 1px;
|
||||
vertical-align: top;
|
||||
}
|
||||
td.rem-today {
|
||||
width: 14%;
|
||||
height: 7em;
|
||||
border-style: solid;
|
||||
border-width: 2px;
|
||||
border-color: #EE3333;
|
||||
vertical-align: top;
|
||||
}
|
||||
|
||||
table.rem-cal {
|
||||
width: 100%;
|
||||
border-collapse: collapse;
|
||||
}
|
||||
|
||||
div.rem-daynumber {
|
||||
float: right;
|
||||
text-align: right;
|
||||
vertical-align: top;
|
||||
font-size: 14pt;
|
||||
}
|
||||
|
||||
p.rem-entry {
|
||||
clear: both;
|
||||
}
|
||||
|
||||
div.rem-moon {
|
||||
float: left;
|
||||
text-align: left;
|
||||
vertical-align: top;
|
||||
}
|
||||
|
||||
th.rem-sc-hdr {
|
||||
text-align: right;
|
||||
}
|
||||
|
||||
td.rem-sc-empty-cell, td.rem-sc-cell {
|
||||
text-align: right;
|
||||
width: 14%;
|
||||
}
|
||||
|
||||
caption.rem-sc-caption {
|
||||
font-size: 12pt;
|
||||
}
|
||||
EOF
|
||||
}
|
||||
23
rem2pdf/Makefile.PL.in
Normal file
23
rem2pdf/Makefile.PL.in
Normal file
@@ -0,0 +1,23 @@
|
||||
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>},
|
||||
VERSION => '@VERSION@',
|
||||
PREREQ_PM => {
|
||||
'Getopt::Long' => 0,
|
||||
'Cairo' => 0,
|
||||
'Pango' => 0,
|
||||
},
|
||||
EXE_FILES => [ 'bin/rem2pdf' ]
|
||||
);
|
||||
48
rem2pdf/Makefile.top.in
Normal file
48
rem2pdf/Makefile.top.in
Normal file
@@ -0,0 +1,48 @@
|
||||
# Set by configure - don't touch.
|
||||
srcdir=@srcdir@
|
||||
prefix=@prefix@
|
||||
exec_prefix=@exec_prefix@
|
||||
mandir=@mandir@
|
||||
bindir=@bindir@
|
||||
datadir=@datadir@
|
||||
datarootdir=@datarootdir@
|
||||
PERL=@PERL@
|
||||
PERLMODS_NEEDED=Getopt::Long Cairo Pango
|
||||
|
||||
all: Makefile
|
||||
@if test "$(PERL)" = "" ; then \
|
||||
echo "Not building rem2pdf; Perl is required"; exit 0; fi; \
|
||||
for m in $(PERLMODS_NEEDED) ; \
|
||||
do \
|
||||
$(PERL) -M$$m -e 1 > /dev/null 2>&1; \
|
||||
if test $$? != 0 ; then echo "Not building rem2pdf; missing $$m"; exit 0; fi; \
|
||||
done; \
|
||||
$(MAKE) all && exit 0; \
|
||||
exit 1;
|
||||
|
||||
install:
|
||||
@if test "$(PERL)" = "" ; then \
|
||||
echo "Not installing rem2pdf; Perl is required"; exit 0; fi; \
|
||||
for m in $(PERLMODS_NEEDED) ; \
|
||||
do \
|
||||
$(PERL) -M$$m -e 1 > /dev/null 2>&1; \
|
||||
if test $$? != 0 ; then echo "Not installing rem2pdf; missing $$m"; exit 0; fi; \
|
||||
done; \
|
||||
echo "Installing rem2pdf"; \
|
||||
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; \
|
||||
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
|
||||
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
|
||||
22
rem2pdf/README
Normal file
22
rem2pdf/README
Normal file
@@ -0,0 +1,22 @@
|
||||
rem2pdf is a Perl program that takes the output of "remind -p" and
|
||||
produces a PDF calendar. See "man rem2pdf" for details.
|
||||
|
||||
rem2pdf has the following Perl modules as prerequisites:
|
||||
|
||||
Pango - https://metacpan.org/pod/Pango
|
||||
Cairo - https://metacpan.org/pod/Cairo
|
||||
|
||||
On Debian or Debian-derived systems, these can be installed with:
|
||||
|
||||
apt install libpango-perl libcairo-perl
|
||||
|
||||
On Red Hat or Red Hat-derived systems, you need to install the perl-Pango
|
||||
and perl-Cairo RPMs, which may require adding other repos to your list of
|
||||
RPM sources.
|
||||
|
||||
rem2pdf is built and installed in the usual Perl program way:
|
||||
|
||||
perl Makefile.PL && make && sudo make install
|
||||
|
||||
--
|
||||
Dianne Skoll - <dianne@skoll.ca>
|
||||
526
rem2pdf/bin/rem2pdf.in
Normal file
526
rem2pdf/bin/rem2pdf.in
Normal file
@@ -0,0 +1,526 @@
|
||||
#!@PERL@
|
||||
# SPDX-License-Identifier: GPL-2.0-only
|
||||
use strict;
|
||||
use warnings;
|
||||
use lib '@prefix@/lib/perl5';
|
||||
|
||||
use Encode;
|
||||
use Cairo;
|
||||
use Pango;
|
||||
use Getopt::Long;
|
||||
|
||||
my $VERSION = '@VERSION@';
|
||||
|
||||
use Remind::PDF;
|
||||
|
||||
my $media_to_size = {
|
||||
"Letter" => [ 612, 792],
|
||||
"Tabloid" => [ 792, 1224],
|
||||
"Ledger" => [1224, 792],
|
||||
"Legal" => [ 612, 1008],
|
||||
"Statement" => [ 396, 612],
|
||||
"Executive" => [ 540, 720],
|
||||
"A3" => [ 842, 1190],
|
||||
"A4" => [ 595, 842],
|
||||
"A5" => [ 420, 595],
|
||||
"B4" => [ 729, 1032],
|
||||
"B5" => [ 519, 729],
|
||||
"Folio" => [ 612, 936],
|
||||
"Quarto" => [ 612, 780],
|
||||
"10x14" => [ 720, 1008],
|
||||
};
|
||||
|
||||
my $help = 0;
|
||||
|
||||
my $settings = {
|
||||
landscape => 0,
|
||||
numbers_on_left => 0,
|
||||
small_calendars => 0,
|
||||
fill_entire_page => 0,
|
||||
wrap_calendar => 0,
|
||||
media => 'Letter',
|
||||
width => 0,
|
||||
height => 0,
|
||||
|
||||
title_font => 'Sans',
|
||||
header_font => 'Sans',
|
||||
daynum_font => 'Sans Bold Oblique',
|
||||
entry_font => 'Sans',
|
||||
small_cal_font => 'Sans',
|
||||
|
||||
title_size => 14,
|
||||
header_size => 12,
|
||||
daynum_size => 14,
|
||||
entry_size => 8,
|
||||
|
||||
border_size => 4,
|
||||
line_thickness => 1,
|
||||
|
||||
margin_top => 36,
|
||||
margin_bottom => 36,
|
||||
margin_left => 36,
|
||||
margin_right => 36,
|
||||
|
||||
verbose => 0,
|
||||
};
|
||||
|
||||
my $me = $0;
|
||||
$me =~ s/^.*\///;
|
||||
|
||||
set_default_media();
|
||||
|
||||
sub usage
|
||||
{
|
||||
print <<"EOF";
|
||||
$me (version $VERSION): Convert Remind -pp output to a PDF calendar.
|
||||
|
||||
Usage: remind -pp [options] filename | $me [options] > out.pdf
|
||||
|
||||
Options:
|
||||
|
||||
--landscape, -l Print in landscape orientation
|
||||
--small-calendars=N Choose location for small calendars
|
||||
-cN Synonym for --small-calendars=N
|
||||
--left-numbers, -x Print day numbers on the left
|
||||
--fill-page, -e Fill the entire page
|
||||
--media=MEDIA, -mMEDIA Size for specified media
|
||||
--width=W, -wW Specify media width in 1/72nds of an inch
|
||||
--height=H, -hH Specify media height in 1/72nds of an inch
|
||||
--wrap, -y Make calendar fit in at most 5 rows
|
||||
--title-font=FONT Specify font for calendar title
|
||||
--header-font=FONT Specify font for weekday names
|
||||
--daynum-font=FONT Specify font for day numbers
|
||||
--entry-font=FONT Specify font for calendar entries
|
||||
--small-cal-font=FONT Specify font for small calendars
|
||||
--title-size=S Specify size of font for calendar title in points
|
||||
--header-size=S Specify size of font for weekday names
|
||||
--daynum-size=S Specify size of font for day numbers
|
||||
--entry-size=S Specify size of font for calendar entries
|
||||
--border-size=S Specify size of gaps between items in 1/72nds of an inch
|
||||
--line-thickness=S Specify line thickness in 1/72nds of an inch
|
||||
--margin-top=S Specify top margin size in 1/72nds of an inch
|
||||
--margin-bottom=S Specify bottom margin size in 1/72nds of an inch
|
||||
--margin-left=S Specify left margin size in 1/72nds of an inch
|
||||
--margin-right=S Specify right margin size in 1/72nds of an inch
|
||||
--verbose, -v Print progress messages
|
||||
--help Display this help
|
||||
EOF
|
||||
}
|
||||
|
||||
Getopt::Long::Configure('bundling_values');
|
||||
|
||||
my $ret = GetOptions('landscape|l' => \$settings->{landscape},
|
||||
'small-calendars|c=i' => \$settings->{small_calendars},
|
||||
'left-numbers|x' => \$settings->{numbers_on_left},
|
||||
'fill-page|e' => \$settings->{fill_entire_page},
|
||||
'media|m=s' => \$settings->{media},
|
||||
'width|w=i' => \$settings->{width},
|
||||
'wrap|y' => \$settings->{wrap_calendar},
|
||||
'height|h=i' => \$settings->{height},
|
||||
'title-font=s' => \$settings->{title_font},
|
||||
'header-font=s' => \$settings->{header_font},
|
||||
'daynum-font=s' => \$settings->{daynum_font},
|
||||
'entry-font=s' => \$settings->{entry_font},
|
||||
'small-cal-font=s' => \$settings->{small_cal_font},
|
||||
'title-size=f' => \$settings->{title_size},
|
||||
'header-size=f' => \$settings->{header_size},
|
||||
'daynum-size=f' => \$settings->{daynum_size},
|
||||
'entry-size=f' => \$settings->{entry_size},
|
||||
'border-size=f' => \$settings->{border_size},
|
||||
'line-thickness=f' => \$settings->{line_thickness},
|
||||
'margin-top=f' => \$settings->{margin_top},
|
||||
'margin-bottom=f' => \$settings->{margin_bottom},
|
||||
'margin-left=f' => \$settings->{margin_left},
|
||||
'margin-right=f' => \$settings->{margin_right},
|
||||
'verbose|v' => \$settings->{verbose},
|
||||
'help' => \$help
|
||||
);
|
||||
if (!$ret) {
|
||||
usage();
|
||||
exit(1);
|
||||
}
|
||||
|
||||
if ($help) {
|
||||
usage();
|
||||
exit(0);
|
||||
}
|
||||
|
||||
if ($settings->{width} <= 0 ||
|
||||
$settings->{height} <= 0) {
|
||||
my $size = $media_to_size->{ucfirst($settings->{media})};
|
||||
if (!$size) {
|
||||
if (lc($settings->{media}) ne 'help') {
|
||||
print STDERR "Unknown media " . $settings->{media} . "\n";
|
||||
}
|
||||
set_default_media();
|
||||
printf("%-12s Size in 1/72 in\n", "Valid media:");
|
||||
foreach my $m (sort { $a cmp $b } (keys(%$media_to_size))) {
|
||||
if ($m eq $settings->{media}) {
|
||||
print "* ";
|
||||
} else {
|
||||
print " ";
|
||||
}
|
||||
printf("%-12s %4d x %4d\n", $m,
|
||||
$media_to_size->{$m}->[0],
|
||||
$media_to_size->{$m}->[1]);
|
||||
}
|
||||
exit(1);
|
||||
}
|
||||
$settings->{width} = $size->[0];
|
||||
$settings->{height} = $size->[1];
|
||||
}
|
||||
|
||||
if ($settings->{landscape}) {
|
||||
my $tmp = $settings->{width};
|
||||
$settings->{width} = $settings->{height};
|
||||
$settings->{height} = $tmp;
|
||||
}
|
||||
|
||||
# Don't read from a terminal
|
||||
if (-t STDIN) { ## no critic
|
||||
print STDERR "I can't read data from a terminal. Please run like this:\n";
|
||||
print STDERR " remind -pp [options] filename | $me [options] > out.pdf\n";
|
||||
exit(1);
|
||||
}
|
||||
|
||||
my $done_one = 0;
|
||||
|
||||
my $errored_out = 0;
|
||||
|
||||
my $surface = Cairo::PdfSurface->create_for_stream(sub { print $_[1] unless $errored_out; }, undef,
|
||||
$settings->{width}, $settings->{height});
|
||||
|
||||
# set_metadata not available in older versions of Cairo
|
||||
eval { $surface->set_metadata('title', 'Calendar'); };
|
||||
eval { $surface->set_metadata('author', 'Remind (https://dianne.skoll.ca/projects/remind/)'); };
|
||||
eval { $surface->set_metadata('creator', 'rem2pdf (https://dianne.skoll.ca/projects/remind/)'); };
|
||||
eval { $surface->set_metadata('subject', 'Calendar'); };
|
||||
|
||||
my $cr = Cairo::Context->create($surface);
|
||||
$cr->set_line_width($settings->{line_thickness});
|
||||
|
||||
while(1) {
|
||||
my ($obj, $err) = Remind::PDF->create_from_stream(*STDIN,
|
||||
{color => 1,
|
||||
shade => 1,
|
||||
moon => 1,
|
||||
pango => 1,
|
||||
week => 1,});
|
||||
|
||||
if (!$obj) {
|
||||
if (!$done_one) {
|
||||
$errored_out = 1;
|
||||
print STDERR "$me: $err\n";
|
||||
exit(1);
|
||||
}
|
||||
last;
|
||||
}
|
||||
$done_one = 1;
|
||||
$obj->render($cr, $settings);
|
||||
}
|
||||
|
||||
$surface->finish();
|
||||
|
||||
sub set_default_media
|
||||
{
|
||||
my $paper;
|
||||
$paper = $ENV{PAPERSIZE};
|
||||
if ($paper && set_media(ucfirst($paper))) {
|
||||
return 1;
|
||||
}
|
||||
if ($ENV{PAPERCONF}) {
|
||||
if (set_media_from_file($ENV{PAPERCONF})) {
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
if (set_media_from_file('/etc/papersize')) {
|
||||
return 1;
|
||||
}
|
||||
return set_media('Letter');
|
||||
}
|
||||
|
||||
sub set_media
|
||||
{
|
||||
my ($m) = @_;
|
||||
|
||||
return 0 unless $media_to_size->{$m};
|
||||
$settings->{media} = $m;
|
||||
return 1;
|
||||
}
|
||||
|
||||
sub set_media_from_file
|
||||
{
|
||||
my ($fn) = @_;
|
||||
my $IN;
|
||||
if (!open($IN, '<', $fn)) {
|
||||
return 0;
|
||||
}
|
||||
while(<$IN>) {
|
||||
chomp;
|
||||
s/^\s+//;
|
||||
s/\s+$//;
|
||||
next if ($_ eq '');
|
||||
next if ($_ =~ /^#/);
|
||||
my $m = $_;
|
||||
close($IN);
|
||||
return set_media($m);
|
||||
}
|
||||
close($IN);
|
||||
return 0;
|
||||
}
|
||||
|
||||
__END__
|
||||
|
||||
=head1 NAME
|
||||
|
||||
rem2pdf - draw a PDF calendar from Remind output
|
||||
|
||||
=head1 SYNOPSIS
|
||||
|
||||
remind -pp [options] file | rem2pdf [options] > output.pdf
|
||||
|
||||
=head1 DESCRIPTION
|
||||
|
||||
B<rem2pdf> reads the standard input, which should be the results of
|
||||
running B<remind> with the B<-p>, B<-pp> or B<-ppp> options. It emits
|
||||
PDF code that draws a calendar to standard output.
|
||||
|
||||
B<rem2pdf> uses the Pango text formatting library (L<https://pango.gnome.org/>)
|
||||
and the Cairo graphics library (L<https://www.cairographics.org/>) to produce
|
||||
its output. The CPAN modules Pango (L<https://metacpan.org/pod/Pango>)
|
||||
and Cairo (L<https://metacpan.org/pod/Cairo>) are prerequisites.
|
||||
|
||||
B<rem2pdf> assumes that its input stream is valid UTF-8. If this is not
|
||||
the case, it may render output incorrectly or even fail to render
|
||||
output at all.
|
||||
|
||||
=head1 OPTIONS
|
||||
|
||||
=over
|
||||
|
||||
=item --landscape, -l
|
||||
|
||||
Print the calendar in landscape orientation. Essentially, this swaps
|
||||
the width and height of the output media.
|
||||
|
||||
=item --small-calendars=I<n>, -cI<n>
|
||||
|
||||
Control the inclusion of small calendars for the previous and next
|
||||
month. Possible values for I<n> are:
|
||||
|
||||
=over
|
||||
|
||||
=item Z<>0
|
||||
|
||||
Do not draw any small calendares
|
||||
|
||||
=item Z<>1
|
||||
|
||||
Place the small calendars at the bottom-right if there is room;
|
||||
otherwise, place them at the top-left.
|
||||
|
||||
=item Z<>2
|
||||
|
||||
Place the small calendars at the top-left if there is room; otherwise,
|
||||
place them at the bottom-right.
|
||||
|
||||
=item Z<>3
|
||||
|
||||
Place the previous month's small calendar at the top-left and the next
|
||||
month's at the bottom-right if there is room; otherwise, follow
|
||||
I<n>=1. A moment's thought reveals that an option which splits the
|
||||
calendars if there is room and otherwise follows I<n>=2 yields the
|
||||
same results.
|
||||
|
||||
=back
|
||||
|
||||
=item --left-numbers, -x
|
||||
|
||||
Draw the day numbers in the top-left corner of each day's box rather than
|
||||
the default top-right.
|
||||
|
||||
=item --fill-page, -e
|
||||
|
||||
Make the calendar fill the available space on the page.
|
||||
|
||||
=item --media=I<media>, -mI<media>
|
||||
|
||||
Specify the paper size (Letter, A4, etc.) For a list of valid media sizes,
|
||||
run:
|
||||
|
||||
rem2pdf --media=help
|
||||
|
||||
The default media size will be marked with an asterisk.
|
||||
|
||||
=item --width=I<n>, -wI<n>, --height=I<m>, -hI<m>
|
||||
|
||||
Rather than specifying a named media size, directly specify the width
|
||||
and height of the output in 1/72ths of an inch. You must specify both
|
||||
width and height for the options to be respected.
|
||||
|
||||
=item --title-font=I<font>
|
||||
|
||||
Specify the font used for the calendar title. It can be any font that
|
||||
the Pango library on your system can use. The default is Sans. If
|
||||
you choose a font with spaces in its name, you may need to quote this
|
||||
argument.
|
||||
|
||||
=item --header-font=I<font>
|
||||
|
||||
Specify the font used for the weekday names. The default is Sans.
|
||||
|
||||
=item --daynum-font=I<font>
|
||||
|
||||
Specify the font used for the day numbers. The default is
|
||||
Sans Bold Oblique.
|
||||
|
||||
=item --entry-font=I<font>
|
||||
|
||||
Specify the font used for calendar entries. The default is Sans.
|
||||
|
||||
=item --small-cal-font=I<font>
|
||||
|
||||
Specify the font used for the small next- and previous-month
|
||||
calendars. The default is Sans.
|
||||
|
||||
=item --title-size=I<n>
|
||||
|
||||
Specify the size of the title font in 1/72ths of an inch. The default
|
||||
is 14. This size, and indeed all following sizes, may be specified as
|
||||
floating-point numbers.
|
||||
|
||||
=item --header-size=I<n>
|
||||
|
||||
Specify the size of the header font in 1/72ths of an inch. The default is 14.
|
||||
|
||||
=item --daynum-size=I<n>
|
||||
|
||||
Specify the size of the day number font in 1/72ths of an inch. The
|
||||
default is 14.
|
||||
|
||||
=item --entry-size=I<n>
|
||||
|
||||
Specify the size of the calendar entry font in 1/72ths of an inch.
|
||||
The default is 8.
|
||||
|
||||
=item --border-size=I<n>
|
||||
|
||||
Specify the size of the blank border between the contents of a calendar
|
||||
box and the centre of the lines surrounding it, in 1/72ths of an inch.
|
||||
The default is 4.
|
||||
|
||||
=item --line-thickness=I<n>
|
||||
|
||||
Specify the thickness of the lines drawn on the calendar. The default is 1.
|
||||
|
||||
=item --margin-top=I<n>
|
||||
|
||||
The size of the margin at the top of the page in 1/72ths of an inch.
|
||||
The default is 36.
|
||||
|
||||
=item --margin-bottom=I<n>
|
||||
|
||||
The size of the margin at the bottom of the page in 1/72ths of an inch.
|
||||
The default is 36.
|
||||
|
||||
=item --margin-left=I<n>
|
||||
|
||||
The size of the margin at the left of the page in 1/72ths of an inch.
|
||||
The default is 36.
|
||||
|
||||
=item --margin-right=I<n>
|
||||
|
||||
The size of the margin at the right of the page in 1/72ths of an inch.
|
||||
The default is 36.
|
||||
|
||||
=item --wrap, -y
|
||||
|
||||
Modify the calendar so that if it would normally require 6 rows to print,
|
||||
then the last day (or last two days, as needed) are moved to the
|
||||
first row of the calendar, and adjust the small calendar positions
|
||||
as needed. This results in a calendar that only requires 5 rows, but
|
||||
with the last day or two appearing in the I<first> row.
|
||||
|
||||
=item --verbose, -v
|
||||
|
||||
Print (on STDERR) the name of the month and year for each month that
|
||||
is rendered.
|
||||
|
||||
=back
|
||||
|
||||
=head1 USAGE
|
||||
|
||||
To use B<rem2df>, pipe the output of B<remind> with one of the
|
||||
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 -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 /dev/null Jan 2023 ; \
|
||||
remind -pp /dev/null June 2023) | rem2pdf -e -l -c3 > cal.pdf
|
||||
|
||||
=head1 FORMATTED TEXT
|
||||
|
||||
B<rem2pdf> supports a B<SPECIAL> reminder type called B<PANGO>. This
|
||||
lets you format text using the Pango markup language, described at
|
||||
L<https://docs.gtk.org/Pango/pango_markup.html>. Here are some
|
||||
examples:
|
||||
|
||||
REM Mon SPECIAL PANGO <b>Bold</b> and <i>italic</i>
|
||||
REM Tue SPECIAL PANGO <span face="zapf chancery">Fancy</span>
|
||||
REM Wed SPECIAL PANGO <span foreground="red"><b>Bold red</b></span>
|
||||
|
||||
Other back-ends such as B<rem2ps> and B<rem2html> will ignore PANGO
|
||||
special reminders.
|
||||
|
||||
Neither B<remind> nor B<rem2pdf> will check the markup to ensure
|
||||
it is syntactically correct. If you use invalid Pango markup, the
|
||||
Pango library will print a warning and B<rem2pdf> will not render any
|
||||
output for the invalid reminder.
|
||||
|
||||
=head1 ABSOLUTELY-POSITIONED TEXT
|
||||
|
||||
If your B<PANGO> special reminder starts with C<@I<x>,I<y>> where I<x>
|
||||
and I<y> are floating-point numbers, then the Pango marked-up test is
|
||||
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 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 calendar box.
|
||||
|
||||
A positive I<y> value positions the top edge of the text I<y> points
|
||||
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 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
|
||||
prevent this.
|
||||
|
||||
As an example, this places Sunrise and Sunset times at the bottom left
|
||||
of each calendar box:
|
||||
|
||||
REM SPECIAL PANGO @1,-1 <span size="4800"><i>Rise [sunrise($U)] Set [sunset($U)]</i></span>
|
||||
|
||||
(Note that Pango expresses font sizes in 1024's of a point, so a size of
|
||||
4800 works out to about 4.6 points.)
|
||||
|
||||
=head1 AUTHOR
|
||||
|
||||
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>
|
||||
|
||||
1017
rem2pdf/lib/Remind/PDF.pm
Normal file
1017
rem2pdf/lib/Remind/PDF.pm
Normal file
File diff suppressed because it is too large
Load Diff
318
rem2pdf/lib/Remind/PDF/Entry.pm
Normal file
318
rem2pdf/lib/Remind/PDF/Entry.pm
Normal file
@@ -0,0 +1,318 @@
|
||||
package Remind::PDF::Entry;
|
||||
# SPDX-License-Identifier: GPL-2.0-only
|
||||
use strict;
|
||||
use warnings;
|
||||
|
||||
use Cairo;
|
||||
use Pango;
|
||||
use Encode;
|
||||
|
||||
=head1 NAME
|
||||
|
||||
Remind::PDF::Entry - Representation of one calendar entry
|
||||
|
||||
=head1 DESCRIPTION
|
||||
|
||||
C<Remind::PDF::Entry> and its subclasses represent one calendar
|
||||
entry. They can be normal reminder-type entries or SPECIAL reminders.
|
||||
|
||||
=head1 CLASS METHODS
|
||||
|
||||
=head2 Remind::PDF::Entry->new_from_hash($hash)
|
||||
|
||||
Create and return a new C<Remind::PDF::Entry> based on one reminder's
|
||||
worth of data from C<remind -p>. Returns a C<Remind::PDF::Entry> object,
|
||||
or in the case of SPECIAL reminders, a subclass of C<Remind::PDF::Entry>.
|
||||
|
||||
=cut
|
||||
sub new_from_hash
|
||||
{
|
||||
my ($class, $hash) = @_;
|
||||
if (exists($hash->{passthru})) {
|
||||
my $special = lc($hash->{passthru});
|
||||
if ($special =~ /^(html|htmlclass|week|moon|shade|color|colour|postscript|psfile|pango)$/) {
|
||||
$special = 'color' if $special eq 'colour';
|
||||
$class = 'Remind::PDF::Entry::' . $special;
|
||||
} else {
|
||||
$class = 'Remind::PDF::Entry::UNKNOWN';
|
||||
}
|
||||
}
|
||||
bless $hash, $class;
|
||||
$hash->_adjust();
|
||||
return $hash;
|
||||
}
|
||||
|
||||
# Base class: Set the color to black
|
||||
sub _adjust
|
||||
{
|
||||
my ($self) = @_;
|
||||
$self->{r} = 0;
|
||||
$self->{g} = 0;
|
||||
$self->{b} = 0;
|
||||
}
|
||||
|
||||
=head1 INSTANCE METHODS
|
||||
|
||||
=head2 render($pdf, $cr, $settings, $so_far, $day, $col, $height)
|
||||
|
||||
Render a single entry. C<$pdf> is the parent C<Remind::PDF>
|
||||
object. C<$cr> is a Cairo drawing context and C<$settings> is the
|
||||
usual settings hash. C<$so_far> is the Y-coordinate at which
|
||||
to start drawing. C<$day> is the month day and C<$col> is
|
||||
the calendar column. C<$height> is the height of the calendar
|
||||
box.
|
||||
|
||||
If C<$height> is zero, then nothing should actually be drawn,
|
||||
but the height of the calendar entry should be computed.
|
||||
|
||||
Returns the height of the calendar entry.
|
||||
|
||||
=cut
|
||||
sub render
|
||||
{
|
||||
my ($self, $pdf, $cr, $settings, $so_far, $day, $col, $height) = @_;
|
||||
|
||||
my ($x1, $y1, $x2, $y2) = $pdf->col_box_coordinates($so_far, $col, $height, $settings);
|
||||
my $layout = Pango::Cairo::create_layout($cr);
|
||||
|
||||
$layout->set_width(1024 * ($x2 - $x1 - 2 * $settings->{border_size}));
|
||||
$layout->set_wrap('word-char');
|
||||
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();
|
||||
|
||||
if ($height) {
|
||||
$cr->save();
|
||||
$cr->set_source_rgb($self->{r} / 255,
|
||||
$self->{g} / 255,
|
||||
$self->{b} / 255);
|
||||
$cr->move_to($x1 + $settings->{border_size}, $so_far);
|
||||
Pango::Cairo::show_layout($cr, $layout);
|
||||
$cr->restore();
|
||||
}
|
||||
return $h;
|
||||
}
|
||||
|
||||
package Remind::PDF::Entry::html;
|
||||
use base 'Remind::PDF::Entry';
|
||||
sub render {}
|
||||
|
||||
package Remind::PDF::Entry::htmlclass;
|
||||
use base 'Remind::PDF::Entry';
|
||||
sub render {}
|
||||
|
||||
package Remind::PDF::Entry::week;
|
||||
use base 'Remind::PDF::Entry';
|
||||
|
||||
sub render
|
||||
{
|
||||
my ($self, $pdf, $cr, $settings, $so_far, $day, $col, $height) = @_;
|
||||
# Do nothing in pre-render mode
|
||||
return 0 unless $height;
|
||||
|
||||
# Render in small text at bottom-right
|
||||
my ($x1, $y1, $x2, $y2) = $pdf->col_box_coordinates($so_far, $col, $height, $settings);
|
||||
my $layout = Pango::Cairo::create_layout($cr);
|
||||
|
||||
$layout->set_text(Encode::decode('UTF-8', $self->{body}));
|
||||
my $desc = Pango::FontDescription->from_string($settings->{entry_font} . ' ' . int(0.75 * $settings->{entry_size}) . 'px');
|
||||
$layout->set_font_description($desc);
|
||||
my ($wid, $h) = $layout->get_pixel_size();
|
||||
|
||||
$cr->save();
|
||||
$cr->move_to($x2 - $settings->{border_size}/4 - $wid, $y2 - $settings->{border_size}/4 - $h);
|
||||
Pango::Cairo::show_layout($cr, $layout);
|
||||
$cr->restore();
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
package Remind::PDF::Entry::moon;
|
||||
use base 'Remind::PDF::Entry';
|
||||
|
||||
sub _adjust {
|
||||
my ($self) = @_;
|
||||
my ($phase, $size, $fontsize, $msg) = split(/\s+/, $self->{body}, 4);
|
||||
$phase = '' unless defined($phase);
|
||||
$size = -1 unless defined($size);
|
||||
$fontsize = -1 unless defined($fontsize);
|
||||
$msg = '' unless defined($msg);
|
||||
$self->{phase} = $phase;
|
||||
$self->{size} = $size;
|
||||
$self->{fontsize} = $fontsize;
|
||||
$self->{body} = $msg;
|
||||
}
|
||||
sub render
|
||||
{
|
||||
my ($self, $pdf, $cr, $settings, $so_far, $day, $col, $height) = @_;
|
||||
|
||||
# Do nothing in pre-render mode
|
||||
return 0 unless $height;
|
||||
|
||||
my ($x1, $y1, $x2, $y2) = $pdf->col_box_coordinates($so_far, $col, $height, $settings);
|
||||
|
||||
my $layout;
|
||||
my $bodywidth = 0;
|
||||
if ($self->{fontsize} <= 0) {
|
||||
$self->{fontsize} = $settings->{entry_size};
|
||||
}
|
||||
if ($self->{size} <= 0) {
|
||||
$self->{size} = $settings->{daynum_size};
|
||||
}
|
||||
|
||||
if ($self->{phase} !~ /^[0123]$/) {
|
||||
# Invalid phase
|
||||
return 0;
|
||||
}
|
||||
|
||||
if ($self->{body} ne '') {
|
||||
$layout = Pango::Cairo::create_layout($cr);
|
||||
$layout->set_text(Encode::decode('UTF-8', $self->{body}));
|
||||
my $desc = Pango::FontDescription->from_string($settings->{entry_font} . ' ' . $self->{fontsize} . 'px');
|
||||
$layout->set_font_description($desc);
|
||||
($bodywidth, undef) = $layout->get_pixel_size();
|
||||
}
|
||||
my ($xc, $yc);
|
||||
if ($settings->{numbers_on_left}) {
|
||||
$yc = $so_far + $settings->{border_size} + ($self->{size} / 2);
|
||||
$xc = $x2 - $settings->{border_size} - ($self->{size} / 2);
|
||||
if ($bodywidth) {
|
||||
$xc -= ($bodywidth + $settings->{border_size});
|
||||
}
|
||||
} else {
|
||||
$xc = $x1 + $settings->{border_size} + ($self->{size} / 2);
|
||||
$yc = $so_far + $settings->{border_size} + ($self->{size} / 2);
|
||||
}
|
||||
$self->draw_moon($xc, $yc, $cr);
|
||||
if ($layout) {
|
||||
$cr->save();
|
||||
$cr->move_to ($xc + ($self->{size}/2) + $settings->{border_size},
|
||||
$yc + ($self->{size}/2) - $self->{fontsize} );
|
||||
Pango::Cairo::show_layout($cr, $layout);
|
||||
$cr->restore();
|
||||
}
|
||||
}
|
||||
|
||||
sub draw_moon
|
||||
{
|
||||
my ($self, $xc, $yc, $cr) = @_;
|
||||
$cr->save();
|
||||
$cr->new_path();
|
||||
$cr->arc($xc, $yc, $self->{size}/2, 0, 2*3.1415926535);
|
||||
if ($self->{phase} == 0) {
|
||||
$cr->stroke_preserve();
|
||||
$cr->fill();
|
||||
} elsif ($self->{phase} == 1) {
|
||||
$cr->stroke();
|
||||
$cr->arc($xc, $yc, $self->{size}/2, 3.1415926535/2, 3 * 3.1415926535/2);
|
||||
$cr->stroke_preserve();
|
||||
$cr->fill();
|
||||
} elsif ($self->{phase} == 2) {
|
||||
$cr->stroke();
|
||||
} elsif ($self->{phase} == 3) {
|
||||
$cr->stroke();
|
||||
$cr->arc($xc, $yc, $self->{size}/2, 3 * 3.1415926535/2, 3.1415926535/2);
|
||||
$cr->stroke_preserve();
|
||||
$cr->fill();
|
||||
}
|
||||
$cr->restore();
|
||||
}
|
||||
|
||||
package Remind::PDF::Entry::shade;
|
||||
use base 'Remind::PDF::Entry';
|
||||
sub _adjust
|
||||
{
|
||||
my ($self) = @_;
|
||||
if ($self->{body} =~ /^(\d+)\s+(\d+)\s+(\d+)/) {
|
||||
$self->{r} = $1;
|
||||
$self->{g} = $2;
|
||||
$self->{b} = $3;
|
||||
}
|
||||
}
|
||||
|
||||
package Remind::PDF::Entry::color;
|
||||
use base 'Remind::PDF::Entry';
|
||||
|
||||
# Nothing to do for COLOR-type reminder
|
||||
sub _adjust
|
||||
{
|
||||
}
|
||||
|
||||
package Remind::PDF::Entry::postscript;
|
||||
use base 'Remind::PDF::Entry';
|
||||
sub render {}
|
||||
|
||||
package Remind::PDF::Entry::psfile;
|
||||
use base 'Remind::PDF::Entry';
|
||||
sub render {}
|
||||
|
||||
package Remind::PDF::Entry::pango;
|
||||
use base 'Remind::PDF::Entry';
|
||||
sub _adjust
|
||||
{
|
||||
my ($self) = @_;
|
||||
if ($self->{body} =~ /^@([-0-9.]+),\s*([-0-9.]+)\s*(.*)/) {
|
||||
$self->{atx} = $1;
|
||||
$self->{aty} = $2;
|
||||
$self->{body} = $3;
|
||||
}
|
||||
}
|
||||
|
||||
sub render
|
||||
{
|
||||
my ($self, $pdf, $cr, $settings, $so_far, $day, $col, $height) = @_;
|
||||
|
||||
my ($x1, $y1, $x2, $y2) = $pdf->col_box_coordinates($so_far, $col, $height, $settings);
|
||||
my $layout = Pango::Cairo::create_layout($cr);
|
||||
|
||||
$layout->set_width(1024 * ($x2 - $x1 - 2 * $settings->{border_size}));
|
||||
$layout->set_wrap('word-char');
|
||||
$layout->set_markup(Encode::decode('UTF-8', $self->{body}));
|
||||
|
||||
if (($layout->get_text() // '') eq '') {
|
||||
# Invalid markup
|
||||
return 0;
|
||||
}
|
||||
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();
|
||||
|
||||
if ($height) {
|
||||
$cr->save();
|
||||
if (defined($self->{atx}) && defined($self->{aty})) {
|
||||
my ($x, $y);
|
||||
if ($self->{atx} < 0) {
|
||||
$x = $x2 + $self->{atx} - $wid;
|
||||
} else {
|
||||
$x = $x1 + $self->{atx};
|
||||
}
|
||||
if ($self->{aty} < 0) {
|
||||
$y = $y2 + $self->{aty} - $h;
|
||||
} else {
|
||||
$y = $y1 + $self->{aty};
|
||||
}
|
||||
$cr->move_to($x, $y);
|
||||
} else {
|
||||
$cr->move_to($x1 + $settings->{border_size}, $so_far);
|
||||
}
|
||||
Pango::Cairo::show_layout($cr, $layout);
|
||||
$cr->restore();
|
||||
}
|
||||
return $h;
|
||||
}
|
||||
|
||||
package Remind::PDF::Entry::UNKNOWN;
|
||||
use base 'Remind::PDF::Entry';
|
||||
sub render {}
|
||||
|
||||
1;
|
||||
|
||||
15
resources/tkremind.desktop
Executable file
15
resources/tkremind.desktop
Executable file
@@ -0,0 +1,15 @@
|
||||
[Desktop Entry]
|
||||
Type=Application
|
||||
Exec=tkremind
|
||||
StartupNotify=true
|
||||
Icon=tkremind
|
||||
Terminal=false
|
||||
Name=tkremind
|
||||
Comment=TkRemind Calendar Program
|
||||
Categories=Office;Calendar;
|
||||
Keywords=Calendar;remind;
|
||||
Keywords[ca]=Calendari;remind;
|
||||
Keywords[de]=Kalender;remind;
|
||||
Keywords[en_GB]=Calendar;remind;
|
||||
Keywords[es]=Calendario;remind;
|
||||
|
||||
BIN
resources/tkremind.png
Normal file
BIN
resources/tkremind.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 3.1 KiB |
@@ -1,4 +1,3 @@
|
||||
Files in this directory:
|
||||
|
||||
tkremind -- Tcl/Tk graphical calendar using Remind as engine
|
||||
cm2rem.tcl -- Convert Sun's "cm" calendar manager files to Remind.
|
||||
|
||||
@@ -1,358 +0,0 @@
|
||||
#!/bin/sh
|
||||
# -*-Mode: TCL;-*-
|
||||
|
||||
#--------------------------------------------------------------
|
||||
# cm2rem.tcl
|
||||
#
|
||||
# A cheesy Tcl script to convert Sun's "cm" calendar manager
|
||||
# files (version 3 only) to Remind format.
|
||||
#
|
||||
# This file is part of REMIND.
|
||||
# Copyright (C) 1992-2018 by Dianne Skoll
|
||||
#
|
||||
#--------------------------------------------------------------
|
||||
|
||||
# the next line restarts using tclsh \
|
||||
exec tclsh "$0" "$@"
|
||||
|
||||
set i 0
|
||||
foreach month {January February March April May June
|
||||
July August September October November December} {
|
||||
incr i
|
||||
set MonthNum($month) $i
|
||||
set FullMonth([string range $month 0 2]) $month
|
||||
}
|
||||
|
||||
#***********************************************************************
|
||||
# %PROCEDURE: convertParens
|
||||
# %ARGUMENTS:
|
||||
# line -- a line read from a cm file
|
||||
# %RETURNS:
|
||||
# A new line with all ( and ) outside quotes converted to { and }.
|
||||
# This cheap trick allows us to use Tcl's built-in list manipulation
|
||||
# functions to munge the line.
|
||||
#***********************************************************************
|
||||
proc convertParens { line } {
|
||||
# Convert all ( and ) to { and } unless they are inside a quoted
|
||||
# string
|
||||
set out ""
|
||||
set len [string length $line]
|
||||
set inQuotes 0
|
||||
for {set i 0} {$i < $len} {incr i} {
|
||||
set char [string range $line $i $i]
|
||||
if {$char == "\\" && $inQuotes} {
|
||||
append out $char
|
||||
incr i
|
||||
set char [string range $line $i $i]
|
||||
append out $char
|
||||
continue
|
||||
}
|
||||
|
||||
if {$char == "(" && !$inQuotes} {
|
||||
set char \{
|
||||
}
|
||||
|
||||
if {$char == ")" && !$inQuotes} {
|
||||
set char \}
|
||||
}
|
||||
|
||||
if {$char == "\""} {
|
||||
set inQuotes [expr !$inQuotes]
|
||||
}
|
||||
|
||||
append out $char
|
||||
}
|
||||
return $out
|
||||
}
|
||||
|
||||
#***********************************************************************
|
||||
# %PROCEDURE: processLine
|
||||
# %ARGUMENTS:
|
||||
# line -- a line read from a cm file
|
||||
# %RETURNS:
|
||||
# Nothing
|
||||
# %DESCRIPTION:
|
||||
# Processes a single line from the file, possibly writing a reminder
|
||||
# in Remind format to stdout
|
||||
#***********************************************************************
|
||||
proc processLine { line } {
|
||||
global Attributes
|
||||
global FullMonth
|
||||
|
||||
catch {unset Attributes}
|
||||
|
||||
# Only convert lines which start with "(add"
|
||||
if {[string range $line 0 3] != "(add"} {
|
||||
return
|
||||
}
|
||||
set line [convertParens $line]
|
||||
# Convert it to a list. CAREFUL: Potential security problem if
|
||||
# $line contains something nasty.
|
||||
|
||||
eval set line $line
|
||||
|
||||
set Attributes(body) ""
|
||||
foreach {key val} $line {
|
||||
switch -exact -- $key {
|
||||
"add" {
|
||||
set Attributes(date) $val
|
||||
}
|
||||
"what:" {
|
||||
append Attributes(body) $val
|
||||
}
|
||||
"details:" {
|
||||
append Attributes(body) $val
|
||||
}
|
||||
"duration:" {
|
||||
set Attributes(duration) $val
|
||||
}
|
||||
"period:" {
|
||||
set Attributes(period) $val
|
||||
}
|
||||
"ntimes:" {
|
||||
set Attributes(ntimes) $val
|
||||
}
|
||||
"attributes:" {
|
||||
set Attributes(action) $val
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
if {[info exists Attributes(action)]} {
|
||||
# Nuke quotes and commas in action
|
||||
regsub -all {[,\"]} $Attributes(action) { } Attributes(action)
|
||||
|
||||
# Add spaces to pairs
|
||||
regsub -all \}\{ $Attributes(action) \}\ \{ Attributes(action)
|
||||
|
||||
# Add another pair of brackets to make a proper list
|
||||
set Attributes(action) "{$Attributes(action)}"
|
||||
|
||||
# Convert to a real Tcl list
|
||||
eval set Attributes(action) $Attributes(action)
|
||||
}
|
||||
# Split out date into month, day, year, time parts
|
||||
scan $Attributes(date) "%s%s%s%s%s" wkday month day time year
|
||||
set time [string range $time 0 4]
|
||||
set Attributes(wkday) $wkday
|
||||
set Attributes(month) $FullMonth($month)
|
||||
set Attributes(day) $day
|
||||
set Attributes(time) $time
|
||||
set Attributes(year) $year
|
||||
|
||||
# Convert newlines in body to spaces
|
||||
set body $Attributes(body)
|
||||
regsub -all "\n" $body " " body
|
||||
|
||||
# TODO: Escape BODY to get rid of [] chars.
|
||||
set Attributes(body) $body
|
||||
|
||||
# Convert to Reminder format
|
||||
convertReminder
|
||||
}
|
||||
|
||||
#***********************************************************************
|
||||
# %PROCEDURE: convertReminder
|
||||
# %ARGUMENTS:
|
||||
# None -- uses global Attributes variable which must be filled in
|
||||
# %RETURNS:
|
||||
# Nothing
|
||||
# %DESCRIPTION:
|
||||
# Converts a reminder to Remind format.
|
||||
#***********************************************************************
|
||||
proc convertReminder {} {
|
||||
global Attributes
|
||||
switch -exact $Attributes(period) {
|
||||
single { convertSingleReminder }
|
||||
daily { convertDailyReminder }
|
||||
weekly { convertWeeklyReminder }
|
||||
monthly { convertMonthlyReminder }
|
||||
yearly { convertYearlyReminder }
|
||||
default {
|
||||
puts "\# Unable to convert reminder with period $Attributes(period)"
|
||||
puts "\# Body is: $Attributes(body)"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#***********************************************************************
|
||||
# %PROCEDURE: convertSingleReminder
|
||||
# %ARGUMENTS:
|
||||
# None -- uses global Attributes variable which must be filled in
|
||||
# %RETURNS:
|
||||
# Nothing
|
||||
# %DESCRIPTION:
|
||||
# Converts a reminder with "single" period to Remind format.
|
||||
#***********************************************************************
|
||||
proc convertSingleReminder {} {
|
||||
global Attributes
|
||||
puts "REM $Attributes(day) $Attributes(month) $Attributes(year) [at][duration]MSG $Attributes(body)"
|
||||
}
|
||||
|
||||
#***********************************************************************
|
||||
# %PROCEDURE: convertDailyReminder
|
||||
# %ARGUMENTS:
|
||||
# None -- uses global Attributes variable which must be filled in
|
||||
# %RETURNS:
|
||||
# Nothing
|
||||
# %DESCRIPTION:
|
||||
# Converts a reminder with "daily" period to Remind format.
|
||||
#***********************************************************************
|
||||
proc convertDailyReminder {} {
|
||||
global Attributes
|
||||
set ntimes [expr $Attributes(ntimes) - 1]
|
||||
if {$ntimes <= 1} {
|
||||
convertSingleReminder
|
||||
return
|
||||
}
|
||||
set until [getUntilDate $Attributes(day) $Attributes(month) $Attributes(year) $ntimes]
|
||||
|
||||
puts "REM $Attributes(day) $Attributes(month) $Attributes(year) *1 [at][duration]UNTIL $until MSG $Attributes(body)"
|
||||
}
|
||||
|
||||
#***********************************************************************
|
||||
# %PROCEDURE: convertWeeklyReminder
|
||||
# %ARGUMENTS:
|
||||
# None -- uses global Attributes variable which must be filled in
|
||||
# %RETURNS:
|
||||
# Nothing
|
||||
# %DESCRIPTION:
|
||||
# Converts a reminder with "daily" period to Remind format.
|
||||
#***********************************************************************
|
||||
proc convertWeeklyReminder {} {
|
||||
global Attributes
|
||||
set ntimes [expr $Attributes(ntimes) - 1]
|
||||
if {$ntimes <= 1} {
|
||||
convertSingleReminder
|
||||
return
|
||||
}
|
||||
set until [getUntilDate $Attributes(day) $Attributes(month) $Attributes(year) [expr $ntimes * 7]]
|
||||
|
||||
puts "REM $Attributes(day) $Attributes(month) $Attributes(year) *7 [at][duration]UNTIL $until MSG $Attributes(body)"
|
||||
}
|
||||
|
||||
#***********************************************************************
|
||||
# %PROCEDURE: convertMonthlyReminder
|
||||
# %ARGUMENTS:
|
||||
# None -- uses global Attributes variable which must be filled in
|
||||
# %RETURNS:
|
||||
# Nothing
|
||||
# %DESCRIPTION:
|
||||
# Converts a reminder with "monthly" period to Remind format.
|
||||
#***********************************************************************
|
||||
proc convertMonthlyReminder {} {
|
||||
global Attributes
|
||||
set ntimes [expr $Attributes(ntimes) - 1]
|
||||
if {$ntimes <= 1} {
|
||||
convertSingleReminder
|
||||
return
|
||||
}
|
||||
|
||||
# If repetition > 1000, it's infinite
|
||||
if {$ntimes > 1000} {
|
||||
puts "REM $Attributes(day) [at][duration]MSG $Attributes(body)"
|
||||
return
|
||||
}
|
||||
|
||||
### UNTIL date is fudged!
|
||||
set until [getUntilDate $Attributes(day) $Attributes(month) $Attributes(year) [expr $ntimes * 30]]
|
||||
|
||||
puts "REM $Attributes(day) [at][duration]UNTIL $until MSG $Attributes(body)"
|
||||
}
|
||||
|
||||
#***********************************************************************
|
||||
# %PROCEDURE: convertYearlyReminder
|
||||
# %ARGUMENTS:
|
||||
# None -- uses global Attributes variable which must be filled in
|
||||
# %RETURNS:
|
||||
# Nothing
|
||||
# %DESCRIPTION:
|
||||
# Converts a reminder with "yearly" period to Remind format.
|
||||
#***********************************************************************
|
||||
proc convertYearlyReminder {} {
|
||||
global Attributes
|
||||
|
||||
# No special handling of ntimes et al.
|
||||
puts "REM $Attributes(day) $Attributes(month) [at][duration]MSG $Attributes(body)"
|
||||
|
||||
}
|
||||
|
||||
#***********************************************************************
|
||||
# %PROCEDURE: at
|
||||
# %ARGUMENTS:
|
||||
# None -- uses Attributes global variable
|
||||
# %RETURNS:
|
||||
# A string providing the correct AT clause for a timed reminder.
|
||||
#***********************************************************************
|
||||
proc at {} {
|
||||
global Attributes
|
||||
if {![info exists Attributes(time)]} {
|
||||
return ""
|
||||
}
|
||||
if {"$Attributes(time)" == ""} {
|
||||
return ""
|
||||
}
|
||||
|
||||
return "AT $Attributes(time) "
|
||||
}
|
||||
|
||||
#***********************************************************************
|
||||
# %PROCEDURE: duration
|
||||
# %ARGUMENTS:
|
||||
# None -- uses Attributes global variable
|
||||
# %RETURNS:
|
||||
# A string providing the correct DURATION clause for a timed reminder.
|
||||
#***********************************************************************
|
||||
proc duration {} {
|
||||
global Attributes
|
||||
if {![info exists Attributes(duration)]} {
|
||||
return ""
|
||||
}
|
||||
if {"$Attributes(duration)" == ""} {
|
||||
return ""
|
||||
}
|
||||
set h [expr $Attributes(duration) / 3600]
|
||||
set remainder [expr $Attributes(duration) - $h*3600]
|
||||
set m [expr $remainder / 60]
|
||||
return "DURATION [format "%d:%02d " $h $m]"
|
||||
}
|
||||
|
||||
#***********************************************************************
|
||||
# %PROCEDURE: getUntilDate
|
||||
# %ARGUMENTS:
|
||||
# day, month, year -- a date
|
||||
# days -- number of days to add to date
|
||||
# %RETURNS:
|
||||
# The date which is "days" later than supplied date in a correct UNTIL
|
||||
# format.
|
||||
#***********************************************************************
|
||||
proc getUntilDate { day month year days } {
|
||||
global RemindPipe
|
||||
global MonthNum
|
||||
set date "'$year/$MonthNum($month)/$day'"
|
||||
puts $RemindPipe "MSG \[trigger($date + $days)\]%"
|
||||
puts $RemindPipe "flush"
|
||||
flush $RemindPipe
|
||||
gets $RemindPipe line
|
||||
return $line
|
||||
}
|
||||
|
||||
catch {wm withdraw .}
|
||||
# Start a Remind process to issue reminders
|
||||
if {[catch {set RemindPipe [open "|remind -" "r+"]} err]} {
|
||||
puts stderr "Error: Cannot run Remind: $err"
|
||||
exit 1
|
||||
}
|
||||
|
||||
puts $RemindPipe "banner %"
|
||||
flush $RemindPipe
|
||||
|
||||
# Write some blurb
|
||||
puts "\# Reminder file converted from \"cm\" data by cm2rem.tcl"
|
||||
puts ""
|
||||
|
||||
while {[gets stdin line] >= 0} {
|
||||
processLine $line
|
||||
}
|
||||
exit 0
|
||||
1263
scripts/tkremind
1263
scripts/tkremind
File diff suppressed because it is too large
Load Diff
@@ -18,11 +18,10 @@ INSTALL_PROGRAM=@INSTALL_PROGRAM@
|
||||
INSTALL_DATA=@INSTALL_DATA@
|
||||
|
||||
PROGS= remind rem2ps
|
||||
SCRIPTS= $(srcdir)/../scripts/tkremind $(srcdir)/../scripts/cm2rem.tcl
|
||||
SCRIPTS= $(srcdir)/../scripts/tkremind
|
||||
|
||||
MANS= $(srcdir)/../man/rem2ps.1 $(srcdir)/../man/remind.1 \
|
||||
$(srcdir)/../man/tkremind.1 $(srcdir)/../man/cm2rem.1 \
|
||||
$(srcdir)/../man/rem.1
|
||||
$(srcdir)/../man/tkremind.1 $(srcdir)/../man/rem.1
|
||||
|
||||
.SUFFIXES:
|
||||
.SUFFIXES: .c .o
|
||||
@@ -37,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; \
|
||||
@@ -62,14 +61,28 @@ 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
|
||||
-mkdir -p $(DESTDIR)$(prefix)/icons
|
||||
-mkdir -p $(DESTDIR)$(prefix)/applications
|
||||
$(INSTALL_DATA) $(srcdir)/../resources/tkremind.png $(DESTDIR)$(prefix)/icons
|
||||
$(INSTALL_PROGRAM) $(srcdir)/../resources/tkremind.desktop $(DESTDIR)$(prefix)/applications
|
||||
-if test "$(DESTDIR)" = ""; then \
|
||||
update-desktop-database < /dev/null > /dev/null 2>&1 ; \
|
||||
xdg-icon-resource install --novendor --size 64 $(DESTDIR)$(prefix)/icons/tkremind.png < /dev/null > /dev/null 2>&1; \
|
||||
xdg-desktop-menu install --novendor $(DESTDIR)$(prefix)/applications/tkremind.desktop < /dev/null > /dev/null 2>&1 ; \
|
||||
fi
|
||||
|
||||
install: install-nostripped
|
||||
install-stripped: install
|
||||
strip $(DESTDIR)$(bindir)/remind || true
|
||||
strip $(DESTDIR)$(bindir)/rem2ps || true
|
||||
|
||||
clean:
|
||||
rm -f *.o *~ core *.bak $(PROGS)
|
||||
|
||||
cppcheck:
|
||||
cppcheck --force --enable=all --suppress=variableScope --suppress=ConfigurationNotChecked *.c
|
||||
|
||||
clobber:
|
||||
rm -f *.o *~ remind rem2ps test.out core *.bak
|
||||
|
||||
|
||||
1079
src/calendar.c
1079
src/calendar.c
File diff suppressed because it is too large
Load Diff
54
src/compare-language-mods.pl
Executable file
54
src/compare-language-mods.pl
Executable 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(@_);
|
||||
}
|
||||
@@ -7,8 +7,11 @@
|
||||
/* Define if your <sys/time.h> declares struct tm. */
|
||||
#undef TM_IN_SYS_TIME
|
||||
|
||||
/* Define if you have the <sys/file.h> header file. */
|
||||
#undef HAVE_SYS_FILE_H
|
||||
/* Define if you have the <sys/types.h> header file. */
|
||||
#undef HAVE_SYS_TYPES_H
|
||||
|
||||
/* Define if you have the <sys/inotify.h> header file. */
|
||||
#undef HAVE_SYS_INOTIFY_H
|
||||
|
||||
/* Define if you have the <glob.h> header file */
|
||||
#undef HAVE_GLOB_H
|
||||
@@ -17,10 +20,16 @@
|
||||
|
||||
#undef HAVE_LOCALE_H
|
||||
|
||||
#undef HAVE_INOTIFY_INIT1
|
||||
|
||||
#undef HAVE_LANGINFO_H
|
||||
|
||||
#undef HAVE_GLOB
|
||||
|
||||
#undef HAVE_SETENV
|
||||
|
||||
#undef HAVE_INITGROUPS
|
||||
|
||||
#undef HAVE_UNSETENV
|
||||
|
||||
#undef HAVE_MBSTOWCS
|
||||
@@ -33,7 +42,4 @@
|
||||
/* The number of bytes in a unsigned long. */
|
||||
#undef SIZEOF_UNSIGNED_LONG
|
||||
|
||||
/* The number of bytes in a unsigned short. */
|
||||
#undef SIZEOF_UNSIGNED_SHORT
|
||||
|
||||
#include "custom.h"
|
||||
|
||||
85
src/custom.h
85
src/custom.h
@@ -6,27 +6,24 @@
|
||||
/* which you can customize. */
|
||||
/* */
|
||||
/* This file is part of REMIND. */
|
||||
/* Copyright (C) 1992-2020 by Dianne Skoll */
|
||||
/* Copyright (C) 1992-2024 by Dianne Skoll */
|
||||
/* SPDX-License-Identifier: GPL-2.0-only */
|
||||
/* */
|
||||
/***************************************************************/
|
||||
|
||||
/*---------------------------------------------------------------------*/
|
||||
/* LAT_DEG, LAT_MIN and LAT_SEC: Latitude of your location */
|
||||
/* LON_DEG, LON_MIN and LON_SEC: Longitude of your location */
|
||||
/* DEFAULT_LATITUDE: Latitude of your location */
|
||||
/* DEFAULT_LONGITUDE: Longitude of your location */
|
||||
/* LOCATION: A string identifying your location. */
|
||||
/* All latitude and longitude numbers should be positive for the */
|
||||
/* northern and western hemisphere. If you live in the southern */
|
||||
/* hemisphere, ALL latitude values should be negative. If you live */
|
||||
/* in the eastern hemisphere, ALL longitude values should be negative. */
|
||||
/* Latitude and longitude should be positive for the */
|
||||
/* northern and eastern hemisphere and negative for the southern and */
|
||||
/* western hemisphere. */
|
||||
/* */
|
||||
/* The default values are initially set to Ottawa, Ontario, Canada. */
|
||||
/* The default values are initially set to the city hall in Ottawa, */
|
||||
/* Ontario, Canada. */
|
||||
/*---------------------------------------------------------------------*/
|
||||
#define LAT_DEG 45
|
||||
#define LAT_MIN 24
|
||||
#define LAT_SEC 0
|
||||
#define LON_DEG 75
|
||||
#define LON_MIN 39
|
||||
#define LON_SEC 0
|
||||
#define DEFAULT_LATITUDE 45.420556
|
||||
#define DEFAULT_LONGITUDE -75.689722
|
||||
#define LOCATION "Ottawa"
|
||||
|
||||
/*---------------------------------------------------------------------*/
|
||||
@@ -58,45 +55,6 @@
|
||||
#define DATETIMESEP '@'
|
||||
/* #define DATETIMESEP '/' */
|
||||
|
||||
/*---------------------------------------------------------------------*/
|
||||
/* ISOLATIN1: define it to 1 if you use the */
|
||||
/* ISO 8859-1 character set instead of ASCII. */
|
||||
/*---------------------------------------------------------------------*/
|
||||
#define ISOLATIN1 1
|
||||
|
||||
/*---------------------------------------------------------------------*/
|
||||
/* ISOLATIN2: define it to 1 if you use the */
|
||||
/* ISO 8859-2 character set instead of ASCII. */
|
||||
/* NOT ALL LANGUAGE MODULES SUPPORT THIS. Note that at most one of */
|
||||
/* ISOLATIN1, ISOLATIN2, IBMEXTENDED and IBM852 should be 1; if more */
|
||||
/* then one are defined as 1, the results are unspecified. */
|
||||
/*---------------------------------------------------------------------*/
|
||||
#define ISOLATIN2 0
|
||||
|
||||
/*---------------------------------------------------------------------*/
|
||||
/* IBMEXTENDED: define as 1 if your system uses the IBM extended */
|
||||
/* character set. */
|
||||
/* NOT ALL LANGUAGE MODULES SUPPORT THIS. Note that at most one of */
|
||||
/* ISOLATIN1, ISOLATIN2, IBMEXTENDED and IBM852 should be 1; if more */
|
||||
/* then one are defined as 1, the results are unspecified. */
|
||||
/*---------------------------------------------------------------------*/
|
||||
#define IBMEXTENDED 0
|
||||
|
||||
/*---------------------------------------------------------------------*/
|
||||
/* IBM852: define as 1 if your system uses the IBM CPI-852 extended */
|
||||
/* character set. */
|
||||
/* NOT ALL LANGUAGE MODULES SUPPORT THIS. Note that at most one of */
|
||||
/* ISOLATIN1, ISOLATIN2, IBMEXTENDED and IBM852 should be 1; if more */
|
||||
/* then one are defined as 1, the results are unspecified. */
|
||||
/*---------------------------------------------------------------------*/
|
||||
#define IBM852 0
|
||||
|
||||
/*---------------------------------------------------------------------*/
|
||||
/* WANT_U_OPTION: Comment out the next define to permanently disable */
|
||||
/* the -u option. */
|
||||
/*---------------------------------------------------------------------*/
|
||||
#define WANT_U_OPTION 1
|
||||
|
||||
/**********************************************************************/
|
||||
/**********************************************************************/
|
||||
/**********************************************************************/
|
||||
@@ -114,16 +72,7 @@
|
||||
/* WANT_SHELL_ESCAPING: Define this if you want special shell */
|
||||
/* characters to be escaped with a backslash for the -k option. */
|
||||
/*---------------------------------------------------------------------*/
|
||||
#if defined(UNIX)
|
||||
#define WANT_SHELL_ESCAPING 1
|
||||
#endif
|
||||
|
||||
/*---------------------------------------------------------------------*/
|
||||
/* Some implementations have a broken 'putc' and 'putchar'. */
|
||||
/*---------------------------------------------------------------------*/
|
||||
#ifdef __SASC_60
|
||||
#define BROKEN_PUTC
|
||||
#endif
|
||||
|
||||
/*---------------------------------------------------------------------*/
|
||||
/* BASE: The base year for date calculation. NOTE! January 1 of the */
|
||||
@@ -168,7 +117,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? */
|
||||
@@ -189,7 +138,7 @@
|
||||
/*---------------------------------------------------------------------*/
|
||||
/* How many global omits of the form YYYY MM DD do we handle? */
|
||||
/*---------------------------------------------------------------------*/
|
||||
#define MAX_FULL_OMITS 500
|
||||
#define MAX_FULL_OMITS 1000
|
||||
|
||||
/*---------------------------------------------------------------------*/
|
||||
/* How many global omits of the form MM DD do we handle? */
|
||||
@@ -223,14 +172,6 @@
|
||||
#define PSBEGIN2 "# rem2ps2 begin"
|
||||
#define PSEND2 "# rem2ps2 end"
|
||||
|
||||
#ifdef BROKEN_PUTC
|
||||
#define Putc SafePutc
|
||||
#define PutChar SafePutChar
|
||||
#else
|
||||
#define Putc putc
|
||||
#define PutChar putchar
|
||||
#endif
|
||||
|
||||
#if defined(HAVE_MBSTOWCS) && defined(HAVE_WCTYPE_H)
|
||||
#define REM_USE_WCHAR 1
|
||||
#else
|
||||
|
||||
@@ -6,27 +6,24 @@
|
||||
/* which you can customize. */
|
||||
/* */
|
||||
/* This file is part of REMIND. */
|
||||
/* Copyright (C) 1992-2020 by Dianne Skoll */
|
||||
/* Copyright (C) 1992-2024 by Dianne Skoll */
|
||||
/* SPDX-License-Identifier: GPL-2.0-only */
|
||||
/* */
|
||||
/***************************************************************/
|
||||
|
||||
/*---------------------------------------------------------------------*/
|
||||
/* LAT_DEG, LAT_MIN and LAT_SEC: Latitude of your location */
|
||||
/* LON_DEG, LON_MIN and LON_SEC: Longitude of your location */
|
||||
/* DEFAULT_LATITUDE: Latitude of your location */
|
||||
/* DEFAULT_LONGITUDE: Longitude of your location */
|
||||
/* LOCATION: A string identifying your location. */
|
||||
/* All latitude and longitude numbers should be positive for the */
|
||||
/* northern and western hemisphere. If you live in the southern */
|
||||
/* hemisphere, ALL latitude values should be negative. If you live */
|
||||
/* in the eastern hemisphere, ALL longitude values should be negative. */
|
||||
/* Latitude and longitude should be positive for the */
|
||||
/* northern and eastern hemisphere and negative for the southern and */
|
||||
/* western hemisphere. */
|
||||
/* */
|
||||
/* The default values are initially set to Ottawa, Ontario, Canada. */
|
||||
/* The default values are initially set to the city hall in Ottawa, */
|
||||
/* Ontario, Canada. */
|
||||
/*---------------------------------------------------------------------*/
|
||||
#define LAT_DEG 45
|
||||
#define LAT_MIN 24
|
||||
#define LAT_SEC 0
|
||||
#define LON_DEG 75
|
||||
#define LON_MIN 39
|
||||
#define LON_SEC 0
|
||||
#define DEFAULT_LATITUDE 45.420556
|
||||
#define DEFAULT_LONGITUDE -75.689722
|
||||
#define LOCATION "Ottawa"
|
||||
|
||||
/*---------------------------------------------------------------------*/
|
||||
@@ -58,45 +55,6 @@
|
||||
#define DATETIMESEP '@'
|
||||
/* #define DATETIMESEP '/' */
|
||||
|
||||
/*---------------------------------------------------------------------*/
|
||||
/* ISOLATIN1: define it to 1 if you use the */
|
||||
/* ISO 8859-1 character set instead of ASCII. */
|
||||
/*---------------------------------------------------------------------*/
|
||||
#define ISOLATIN1 1
|
||||
|
||||
/*---------------------------------------------------------------------*/
|
||||
/* ISOLATIN2: define it to 1 if you use the */
|
||||
/* ISO 8859-2 character set instead of ASCII. */
|
||||
/* NOT ALL LANGUAGE MODULES SUPPORT THIS. Note that at most one of */
|
||||
/* ISOLATIN1, ISOLATIN2, IBMEXTENDED and IBM852 should be 1; if more */
|
||||
/* then one are defined as 1, the results are unspecified. */
|
||||
/*---------------------------------------------------------------------*/
|
||||
#define ISOLATIN2 0
|
||||
|
||||
/*---------------------------------------------------------------------*/
|
||||
/* IBMEXTENDED: define as 1 if your system uses the IBM extended */
|
||||
/* character set. */
|
||||
/* NOT ALL LANGUAGE MODULES SUPPORT THIS. Note that at most one of */
|
||||
/* ISOLATIN1, ISOLATIN2, IBMEXTENDED and IBM852 should be 1; if more */
|
||||
/* then one are defined as 1, the results are unspecified. */
|
||||
/*---------------------------------------------------------------------*/
|
||||
#define IBMEXTENDED 0
|
||||
|
||||
/*---------------------------------------------------------------------*/
|
||||
/* IBM852: define as 1 if your system uses the IBM CPI-852 extended */
|
||||
/* character set. */
|
||||
/* NOT ALL LANGUAGE MODULES SUPPORT THIS. Note that at most one of */
|
||||
/* ISOLATIN1, ISOLATIN2, IBMEXTENDED and IBM852 should be 1; if more */
|
||||
/* then one are defined as 1, the results are unspecified. */
|
||||
/*---------------------------------------------------------------------*/
|
||||
#define IBM852 0
|
||||
|
||||
/*---------------------------------------------------------------------*/
|
||||
/* WANT_U_OPTION: Comment out the next define to permanently disable */
|
||||
/* the -u option. */
|
||||
/*---------------------------------------------------------------------*/
|
||||
#define WANT_U_OPTION 1
|
||||
|
||||
/**********************************************************************/
|
||||
/**********************************************************************/
|
||||
/**********************************************************************/
|
||||
@@ -114,16 +72,7 @@
|
||||
/* WANT_SHELL_ESCAPING: Define this if you want special shell */
|
||||
/* characters to be escaped with a backslash for the -k option. */
|
||||
/*---------------------------------------------------------------------*/
|
||||
#if defined(UNIX)
|
||||
#define WANT_SHELL_ESCAPING 1
|
||||
#endif
|
||||
|
||||
/*---------------------------------------------------------------------*/
|
||||
/* Some implementations have a broken 'putc' and 'putchar'. */
|
||||
/*---------------------------------------------------------------------*/
|
||||
#ifdef __SASC_60
|
||||
#define BROKEN_PUTC
|
||||
#endif
|
||||
|
||||
/*---------------------------------------------------------------------*/
|
||||
/* BASE: The base year for date calculation. NOTE! January 1 of the */
|
||||
@@ -168,7 +117,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? */
|
||||
@@ -189,7 +138,7 @@
|
||||
/*---------------------------------------------------------------------*/
|
||||
/* How many global omits of the form YYYY MM DD do we handle? */
|
||||
/*---------------------------------------------------------------------*/
|
||||
#define MAX_FULL_OMITS 500
|
||||
#define MAX_FULL_OMITS 1000
|
||||
|
||||
/*---------------------------------------------------------------------*/
|
||||
/* How many global omits of the form MM DD do we handle? */
|
||||
@@ -223,14 +172,6 @@
|
||||
#define PSBEGIN2 "# rem2ps2 begin"
|
||||
#define PSEND2 "# rem2ps2 end"
|
||||
|
||||
#ifdef BROKEN_PUTC
|
||||
#define Putc SafePutc
|
||||
#define PutChar SafePutChar
|
||||
#else
|
||||
#define Putc putc
|
||||
#define PutChar putchar
|
||||
#endif
|
||||
|
||||
#if defined(HAVE_MBSTOWCS) && defined(HAVE_WCTYPE_H)
|
||||
#define REM_USE_WCHAR 1
|
||||
#else
|
||||
|
||||
455
src/dorem.c
455
src/dorem.c
@@ -7,7 +7,8 @@
|
||||
/* commands. */
|
||||
/* */
|
||||
/* This file is part of REMIND. */
|
||||
/* Copyright (C) 1992-2020 by Dianne Skoll */
|
||||
/* Copyright (C) 1992-2024 by Dianne Skoll */
|
||||
/* SPDX-License-Identifier: GPL-2.0-only */
|
||||
/* */
|
||||
/***************************************************************/
|
||||
|
||||
@@ -24,16 +25,12 @@
|
||||
#include "protos.h"
|
||||
#include "expr.h"
|
||||
|
||||
/* Define the shell characters not to escape */
|
||||
static char const DontEscapeMe[] =
|
||||
"1234567890_-=+abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ@.,";
|
||||
|
||||
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 ShouldTriggerBasedOnWarn (Trigger *t, int jul, int *err);
|
||||
static int ParseUntil (ParsePtr s, Trigger *t, int type);
|
||||
static int ShouldTriggerBasedOnWarn (Trigger *t, int dse, int *err);
|
||||
static int ComputeTrigDuration(TimeTrig *t);
|
||||
|
||||
static int
|
||||
@@ -59,7 +56,7 @@ int DoRem(ParsePtr p)
|
||||
Trigger trig;
|
||||
TimeTrig tim;
|
||||
int r, err;
|
||||
int jul;
|
||||
int dse;
|
||||
DynamicBuffer buf;
|
||||
Token tok;
|
||||
|
||||
@@ -100,9 +97,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);
|
||||
@@ -122,16 +123,20 @@ int DoRem(ParsePtr p)
|
||||
}
|
||||
StrnCpy(trig.passthru, DBufValue(&buf), PASSTHRU_LEN);
|
||||
DBufFree(&buf);
|
||||
}
|
||||
trig.typ = tok.val;
|
||||
jul = LastTriggerDate;
|
||||
}
|
||||
trig.typ = tok.val;
|
||||
|
||||
/* Convert some SPECIALs back to plain types */
|
||||
FixSpecialType(&trig);
|
||||
|
||||
dse = LastTriggerDate;
|
||||
if (!LastTrigValid || PurgeMode) {
|
||||
FreeTrig(&trig);
|
||||
return OK;
|
||||
}
|
||||
} else {
|
||||
/* Calculate the trigger date */
|
||||
jul = ComputeTrigger(trig.scanfrom, &trig, &tim, &r, 1);
|
||||
dse = ComputeTrigger(trig.scanfrom, &trig, &tim, &r, 1);
|
||||
if (r) {
|
||||
if (PurgeMode) {
|
||||
PurgeEchoLine("%s: %s\n", "#!P! Problem calculating trigger date", ErrMsg[r]);
|
||||
@@ -145,8 +150,16 @@ int DoRem(ParsePtr p)
|
||||
}
|
||||
}
|
||||
|
||||
/* Add to global OMITs if so indicated */
|
||||
if (trig.addomit) {
|
||||
r = AddGlobalOmit(dse);
|
||||
if (r) {
|
||||
FreeTrig(&trig);
|
||||
return r;
|
||||
}
|
||||
}
|
||||
if (PurgeMode) {
|
||||
if (trig.expired || jul < JulianToday) {
|
||||
if (trig.expired || dse < DSEToday) {
|
||||
if (p->expr_happened) {
|
||||
if (p->nonconst_expr) {
|
||||
PurgeEchoLine("%s\n", "#!P: Next line may have expired, but contains non-constant expression");
|
||||
@@ -164,27 +177,39 @@ int DoRem(ParsePtr p)
|
||||
FreeTrig(&trig);
|
||||
return OK;
|
||||
}
|
||||
/* Queue the reminder, if necessary */
|
||||
if (jul == JulianToday &&
|
||||
|
||||
/* Queue the reminder, if necessary */
|
||||
if (dse == DSEToday &&
|
||||
!(!IgnoreOnce &&
|
||||
trig.once != NO_ONCE &&
|
||||
FileAccessDate == JulianToday))
|
||||
FileAccessDate == DSEToday))
|
||||
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;
|
||||
}
|
||||
|
||||
if (ShouldTriggerReminder(&trig, &tim, jul, &err)) {
|
||||
if ( (r=TriggerReminder(p, &trig, &tim, jul)) ) {
|
||||
r = OK;
|
||||
if (ShouldTriggerReminder(&trig, &tim, dse, &err)) {
|
||||
if ( (r=TriggerReminder(p, &trig, &tim, dse, 0, NULL)) ) {
|
||||
FreeTrig(&trig);
|
||||
return r;
|
||||
}
|
||||
} else {
|
||||
/* Parse the rest of the line to catch any potential
|
||||
expression-pasting errors */
|
||||
if (ParseUntriggered) {
|
||||
while (ParseChar(p, &r, 0)) {
|
||||
if (r != 0) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
FreeTrig(&trig);
|
||||
return OK;
|
||||
return r;
|
||||
}
|
||||
|
||||
/***************************************************************/
|
||||
@@ -215,6 +240,8 @@ int ParseRem(ParsePtr s, Trigger *trig, TimeTrig *tim, int save_in_globals)
|
||||
trig->localomit = NO_WD;
|
||||
trig->skip = NO_SKIP;
|
||||
trig->once = NO_ONCE;
|
||||
trig->addomit = 0;
|
||||
trig->noqueue = 0;
|
||||
trig->typ = NO_TYPE;
|
||||
trig->scanfrom = NO_DATE;
|
||||
trig->from = NO_DATE;
|
||||
@@ -229,14 +256,18 @@ int ParseRem(ParsePtr s, Trigger *trig, TimeTrig *tim, int save_in_globals)
|
||||
DBufInit(&(trig->tags));
|
||||
trig->passthru[0] = 0;
|
||||
tim->ttime = NO_TIME;
|
||||
tim->delta = NO_DELTA;
|
||||
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;
|
||||
@@ -244,12 +275,31 @@ 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;
|
||||
if (trig->m != NO_MON) return E_MON_TWICE;
|
||||
if (trig->y != NO_YR) return E_YR_TWICE;
|
||||
FromJulian(tok.val, &y, &m, &d);
|
||||
FromDSE(tok.val, &y, &m, &d);
|
||||
trig->y = y;
|
||||
trig->m = m;
|
||||
trig->d = d;
|
||||
@@ -260,7 +310,7 @@ int ParseRem(ParsePtr s, Trigger *trig, TimeTrig *tim, int save_in_globals)
|
||||
if (trig->d != NO_DAY) return E_DAY_TWICE;
|
||||
if (trig->m != NO_MON) return E_MON_TWICE;
|
||||
if (trig->y != NO_YR) return E_YR_TWICE;
|
||||
FromJulian(tok.val / MINUTES_PER_DAY, &y, &m, &d);
|
||||
FromDSE(tok.val / MINUTES_PER_DAY, &y, &m, &d);
|
||||
trig->y = y;
|
||||
trig->m = m;
|
||||
trig->d = d;
|
||||
@@ -284,6 +334,7 @@ int ParseRem(ParsePtr s, Trigger *trig, TimeTrig *tim, int save_in_globals)
|
||||
break;
|
||||
|
||||
case T_MaybeUncomputable:
|
||||
DBufFree(&buf);
|
||||
trig->maybe_uncomputable = 1;
|
||||
break;
|
||||
|
||||
@@ -299,6 +350,16 @@ int ParseRem(ParsePtr s, Trigger *trig, TimeTrig *tim, int save_in_globals)
|
||||
if (r) return r;
|
||||
break;
|
||||
|
||||
/* A time implicitly introduces an AT if AT is not explicit */
|
||||
case T_Time:
|
||||
DBufFree(&buf);
|
||||
if (tim->ttime != NO_TIME) return E_TIME_TWICE;
|
||||
tim->ttime = tok.val;
|
||||
r = ParseTimeTrig(s, tim, save_in_globals);
|
||||
if (r) return r;
|
||||
trig->duration_days = ComputeTrigDuration(tim);
|
||||
break;
|
||||
|
||||
case T_At:
|
||||
DBufFree(&buf);
|
||||
r=ParseTimeTrig(s, tim, save_in_globals);
|
||||
@@ -316,7 +377,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;
|
||||
@@ -326,19 +386,21 @@ int ParseRem(ParsePtr s, Trigger *trig, TimeTrig *tim, int save_in_globals)
|
||||
}
|
||||
StrnCpy(trig->passthru, DBufValue(&buf), PASSTHRU_LEN);
|
||||
}
|
||||
return OK;
|
||||
FixSpecialType(trig);
|
||||
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;
|
||||
|
||||
@@ -372,16 +434,35 @@ 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;
|
||||
trig->once = ONCE_ONCE;
|
||||
break;
|
||||
|
||||
case T_AddOmit:
|
||||
DBufFree(&buf);
|
||||
trig->addomit = 1;
|
||||
break;
|
||||
|
||||
case T_NoQueue:
|
||||
DBufFree(&buf);
|
||||
trig->noqueue = 1;
|
||||
break;
|
||||
|
||||
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);
|
||||
@@ -390,12 +471,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;
|
||||
@@ -417,7 +498,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:
|
||||
@@ -463,10 +549,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 (DSE(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 = DSEToday;
|
||||
}
|
||||
|
||||
return OK;
|
||||
}
|
||||
|
||||
/***************************************************************/
|
||||
@@ -478,7 +612,7 @@ static int ParseTimeTrig(ParsePtr s, TimeTrig *tim, int save_in_globals)
|
||||
{
|
||||
Token tok;
|
||||
int r;
|
||||
|
||||
int seen_delta = 0;
|
||||
DynamicBuffer buf;
|
||||
DBufInit(&buf);
|
||||
|
||||
@@ -495,8 +629,9 @@ static int ParseTimeTrig(ParsePtr s, TimeTrig *tim, int save_in_globals)
|
||||
|
||||
case T_Delta:
|
||||
DBufFree(&buf);
|
||||
if (tim->delta != NO_DELTA) return E_DELTA_TWICE;
|
||||
tim->delta = (tok.val > 0) ? tok.val : -tok.val;
|
||||
if (seen_delta) return E_DELTA_TWICE;
|
||||
seen_delta = 1;
|
||||
tim->delta = (tok.val >= 0) ? tok.val : -tok.val;
|
||||
break;
|
||||
|
||||
case T_Rep:
|
||||
@@ -556,12 +691,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;
|
||||
@@ -577,7 +718,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;
|
||||
@@ -586,7 +727,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;
|
||||
@@ -595,7 +736,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;
|
||||
@@ -604,23 +745,23 @@ 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);
|
||||
FromDSE(tok.val, &y, &m, &d);
|
||||
break;
|
||||
|
||||
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;
|
||||
}
|
||||
@@ -628,7 +769,7 @@ static int ParseUntil(ParsePtr s, Trigger *t)
|
||||
DBufFree(&buf);
|
||||
return E_BAD_DATE;
|
||||
}
|
||||
t->until = Julian(y, m, d);
|
||||
t->until = DSE(y, m, d);
|
||||
PushToken(DBufValue(&buf), s);
|
||||
DBufFree(&buf);
|
||||
return OK;
|
||||
@@ -707,7 +848,7 @@ static int ParseScanFrom(ParsePtr s, Trigger *t, int type)
|
||||
Eprint("%s: %s", word, ErrMsg[E_DAY_TWICE]);
|
||||
return E_DAY_TWICE;
|
||||
}
|
||||
FromJulian(tok.val, &y, &m, &d);
|
||||
FromDSE(tok.val, &y, &m, &d);
|
||||
break;
|
||||
|
||||
case T_Back:
|
||||
@@ -731,7 +872,7 @@ static int ParseScanFrom(ParsePtr s, Trigger *t, int type)
|
||||
if (tok.val < 0) {
|
||||
tok.val = -tok.val;
|
||||
}
|
||||
FromJulian(JulianToday - tok.val, &y, &m, &d);
|
||||
FromDSE(DSEToday - tok.val, &y, &m, &d);
|
||||
break;
|
||||
|
||||
default:
|
||||
@@ -744,11 +885,11 @@ static int ParseScanFrom(ParsePtr s, Trigger *t, int type)
|
||||
DBufFree(&buf);
|
||||
return E_BAD_DATE;
|
||||
}
|
||||
t->scanfrom = Julian(y, m, d);
|
||||
t->scanfrom = DSE(y, m, d);
|
||||
if (type == FROM_TYPE) {
|
||||
t->from = t->scanfrom;
|
||||
if (t->scanfrom < JulianToday) {
|
||||
t->scanfrom = JulianToday;
|
||||
if (t->scanfrom < DSEToday) {
|
||||
t->scanfrom = DSEToday;
|
||||
}
|
||||
} else {
|
||||
t->from = NO_DATE;
|
||||
@@ -760,6 +901,8 @@ static int ParseScanFrom(ParsePtr s, Trigger *t, int type)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/***************************************************************/
|
||||
/* */
|
||||
/* TriggerReminder */
|
||||
@@ -767,7 +910,7 @@ static int ParseScanFrom(ParsePtr s, Trigger *t, int type)
|
||||
/* Trigger the reminder if it's a RUN or MSG type. */
|
||||
/* */
|
||||
/***************************************************************/
|
||||
int TriggerReminder(ParsePtr p, Trigger *t, TimeTrig *tim, int jul)
|
||||
int TriggerReminder(ParsePtr p, Trigger *t, TimeTrig *tim, int dse, int is_queued, DynamicBuffer *output)
|
||||
{
|
||||
int r, y, m, d;
|
||||
char PrioExpr[VAR_NAME_LEN+25];
|
||||
@@ -775,8 +918,21 @@ int TriggerReminder(ParsePtr p, Trigger *t, TimeTrig *tim, int jul)
|
||||
DynamicBuffer buf, calRow;
|
||||
DynamicBuffer pre_buf;
|
||||
char const *s;
|
||||
char const *msg_command = NULL;
|
||||
Value v;
|
||||
|
||||
if (MsgCommand) {
|
||||
msg_command = MsgCommand;
|
||||
}
|
||||
if (is_queued && QueuedMsgCommand) {
|
||||
msg_command = QueuedMsgCommand;
|
||||
}
|
||||
|
||||
/* A null command is no command */
|
||||
if (msg_command && !*msg_command) {
|
||||
msg_command = NULL;
|
||||
}
|
||||
|
||||
int red = -1, green = -1, blue = -1;
|
||||
int is_color = 0;
|
||||
|
||||
@@ -821,25 +977,26 @@ 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 && !msg_command && !is_queued) {
|
||||
DidMsgReminder = 1;
|
||||
if (!DoSubstFromString(DBufValue(&Banner), &buf,
|
||||
JulianToday, NO_TIME) &&
|
||||
DSEToday, NO_TIME) &&
|
||||
DBufLen(&buf)) {
|
||||
printf("%s\n", DBufValue(&buf));
|
||||
}
|
||||
printf("%s\n", DBufValue(&buf));
|
||||
}
|
||||
DBufFree(&buf);
|
||||
}
|
||||
|
||||
/* If it's NextMode, process as a ADVANCE_MODE-type entry, and issue
|
||||
simple-calendar format. */
|
||||
if (NextMode) {
|
||||
if ( (r=DoSubst(p, &buf, t, tim, jul, ADVANCE_MODE)) ) return r;
|
||||
if ( (r=DoSubst(p, &buf, t, tim, dse, ADVANCE_MODE)) ) return r;
|
||||
if (!DBufLen(&buf)) {
|
||||
DBufFree(&buf);
|
||||
DBufFree(&pre_buf);
|
||||
return OK;
|
||||
}
|
||||
FromJulian(jul, &y, &m, &d);
|
||||
FromDSE(dse, &y, &m, &d);
|
||||
sprintf(tmpBuf, "%04d/%02d/%02d ", y, m+1, d);
|
||||
if (DBufPuts(&calRow, tmpBuf) != OK) {
|
||||
DBufFree(&calRow);
|
||||
@@ -887,11 +1044,18 @@ int TriggerReminder(ParsePtr p, Trigger *t, TimeTrig *tim, int jul)
|
||||
return E_NO_MEM;
|
||||
}
|
||||
|
||||
printf("%s%s%s\n", DBufValue(&calRow), DBufValue(&pre_buf), DBufValue(&buf));
|
||||
r = OK;
|
||||
if (output) {
|
||||
if (DBufPuts(output, DBufValue(&calRow)) != OK) r = E_NO_MEM;
|
||||
if (DBufPuts(output, DBufValue(&pre_buf)) != OK) r = E_NO_MEM;
|
||||
if (DBufPuts(output, DBufValue(&buf)) != OK) r = E_NO_MEM;
|
||||
} else {
|
||||
printf("%s%s%s\n", DBufValue(&calRow), DBufValue(&pre_buf), DBufValue(&buf));
|
||||
}
|
||||
DBufFree(&buf);
|
||||
DBufFree(&pre_buf);
|
||||
DBufFree(&calRow);
|
||||
return OK;
|
||||
return r;
|
||||
}
|
||||
|
||||
/* Correct colors */
|
||||
@@ -922,7 +1086,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);
|
||||
@@ -936,9 +1100,9 @@ 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 ( (r=DoSubst(p, &buf, t, tim, dse, NORMAL_MODE)) ) return r;
|
||||
if (t->typ != RUN_TYPE) {
|
||||
if (UserFuncExists("msgsuffix") == 1) {
|
||||
sprintf(PrioExpr, "msgsuffix(%d)", t->priority);
|
||||
@@ -947,7 +1111,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);
|
||||
@@ -961,10 +1125,10 @@ 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) {
|
||||
if ((!msg_command && t->typ == MSG_TYPE) || t->typ == MSF_TYPE) {
|
||||
if (DBufPutc(&buf, '\n') != OK) {
|
||||
DBufFree(&buf);
|
||||
return E_NO_MEM;
|
||||
@@ -973,7 +1137,7 @@ int TriggerReminder(ParsePtr p, Trigger *t, TimeTrig *tim, int jul)
|
||||
|
||||
/* If we are sorting, just queue it up in the sort buffer */
|
||||
if (SortByDate) {
|
||||
if (InsertIntoSortBuffer(jul, tim->ttime, DBufValue(&buf),
|
||||
if (InsertIntoSortBuffer(dse, tim->ttime, DBufValue(&buf),
|
||||
t->typ, t->priority) == OK) {
|
||||
DBufFree(&buf);
|
||||
NumTriggered++;
|
||||
@@ -986,19 +1150,28 @@ int TriggerReminder(ParsePtr p, Trigger *t, TimeTrig *tim, int jul)
|
||||
switch(t->typ) {
|
||||
case MSG_TYPE:
|
||||
case PASSTHRU_TYPE:
|
||||
if (MsgCommand) {
|
||||
DoMsgCommand(MsgCommand, DBufValue(&buf));
|
||||
if (msg_command) {
|
||||
DoMsgCommand(msg_command, DBufValue(&buf), is_queued);
|
||||
} else {
|
||||
printf("%s", DBufValue(&buf));
|
||||
if (output) {
|
||||
DBufPuts(output, DBufValue(&buf));
|
||||
} else {
|
||||
/* Add a space before "NOTE endreminder" */
|
||||
if (IsServerMode() && !strncmp(DBufValue(&buf), "NOTE endreminder", 16)) {
|
||||
printf(" %s", DBufValue(&buf));
|
||||
} else {
|
||||
printf("%s", DBufValue(&buf));
|
||||
}
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
case MSF_TYPE:
|
||||
FillParagraph(DBufValue(&buf));
|
||||
FillParagraph(DBufValue(&buf), output);
|
||||
break;
|
||||
|
||||
case RUN_TYPE:
|
||||
System(DBufValue(&buf));
|
||||
System(DBufValue(&buf), is_queued);
|
||||
break;
|
||||
|
||||
default: /* Unknown/illegal type? */
|
||||
@@ -1020,24 +1193,24 @@ int TriggerReminder(ParsePtr p, Trigger *t, TimeTrig *tim, int jul)
|
||||
/* triggered. Sets *err non-zero in event of an error. */
|
||||
/* */
|
||||
/***************************************************************/
|
||||
int ShouldTriggerReminder(Trigger *t, TimeTrig *tim, int jul, int *err)
|
||||
int ShouldTriggerReminder(Trigger *t, TimeTrig *tim, int dse, int *err)
|
||||
{
|
||||
int r, omit;
|
||||
*err = 0;
|
||||
|
||||
/* Handle the ONCE modifier in the reminder. */
|
||||
if (!IgnoreOnce && t->once !=NO_ONCE && FileAccessDate == JulianToday)
|
||||
if (!IgnoreOnce && t->once !=NO_ONCE && FileAccessDate == DSEToday)
|
||||
return 0;
|
||||
|
||||
if (jul < JulianToday) return 0;
|
||||
if (dse < DSEToday) return 0;
|
||||
|
||||
/* Don't trigger timed reminders if DontIssueAts is true, and if the
|
||||
reminder is for today */
|
||||
if (jul == JulianToday && DontIssueAts && tim->ttime != NO_TIME) {
|
||||
if (dse == DSEToday && DontIssueAts && tim->ttime != NO_TIME) {
|
||||
if (DontIssueAts > 1) {
|
||||
/* If two or more -a options, then *DO* issue ats that are in the
|
||||
future */
|
||||
if (tim->ttime < SystemTime(0) / 60) {
|
||||
if (tim->ttime < MinutesPastMidnight(0)) {
|
||||
return 0;
|
||||
}
|
||||
} else {
|
||||
@@ -1045,41 +1218,43 @@ int ShouldTriggerReminder(Trigger *t, TimeTrig *tim, int jul, int *err)
|
||||
}
|
||||
}
|
||||
|
||||
/* Don't trigger "old" timed reminders */
|
||||
/*** REMOVED...
|
||||
if (jul == JulianToday &&
|
||||
tim->ttime != NO_TIME &&
|
||||
tim->ttime < SystemTime(0) / 60) return 0;
|
||||
*** ...UNTIL HERE */
|
||||
|
||||
/* If "infinite delta" option is chosen, always trigger future reminders */
|
||||
if (InfiniteDelta || NextMode) return 1;
|
||||
|
||||
/* If there's a "warn" function, it overrides any deltas */
|
||||
/* If there's a "warn" function, it overrides any deltas except
|
||||
* DeltaOverride*/
|
||||
if (t->warn[0] != 0) {
|
||||
if (DeltaOffset) {
|
||||
if (jul <= JulianToday + DeltaOffset) {
|
||||
if (DeltaOverride > 0) {
|
||||
if (dse <= DSEToday + DeltaOverride) {
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
return ShouldTriggerBasedOnWarn(t, jul, err);
|
||||
return ShouldTriggerBasedOnWarn(t, dse, err);
|
||||
}
|
||||
|
||||
/* Zero delta */
|
||||
if (DeltaOverride < 0) {
|
||||
return dse == DSEToday;
|
||||
}
|
||||
|
||||
/* Move back by delta days, if any */
|
||||
if (t->delta != NO_DELTA) {
|
||||
if (t->delta < 0)
|
||||
jul = jul + t->delta;
|
||||
if (DeltaOverride) {
|
||||
/* A positive DeltaOverride takes precedence over everything */
|
||||
dse = dse - DeltaOverride;
|
||||
} else if (t->delta != NO_DELTA) {
|
||||
if (t->delta < 0)
|
||||
dse = dse + t->delta;
|
||||
else {
|
||||
int iter = 0;
|
||||
int max = MaxSatIter;
|
||||
r = t->delta;
|
||||
if (max < r*2) max = r*2;
|
||||
while(iter++ < max) {
|
||||
if (!r || (jul <= JulianToday)) {
|
||||
if (!r || (dse <= DSEToday)) {
|
||||
break;
|
||||
}
|
||||
jul--;
|
||||
*err = IsOmitted(jul, t->localomit, t->omitfunc, &omit);
|
||||
dse--;
|
||||
*err = IsOmitted(dse, t->localomit, t->omitfunc, &omit);
|
||||
if (*err) return 0;
|
||||
if (!omit) r--;
|
||||
}
|
||||
@@ -1092,7 +1267,7 @@ int ShouldTriggerReminder(Trigger *t, TimeTrig *tim, int jul, int *err)
|
||||
}
|
||||
|
||||
/* Should we trigger the reminder? */
|
||||
return (jul <= JulianToday + DeltaOffset);
|
||||
return (dse <= DSEToday);
|
||||
}
|
||||
|
||||
/***************************************************************/
|
||||
@@ -1104,7 +1279,7 @@ int ShouldTriggerReminder(Trigger *t, TimeTrig *tim, int jul, int *err)
|
||||
/***************************************************************/
|
||||
int DoSatRemind(Trigger *trig, TimeTrig *tt, ParsePtr p)
|
||||
{
|
||||
int iter, jul, r, start;
|
||||
int iter, dse, r, start;
|
||||
Value v;
|
||||
char const *s;
|
||||
char const *t;
|
||||
@@ -1113,25 +1288,25 @@ int DoSatRemind(Trigger *trig, TimeTrig *tt, ParsePtr p)
|
||||
iter = 0;
|
||||
start = trig->scanfrom;
|
||||
while (iter++ < MaxSatIter) {
|
||||
jul = ComputeTriggerNoAdjustDuration(start, trig, tt, &r, 1, 0);
|
||||
dse = ComputeTriggerNoAdjustDuration(start, trig, tt, &r, 1, 0);
|
||||
if (r) {
|
||||
if (r == E_CANT_TRIG) return OK; else return r;
|
||||
}
|
||||
if (jul != start && trig->duration_days) {
|
||||
jul = ComputeTriggerNoAdjustDuration(start, trig, tt, &r, 1, trig->duration_days);
|
||||
if (dse != start && trig->duration_days) {
|
||||
dse = ComputeTriggerNoAdjustDuration(start, trig, tt, &r, 1, trig->duration_days);
|
||||
if (r) {
|
||||
if (r == E_CANT_TRIG) return OK; else return r;
|
||||
}
|
||||
} else if (jul == start) {
|
||||
} else if (dse == start) {
|
||||
if (tt->ttime != NO_TIME) {
|
||||
trig->eventstart = MINUTES_PER_DAY * r + tt->ttime;
|
||||
if (tt->duration != NO_TIME) {
|
||||
trig->eventduration = tt->duration;
|
||||
}
|
||||
}
|
||||
SaveAllTriggerInfo(trig, tt, jul, tt->ttime, 1);
|
||||
SaveAllTriggerInfo(trig, tt, dse, tt->ttime, 1);
|
||||
}
|
||||
if (jul == -1) {
|
||||
if (dse == -1) {
|
||||
return E_EXPIRED;
|
||||
}
|
||||
s = p->pos;
|
||||
@@ -1141,15 +1316,15 @@ int DoSatRemind(Trigger *trig, TimeTrig *tt, ParsePtr p)
|
||||
if (v.type != INT_TYPE && v.type != STR_TYPE) return E_BAD_TYPE;
|
||||
if ((v.type == INT_TYPE && v.v.val) ||
|
||||
(v.type == STR_TYPE && *v.v.str)) {
|
||||
AdjustTriggerForDuration(trig->scanfrom, jul, trig, tt, 1);
|
||||
AdjustTriggerForDuration(trig->scanfrom, dse, trig, tt, 1);
|
||||
if (DebugFlag & DB_PRTTRIG) {
|
||||
int y, m, d;
|
||||
FromJulian(LastTriggerDate, &y, &m, &d);
|
||||
FromDSE(LastTriggerDate, &y, &m, &d);
|
||||
fprintf(ErrFp, "%s(%d): Trig(satisfied) = %s, %d %s, %d",
|
||||
FileName, LineNo,
|
||||
DayName[LastTriggerDate % 7],
|
||||
get_day_name(LastTriggerDate % 7),
|
||||
d,
|
||||
MonthName[m],
|
||||
get_month_name(m),
|
||||
y);
|
||||
if (tt->ttime != NO_TIME) {
|
||||
fprintf(ErrFp, " AT %02d:%02d",
|
||||
@@ -1166,10 +1341,10 @@ int DoSatRemind(Trigger *trig, TimeTrig *tt, ParsePtr p)
|
||||
return OK;
|
||||
}
|
||||
p->pos = s;
|
||||
if (jul+trig->duration_days < start) {
|
||||
if (dse+trig->duration_days < start) {
|
||||
start++;
|
||||
} else {
|
||||
start = jul+trig->duration_days+1;
|
||||
start = dse+trig->duration_days+1;
|
||||
}
|
||||
}
|
||||
p->pos = t;
|
||||
@@ -1223,31 +1398,23 @@ static int ParsePriority(ParsePtr s, Trigger *t)
|
||||
/* Execute the '-k' command, escaping shell chars in message. */
|
||||
/* */
|
||||
/***************************************************************/
|
||||
int DoMsgCommand(char const *cmd, char const *msg)
|
||||
int DoMsgCommand(char const *cmd, char const *msg, int is_queued)
|
||||
{
|
||||
int r;
|
||||
int i, l;
|
||||
DynamicBuffer execBuffer;
|
||||
|
||||
DynamicBuffer buf;
|
||||
char const *s;
|
||||
|
||||
DBufInit(&buf);
|
||||
DBufInit(&execBuffer);
|
||||
|
||||
/* Escape shell characters in msg INCLUDING WHITESPACE! */
|
||||
for (s=msg; *s; s++) {
|
||||
if (isspace(*s) || !strchr(DontEscapeMe, *s)) {
|
||||
if (DBufPutc(&buf, '\\') != OK) {
|
||||
r = E_NO_MEM;
|
||||
goto finished;
|
||||
}
|
||||
}
|
||||
if (DBufPutc(&buf, *s) != OK) {
|
||||
r = E_NO_MEM;
|
||||
goto finished;
|
||||
}
|
||||
/* Escape shell characters in msg */
|
||||
if (ShellEscape(msg, &buf) != OK) {
|
||||
r = E_NO_MEM;
|
||||
goto finished;
|
||||
}
|
||||
|
||||
msg = DBufValue(&buf);
|
||||
|
||||
/* Do "%s" substitution */
|
||||
@@ -1268,7 +1435,7 @@ int DoMsgCommand(char const *cmd, char const *msg)
|
||||
}
|
||||
r = OK;
|
||||
|
||||
System(DBufValue(&execBuffer));
|
||||
System(DBufValue(&execBuffer), is_queued);
|
||||
|
||||
finished:
|
||||
DBufFree(&buf);
|
||||
@@ -1284,7 +1451,7 @@ finished:
|
||||
/* function. */
|
||||
/* */
|
||||
/***************************************************************/
|
||||
static int ShouldTriggerBasedOnWarn(Trigger *t, int jul, int *err)
|
||||
static int ShouldTriggerBasedOnWarn(Trigger *t, int dse, int *err)
|
||||
{
|
||||
char buffer[VAR_NAME_LEN+32];
|
||||
int i;
|
||||
@@ -1296,7 +1463,7 @@ static int ShouldTriggerBasedOnWarn(Trigger *t, int jul, int *err)
|
||||
/* If no proper function exists, barf... */
|
||||
if (UserFuncExists(t->warn) != 1) {
|
||||
Eprint("%s: `%s'", ErrMsg[M_BAD_WARN_FUNC], t->warn);
|
||||
return (jul == JulianToday);
|
||||
return (dse == DSEToday);
|
||||
}
|
||||
for (i=1; ; i++) {
|
||||
sprintf(buffer, "%s(%d)", t->warn, i);
|
||||
@@ -1305,28 +1472,28 @@ static int ShouldTriggerBasedOnWarn(Trigger *t, int jul, int *err)
|
||||
if (r) {
|
||||
Eprint("%s: `%s': %s", ErrMsg[M_BAD_WARN_FUNC],
|
||||
t->warn, ErrMsg[r]);
|
||||
return (jul == JulianToday);
|
||||
return (dse == DSEToday);
|
||||
}
|
||||
if (v.type != INT_TYPE) {
|
||||
DestroyValue(v);
|
||||
Eprint("%s: `%s': %s", ErrMsg[M_BAD_WARN_FUNC],
|
||||
t->warn, ErrMsg[E_BAD_TYPE]);
|
||||
return (jul == JulianToday);
|
||||
return (dse == DSEToday);
|
||||
}
|
||||
|
||||
/* If absolute value of return is not monotonically
|
||||
decreasing, exit */
|
||||
if (i > 1 && abs(v.v.val) >= lastReturnVal) {
|
||||
return (jul == JulianToday);
|
||||
return (dse == DSEToday);
|
||||
}
|
||||
|
||||
lastReturnVal = abs(v.v.val);
|
||||
/* Positive values: Just subtract. Negative values:
|
||||
skip omitted days. */
|
||||
if (v.v.val >= 0) {
|
||||
if (JulianToday + v.v.val == jul) return 1;
|
||||
if (DSEToday + v.v.val == dse) return 1;
|
||||
} else {
|
||||
int j = jul;
|
||||
int j = dse;
|
||||
int iter = 0;
|
||||
int max = MaxSatIter;
|
||||
if (max < v.v.val * 2) max = v.v.val*2;
|
||||
@@ -1343,7 +1510,29 @@ static int ShouldTriggerBasedOnWarn(Trigger *t, int jul, int *err)
|
||||
Eprint("Delta: Bad OMITFUNC? %s", ErrMsg[E_CANT_TRIG]);
|
||||
return 0;
|
||||
}
|
||||
if (j == JulianToday) return 1;
|
||||
if (j == DSEToday) return 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void FixSpecialType(Trigger *t)
|
||||
{
|
||||
if (t->typ != PASSTHRU_TYPE) {
|
||||
return;
|
||||
}
|
||||
|
||||
/* Convert SPECIAL MSG / MSF / RUN / CAL to just plain MSG / MSF / etc */
|
||||
if (!StrCmpi(t->passthru, "MSG")) {
|
||||
t->typ = MSG_TYPE;
|
||||
} else if (!StrCmpi(t->passthru, "MSF")) {
|
||||
t->typ = MSF_TYPE;
|
||||
} else if (!StrCmpi(t->passthru, "RUN")) {
|
||||
t->typ = RUN_TYPE;
|
||||
} else if (!StrCmpi(t->passthru, "CAL")) {
|
||||
t->typ = CAL_TYPE;
|
||||
} else if (!StrCmpi(t->passthru, "PS")) {
|
||||
t->typ = PS_TYPE;
|
||||
} else if (!StrCmpi(t->passthru, "PSFILE")) {
|
||||
t->typ = PSF_TYPE;
|
||||
}
|
||||
}
|
||||
|
||||
804
src/dosubst.c
804
src/dosubst.c
File diff suppressed because it is too large
Load Diff
@@ -6,7 +6,8 @@
|
||||
/* buffers. */
|
||||
/* */
|
||||
/* This file is part of REMIND. */
|
||||
/* Copyright (C) 1992-2020 by Dianne Skoll */
|
||||
/* Copyright (C) 1992-2024 by Dianne Skoll */
|
||||
/* SPDX-License-Identifier: GPL-2.0-only */
|
||||
/* */
|
||||
/***************************************************************/
|
||||
|
||||
@@ -27,11 +28,11 @@
|
||||
Doubles the size of dynamic buffer until it has room for at least
|
||||
'n' characters, not including trailing '\0'
|
||||
**********************************************************************/
|
||||
static int DBufMakeRoom(DynamicBuffer *dbuf, int n)
|
||||
static int DBufMakeRoom(DynamicBuffer *dbuf, size_t n)
|
||||
{
|
||||
/* Double size until it's greater than n (strictly > to leave room
|
||||
for trailing '\0' */
|
||||
int size = dbuf->allocatedLen;
|
||||
size_t size = dbuf->allocatedLen;
|
||||
char *buf;
|
||||
|
||||
if (size > n) return OK;
|
||||
|
||||
11
src/dynbuf.h
11
src/dynbuf.h
@@ -5,7 +5,8 @@
|
||||
/* Declaration of functions for manipulating dynamic buffers */
|
||||
/* */
|
||||
/* This file is part of REMIND. */
|
||||
/* Copyright (C) 1992-2020 by Dianne Skoll */
|
||||
/* Copyright (C) 1992-2024 by Dianne Skoll */
|
||||
/* SPDX-License-Identifier: GPL-2.0-only */
|
||||
/* */
|
||||
/***************************************************************/
|
||||
|
||||
@@ -17,8 +18,8 @@
|
||||
#define DBUF_STATIC_SIZE 128
|
||||
typedef struct {
|
||||
char *buffer;
|
||||
int len;
|
||||
int allocatedLen;
|
||||
size_t len;
|
||||
size_t allocatedLen;
|
||||
char staticBuf[DBUF_STATIC_SIZE];
|
||||
} DynamicBuffer;
|
||||
|
||||
@@ -31,6 +32,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 */
|
||||
|
||||
17
src/err.h
17
src/err.h
@@ -5,7 +5,8 @@
|
||||
/* Error definitions. */
|
||||
/* */
|
||||
/* This file is part of REMIND. */
|
||||
/* Copyright (C) 1992-2020 by Dianne Skoll */
|
||||
/* Copyright (C) 1992-2024 by Dianne Skoll */
|
||||
/* SPDX-License-Identifier: GPL-2.0-only */
|
||||
/* */
|
||||
/***************************************************************/
|
||||
|
||||
@@ -70,7 +71,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
|
||||
@@ -128,6 +129,10 @@
|
||||
#define EXTERN extern
|
||||
#endif
|
||||
|
||||
#define STR(X) STR2(X)
|
||||
#define STR2(X) #X
|
||||
|
||||
|
||||
#ifndef L_ERR_OVERRIDE
|
||||
EXTERN char *ErrMsg[]
|
||||
|
||||
@@ -164,7 +169,7 @@ EXTERN char *ErrMsg[]
|
||||
"Number too high",
|
||||
"Number too low",
|
||||
"Can't open file",
|
||||
"INCLUDE nested too deeply",
|
||||
"INCLUDE nested too deeply (max. " STR(INCLUDE_NEST) ")",
|
||||
"Parse error",
|
||||
"Can't compute trigger",
|
||||
"Too many nested IFs",
|
||||
@@ -187,9 +192,9 @@ EXTERN char *ErrMsg[]
|
||||
"Month specified twice",
|
||||
"Day specified twice",
|
||||
"Unknown token",
|
||||
"Must specify month and day in OMIT command",
|
||||
"Too many partial OMITs",
|
||||
"Too many full OMITs",
|
||||
"Must specify month in OMIT command",
|
||||
"Too many partial OMITs (max. " STR(MAX_PARTIAL_OMITS) ")",
|
||||
"Too many full OMITs (max. " STR(MAX_FULL_OMITS) ")",
|
||||
"Warning: PUSH-OMIT-CONTEXT without matching POP-OMIT-CONTEXT",
|
||||
"Error reading",
|
||||
"Expecting end-of-line",
|
||||
|
||||
267
src/expr.c
267
src/expr.c
@@ -5,7 +5,8 @@
|
||||
/* This file contains routines to parse and evaluate */
|
||||
/* expressions. */
|
||||
/* */
|
||||
/* Copyright 1992-2020 by Dianne Skoll */
|
||||
/* Copyright 1992-2024 by Dianne Skoll */
|
||||
/* SPDX-License-Identifier: GPL-2.0-only */
|
||||
/* */
|
||||
/***************************************************************/
|
||||
|
||||
@@ -13,6 +14,7 @@
|
||||
#include <stdio.h>
|
||||
#include <ctype.h>
|
||||
#include <string.h>
|
||||
#include <limits.h>
|
||||
|
||||
#include <stdlib.h>
|
||||
|
||||
@@ -43,21 +45,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 },
|
||||
};
|
||||
@@ -65,16 +78,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;
|
||||
|
||||
/***************************************************************/
|
||||
/* */
|
||||
@@ -100,7 +116,7 @@ static int DebugPerform(Operator *op)
|
||||
fprintf(ErrFp, " => ");
|
||||
if (!r) {
|
||||
PrintValue(&ValStack[ValStackPtr-1], ErrFp);
|
||||
Putc('\n', ErrFp);
|
||||
putc('\n', ErrFp);
|
||||
} else {
|
||||
fprintf(ErrFp, "%s\n", ErrMsg[r]);
|
||||
}
|
||||
@@ -114,12 +130,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;
|
||||
}
|
||||
|
||||
/***************************************************************/
|
||||
@@ -237,6 +254,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)++;
|
||||
@@ -305,8 +326,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);
|
||||
|
||||
@@ -315,11 +336,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;
|
||||
}
|
||||
|
||||
@@ -351,12 +376,10 @@ int Evaluate(char const **s, Var *locals, ParsePtr p)
|
||||
DBufFree(&ExprBuf);
|
||||
r = Evaluate(s, locals, p); /* Leaves the last parsed token in ExprBuf */
|
||||
if (r) return r;
|
||||
r = OK;
|
||||
if (*DBufValue(&ExprBuf) != ')') {
|
||||
if (*DBufValue(&ExprBuf) != ')') {
|
||||
DBufFree(&ExprBuf);
|
||||
return E_MISS_RIGHT_PAREN;
|
||||
}
|
||||
if (r) return r;
|
||||
} else if (*DBufValue(&ExprBuf) == '+') {
|
||||
continue; /* Ignore unary + */
|
||||
}
|
||||
@@ -493,6 +516,7 @@ static int MakeValue(char const *s, Value *v, Var *locals, ParsePtr p)
|
||||
int len;
|
||||
int h, m, r;
|
||||
int ampm = 0;
|
||||
int prev_val;
|
||||
|
||||
if (*s == '\"') { /* It's a literal string "*/
|
||||
len = strlen(s)-1;
|
||||
@@ -519,9 +543,15 @@ static int MakeValue(char const *s, Value *v, Var *locals, ParsePtr p)
|
||||
return OK;
|
||||
} else if (isdigit(*s)) { /* It's a number - use len to hold it.*/
|
||||
len = 0;
|
||||
prev_val = 0;
|
||||
while (*s && isdigit(*s)) {
|
||||
len *= 10;
|
||||
len += (*s++ - '0');
|
||||
if (len < prev_val) {
|
||||
/* We overflowed */
|
||||
return E_2HIGH;
|
||||
}
|
||||
prev_val = len;
|
||||
}
|
||||
if (*s == ':' || *s == '.' || *s == TimeSep) { /* Must be a literal time */
|
||||
s++;
|
||||
@@ -572,7 +602,7 @@ static int MakeValue(char const *s, Value *v, Var *locals, ParsePtr p)
|
||||
if (! (DebugFlag & DB_PRTEXPR)) return r;
|
||||
if (r == OK) {
|
||||
PrintValue(v, ErrFp);
|
||||
Putc('\n', ErrFp);
|
||||
putc('\n', ErrFp);
|
||||
}
|
||||
return r;
|
||||
} else { /* Must be a symbol */
|
||||
@@ -583,7 +613,7 @@ static int MakeValue(char const *s, Value *v, Var *locals, ParsePtr p)
|
||||
if (! (DebugFlag & DB_PRTEXPR)) return r;
|
||||
if (r == OK) {
|
||||
PrintValue(v, ErrFp);
|
||||
Putc('\n', ErrFp);
|
||||
putc('\n', ErrFp);
|
||||
}
|
||||
return r;
|
||||
}
|
||||
@@ -631,13 +661,13 @@ int DoCoerce(char type, Value *v)
|
||||
case TIME_TYPE: sprintf(coerce_buf, "%02d%c%02d", v->v.val / 60,
|
||||
TimeSep, v->v.val % 60);
|
||||
break;
|
||||
case DATE_TYPE: FromJulian(v->v.val, &y, &m, &d);
|
||||
case DATE_TYPE: FromDSE(v->v.val, &y, &m, &d);
|
||||
sprintf(coerce_buf, "%04d%c%02d%c%02d",
|
||||
y, DateSep, m+1, DateSep, d);
|
||||
break;
|
||||
case DATETIME_TYPE:
|
||||
i = v->v.val / MINUTES_PER_DAY;
|
||||
FromJulian(i, &y, &m, &d);
|
||||
FromDSE(i, &y, &m, &d);
|
||||
k = v->v.val % MINUTES_PER_DAY;
|
||||
h = k / 60;
|
||||
i = k % 60;
|
||||
@@ -758,14 +788,19 @@ static int Add(void)
|
||||
|
||||
/* If both are ints, just add 'em */
|
||||
if (v2.type == INT_TYPE && v1.type == INT_TYPE) {
|
||||
v2.v.val += v1.v.val;
|
||||
PushValStack(v2);
|
||||
/* Check for overflow */
|
||||
if (_private_add_overflow(v1.v.val, v2.v.val)) {
|
||||
return E_2HIGH;
|
||||
}
|
||||
v1.v.val += v2.v.val;
|
||||
PushValStack(v1);
|
||||
return OK;
|
||||
}
|
||||
|
||||
/* 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)) {
|
||||
if (_private_add_overflow(v1.v.val, v2.v.val)) return E_DATE_OVER;
|
||||
v1.v.val += v2.v.val;
|
||||
if (v1.v.val < 0) return E_DATE_OVER;
|
||||
v1.type = DATE_TYPE;
|
||||
@@ -776,6 +811,7 @@ 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)) {
|
||||
if (_private_add_overflow(v1.v.val, v2.v.val)) return E_DATE_OVER;
|
||||
v1.v.val += v2.v.val;
|
||||
if (v1.v.val < 0) return E_DATE_OVER;
|
||||
v1.type = DATETIME_TYPE;
|
||||
@@ -788,7 +824,9 @@ 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)) {
|
||||
v1.v.val = (v1.v.val + v2.v.val) % MINUTES_PER_DAY;
|
||||
if (_private_add_overflow(v1.v.val, v2.v.val)) return E_DATE_OVER;
|
||||
v1.v.val += v2.v.val;
|
||||
v1.v.val = v1.v.val % MINUTES_PER_DAY;
|
||||
if (v1.v.val < 0) v1.v.val += MINUTES_PER_DAY;
|
||||
v1.type = TIME_TYPE;
|
||||
PushValStack(v1);
|
||||
@@ -808,7 +846,7 @@ static int Add(void)
|
||||
v3.type = STR_TYPE;
|
||||
l1 = strlen(v1.v.str);
|
||||
l2 = strlen(v2.v.str);
|
||||
if (MaxStringLen && (l1 + l2 > (size_t) MaxStringLen)) {
|
||||
if (MaxStringLen > 0 && (l1 + l2 > (size_t) MaxStringLen)) {
|
||||
DestroyValue(v1); DestroyValue(v2);
|
||||
return E_STRING_TOO_LONG;
|
||||
}
|
||||
@@ -848,6 +886,7 @@ static int Subtract(void)
|
||||
|
||||
/* If they're both INTs, do subtraction */
|
||||
if (v1.type == INT_TYPE && v2.type == INT_TYPE) {
|
||||
if (_private_sub_overflow(v1.v.val, v2.v.val)) return E_2HIGH;
|
||||
v1.v.val -= v2.v.val;
|
||||
PushValStack(v1);
|
||||
return OK;
|
||||
@@ -855,6 +894,7 @@ static int Subtract(void)
|
||||
|
||||
/* If it's a date minus an int, do subtraction, checking for underflow */
|
||||
if (v1.type == DATE_TYPE && v2.type == INT_TYPE) {
|
||||
if (_private_sub_overflow(v1.v.val, v2.v.val)) return E_DATE_OVER;
|
||||
v1.v.val -= v2.v.val;
|
||||
if (v1.v.val < 0) return E_DATE_OVER;
|
||||
PushValStack(v1);
|
||||
@@ -864,6 +904,7 @@ 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)) {
|
||||
if (_private_sub_overflow(v1.v.val, v2.v.val)) return E_DATE_OVER;
|
||||
v1.v.val -= v2.v.val;
|
||||
if (v1.v.val < 0) return E_DATE_OVER;
|
||||
PushValStack(v1);
|
||||
@@ -882,6 +923,7 @@ 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)) {
|
||||
if (_private_sub_overflow(v1.v.val, v2.v.val)) return E_DATE_OVER;
|
||||
v1.v.val -= v2.v.val;
|
||||
v1.type = INT_TYPE;
|
||||
PushValStack(v1);
|
||||
@@ -902,7 +944,8 @@ static int Subtract(void)
|
||||
/***************************************************************/
|
||||
static int Multiply(void)
|
||||
{
|
||||
Value v1, v2;
|
||||
Value v1, v2, v3;
|
||||
char *ptr;
|
||||
int r;
|
||||
|
||||
PopValStack(v2);
|
||||
@@ -912,10 +955,71 @@ static int Multiply(void)
|
||||
}
|
||||
|
||||
if (v1.type == INT_TYPE && v2.type == INT_TYPE) {
|
||||
/* Prevent floating-point exception */
|
||||
if ((v2.v.val == -1 && v1.v.val == INT_MIN) ||
|
||||
(v1.v.val == -1 && v2.v.val == INT_MIN)) {
|
||||
return E_2HIGH;
|
||||
}
|
||||
if (_private_mul_overflow(v1.v.val, v2.v.val)) return E_2HIGH;
|
||||
v1.v.val *= v2.v.val;
|
||||
PushValStack(v1);
|
||||
return OK;
|
||||
}
|
||||
|
||||
/* String times int means repeat the string that many times */
|
||||
if ((v1.type == INT_TYPE && v2.type == STR_TYPE) ||
|
||||
(v1.type == STR_TYPE && v2.type == INT_TYPE)) {
|
||||
int rep = (v1.type == INT_TYPE ? v1.v.val : v2.v.val);
|
||||
char const *str = (v1.type == INT_TYPE ? v2.v.str : v1.v.str);
|
||||
int l;
|
||||
|
||||
/* Can't multiply by a negative number */
|
||||
if (rep < 0) {
|
||||
return E_2LOW;
|
||||
}
|
||||
if (rep == 0 || !str || !*str) {
|
||||
/* Empty string */
|
||||
DestroyValue(v1); DestroyValue(v2);
|
||||
v3.type = STR_TYPE;
|
||||
v3.v.str = malloc(1);
|
||||
if (!v3.v.str) {
|
||||
return E_NO_MEM;
|
||||
}
|
||||
*v3.v.str = 0;
|
||||
PushValStack(v3);
|
||||
return OK;
|
||||
}
|
||||
|
||||
/* Create the new value */
|
||||
l = (int) strlen(str);
|
||||
if (l * rep < 0) {
|
||||
DestroyValue(v1); DestroyValue(v2);
|
||||
return E_STRING_TOO_LONG;
|
||||
}
|
||||
if ((unsigned long) l * (unsigned long) rep >= (unsigned long) INT_MAX) {
|
||||
DestroyValue(v1); DestroyValue(v2);
|
||||
return E_STRING_TOO_LONG;
|
||||
}
|
||||
if (MaxStringLen > 0 && ((unsigned long) l * (unsigned long) rep) > (unsigned long)MaxStringLen) {
|
||||
DestroyValue(v1); DestroyValue(v2);
|
||||
return E_STRING_TOO_LONG;
|
||||
}
|
||||
v3.type = STR_TYPE;
|
||||
v3.v.str = malloc(l * rep + 1);
|
||||
if (!v3.v.str) {
|
||||
DestroyValue(v1); DestroyValue(v2);
|
||||
return E_NO_MEM;
|
||||
}
|
||||
*v3.v.str = 0;
|
||||
ptr = v3.v.str;
|
||||
for (int i=0; i<rep; i++) {
|
||||
strcat(ptr, str);
|
||||
ptr += l;
|
||||
}
|
||||
DestroyValue(v1); DestroyValue(v2);
|
||||
PushValStack(v3);
|
||||
return OK;
|
||||
}
|
||||
DestroyValue(v1); DestroyValue(v2);
|
||||
return E_BAD_TYPE;
|
||||
}
|
||||
@@ -940,6 +1044,10 @@ static int Divide(void)
|
||||
|
||||
if (v1.type == INT_TYPE && v2.type == INT_TYPE) {
|
||||
if (v2.v.val == 0) return E_DIV_ZERO;
|
||||
/* This is the only way it can overflow */
|
||||
if (v2.v.val == -1 && v1.v.val == INT_MIN) {
|
||||
return E_2HIGH;
|
||||
}
|
||||
v1.v.val /= v2.v.val;
|
||||
PushValStack(v1);
|
||||
return OK;
|
||||
@@ -1067,13 +1175,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;
|
||||
}
|
||||
|
||||
/***************************************************************/
|
||||
@@ -1094,13 +1205,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;
|
||||
}
|
||||
|
||||
/***************************************************************/
|
||||
@@ -1114,6 +1227,7 @@ static int UnMinus(void)
|
||||
{
|
||||
Value *v = &ValStack[ValStackPtr-1];
|
||||
if (v->type != INT_TYPE) return E_BAD_TYPE;
|
||||
if (v->v.val == INT_MIN) return E_2HIGH;
|
||||
v->v.val = -v->v.val;
|
||||
return OK;
|
||||
}
|
||||
@@ -1135,9 +1249,9 @@ static int LogNot(void)
|
||||
|
||||
/***************************************************************/
|
||||
/* */
|
||||
/* FindFunc */
|
||||
/* FindOperator */
|
||||
/* */
|
||||
/* Find a function. */
|
||||
/* Find an operator. */
|
||||
/* */
|
||||
/***************************************************************/
|
||||
Operator *FindOperator(char const *name, Operator where[], int num)
|
||||
@@ -1146,7 +1260,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;
|
||||
@@ -1154,6 +1268,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 */
|
||||
@@ -1167,7 +1295,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;
|
||||
@@ -1185,24 +1313,43 @@ 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;
|
||||
Putc('"', fp);
|
||||
for (y=0; y<MAX_PRT_LEN && *s; y++) Putc(*s++, fp);
|
||||
Putc('"',fp);
|
||||
s = (unsigned char const *) v->v.str;
|
||||
putc('"', 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, "...");
|
||||
}
|
||||
else if (v->type == INT_TYPE) fprintf(fp, "%d", v->v.val);
|
||||
else if (v->type == TIME_TYPE) fprintf(fp, "%02d%c%02d", v->v.val / 60,
|
||||
TimeSep, v->v.val % 60);
|
||||
else if (v->type == DATE_TYPE) {
|
||||
FromJulian(v->v.val, &y, &m, &d);
|
||||
FromDSE(v->v.val, &y, &m, &d);
|
||||
fprintf(fp, "%04d%c%02d%c%02d", y, DateSep, m+1, DateSep, d);
|
||||
}
|
||||
else if (v->type == DATETIME_TYPE) {
|
||||
FromJulian(v->v.val / MINUTES_PER_DAY, &y, &m, &d);
|
||||
FromDSE(v->v.val / MINUTES_PER_DAY, &y, &m, &d);
|
||||
fprintf(fp, "%04d%c%02d%c%02d%c%02d%c%02d", y, DateSep, m+1, DateSep, d, DateTimeSep,
|
||||
(v->v.val % MINUTES_PER_DAY) / 60, TimeSep, (v->v.val % MINUTES_PER_DAY) % 60);
|
||||
}
|
||||
@@ -1275,11 +1422,11 @@ int ParseLiteralTime(char const **s, int *tim)
|
||||
/* */
|
||||
/* ParseLiteralDate */
|
||||
/* */
|
||||
/* Parse a literal date or datetime. Return result in jul */
|
||||
/* Parse a literal date or datetime. Return result in dse */
|
||||
/* and tim; update s. */
|
||||
/* */
|
||||
/***************************************************************/
|
||||
int ParseLiteralDate(char const **s, int *jul, int *tim)
|
||||
int ParseLiteralDate(char const **s, int *dse, int *tim)
|
||||
{
|
||||
int y, m, d;
|
||||
int r;
|
||||
@@ -1309,7 +1456,7 @@ int ParseLiteralDate(char const **s, int *jul, int *tim)
|
||||
}
|
||||
if (!DateOK(y, m, d)) return E_BAD_DATE;
|
||||
|
||||
*jul = Julian(y, m, d);
|
||||
*dse = DSE(y, m, d);
|
||||
|
||||
/* Do we have a time part as well? */
|
||||
if (**s == ' ' || **s == '@' || **s == 'T' || **s == 't') {
|
||||
|
||||
27
src/expr.h
27
src/expr.h
@@ -5,18 +5,20 @@
|
||||
/* Contains a few definitions used by expression evaluator. */
|
||||
/* */
|
||||
/* This file is part of REMIND. */
|
||||
/* Copyright (C) 1992-2020 by Dianne Skoll */
|
||||
/* Copyright (C) 1992-2024 by Dianne Skoll */
|
||||
/* SPDX-License-Identifier: GPL-2.0-only */
|
||||
/* */
|
||||
/***************************************************************/
|
||||
|
||||
/* Define the types of values */
|
||||
#define ERR_TYPE 0
|
||||
#define INT_TYPE 1
|
||||
#define TIME_TYPE 2
|
||||
#define DATE_TYPE 3
|
||||
#define STR_TYPE 4
|
||||
#define DATETIME_TYPE 5
|
||||
#define SPECIAL_TYPE 6 /* Only for system variables */
|
||||
#define ERR_TYPE 0
|
||||
#define INT_TYPE 1
|
||||
#define TIME_TYPE 2
|
||||
#define DATE_TYPE 3
|
||||
#define STR_TYPE 4
|
||||
#define DATETIME_TYPE 5
|
||||
#define SPECIAL_TYPE 6 /* Only for system variables */
|
||||
#define CONST_INT_TYPE 7 /* Only for system variables */
|
||||
|
||||
/* Define stuff for parsing expressions */
|
||||
#define BEG_OF_EXPR '['
|
||||
@@ -53,3 +55,12 @@ if (ValStackPtr <= 0) \
|
||||
return E_VA_STK_UNDER; \
|
||||
else \
|
||||
(val) = ValStack[--ValStackPtr]
|
||||
|
||||
/* These functions are in utils.c and are used to detect overflow
|
||||
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_mul_overflow(int a, int b);
|
||||
extern int _private_add_overflow(int a, int b);
|
||||
extern int _private_sub_overflow(int a, int b);
|
||||
|
||||
|
||||
404
src/files.c
404
src/files.c
@@ -7,14 +7,15 @@
|
||||
/* files. */
|
||||
/* */
|
||||
/* This file is part of REMIND. */
|
||||
/* Copyright (C) 1992-2020 by Dianne Skoll */
|
||||
/* Copyright (C) 1992-2024 by Dianne Skoll */
|
||||
/* SPDX-License-Identifier: GPL-2.0-only */
|
||||
/* */
|
||||
/***************************************************************/
|
||||
|
||||
#include "config.h"
|
||||
|
||||
#include <stdio.h>
|
||||
|
||||
#include <fcntl.h>
|
||||
#include <string.h>
|
||||
#include <errno.h>
|
||||
#include <ctype.h>
|
||||
@@ -40,8 +41,9 @@
|
||||
#include "err.h"
|
||||
|
||||
|
||||
/* Convenient macro for closing files */
|
||||
/* Convenient macros for closing files */
|
||||
#define FCLOSE(fp) (((fp)&&((fp)!=stdin)) ? (fclose(fp),(fp)=NULL) : ((fp)=NULL))
|
||||
#define PCLOSE(fp) (((fp)&&((fp)!=stdin)) ? (pclose(fp),(fp)=NULL) : ((fp)=NULL))
|
||||
|
||||
/* Define the structures needed by the file caching system */
|
||||
typedef struct cache {
|
||||
@@ -91,11 +93,24 @@ static FILE *fp;
|
||||
static IncludeStruct IStack[INCLUDE_NEST];
|
||||
static int IStackPtr = 0;
|
||||
|
||||
static int ReadLineFromFile (void);
|
||||
static int CacheFile (char const *fname);
|
||||
static int ReadLineFromFile (int use_pclose);
|
||||
static int CacheFile (char const *fname, int use_pclose);
|
||||
static void DestroyCache (CachedFile *cf);
|
||||
static int CheckSafety (void);
|
||||
static int CheckSafetyAux (struct stat *statbuf);
|
||||
static int PopFile (void);
|
||||
static int IncludeCmd(char const *);
|
||||
|
||||
void set_cloexec(int fd)
|
||||
{
|
||||
int flags;
|
||||
flags = fcntl(fd, F_GETFD);
|
||||
if (flags >= 0) {
|
||||
flags |= FD_CLOEXEC;
|
||||
fcntl(fd, F_SETFD, flags);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static void OpenPurgeFile(char const *fname, char const *mode)
|
||||
{
|
||||
@@ -120,6 +135,7 @@ static void OpenPurgeFile(char const *fname, char const *mode)
|
||||
if (!PurgeFP) {
|
||||
fprintf(ErrFp, "Cannot open `%s' for writing: %s\n", DBufValue(&fname_buf), strerror(errno));
|
||||
}
|
||||
set_cloexec(fileno(PurgeFP));
|
||||
DBufFree(&fname_buf);
|
||||
}
|
||||
|
||||
@@ -162,12 +178,13 @@ int ReadLine(void)
|
||||
LineNo = CLine->LineNo;
|
||||
CLine = CLine->next;
|
||||
FreshLine = 1;
|
||||
clear_callstack();
|
||||
if (DebugFlag & DB_ECHO_LINE) OutputLine(ErrFp);
|
||||
return OK;
|
||||
}
|
||||
|
||||
/* Not cached. Read from the file. */
|
||||
return ReadLineFromFile();
|
||||
return ReadLineFromFile(0);
|
||||
}
|
||||
|
||||
/***************************************************************/
|
||||
@@ -177,7 +194,7 @@ int ReadLine(void)
|
||||
/* Read a line from the file pointed to by fp. */
|
||||
/* */
|
||||
/***************************************************************/
|
||||
static int ReadLineFromFile(void)
|
||||
static int ReadLineFromFile(int use_pclose)
|
||||
{
|
||||
int l;
|
||||
char copy_buffer[4096];
|
||||
@@ -200,7 +217,11 @@ static int ReadLineFromFile(void)
|
||||
return E_IO_ERR;
|
||||
}
|
||||
if (feof(fp)) {
|
||||
FCLOSE(fp);
|
||||
if (use_pclose) {
|
||||
PCLOSE(fp);
|
||||
} else {
|
||||
FCLOSE(fp);
|
||||
}
|
||||
if ((DBufLen(&buf) == 0) &&
|
||||
(DBufLen(&LineBuffer) == 0) && PurgeMode) {
|
||||
if (PurgeFP != NULL && PurgeFP != stdout) fclose(PurgeFP);
|
||||
@@ -248,12 +269,17 @@ static int ReadLineFromFile(void)
|
||||
if (PurgeFP != stdout) fclose(PurgeFP);
|
||||
PurgeFP = NULL;
|
||||
}
|
||||
FCLOSE(fp);
|
||||
if (use_pclose) {
|
||||
PCLOSE(fp);
|
||||
} else {
|
||||
FCLOSE(fp);
|
||||
}
|
||||
DBufFree(&LineBuffer);
|
||||
CurLine = DBufValue(&LineBuffer);
|
||||
}
|
||||
|
||||
FreshLine = 1;
|
||||
clear_callstack();
|
||||
if (DebugFlag & DB_ECHO_LINE) OutputLine(ErrFp);
|
||||
return OK;
|
||||
}
|
||||
@@ -282,9 +308,6 @@ int OpenFile(char const *fname)
|
||||
PurgeFP = NULL;
|
||||
}
|
||||
|
||||
/* Assume we own the file for now */
|
||||
RunDisabled &= ~RUN_NOTOWNER;
|
||||
|
||||
/* If it's in the cache, get it from there. */
|
||||
|
||||
while (h) {
|
||||
@@ -297,7 +320,9 @@ int OpenFile(char const *fname)
|
||||
LineNo = 0;
|
||||
if (!h->ownedByMe) {
|
||||
RunDisabled |= RUN_NOTOWNER;
|
||||
}
|
||||
} else {
|
||||
RunDisabled &= ~RUN_NOTOWNER;
|
||||
}
|
||||
if (FileName) return OK; else return E_NO_MEM;
|
||||
}
|
||||
h = h->next;
|
||||
@@ -306,6 +331,7 @@ int OpenFile(char const *fname)
|
||||
/* If it's a dash, then it's stdin */
|
||||
if (!strcmp(fname, "-")) {
|
||||
fp = stdin;
|
||||
RunDisabled &= ~RUN_NOTOWNER;
|
||||
if (PurgeMode) {
|
||||
PurgeFP = stdout;
|
||||
}
|
||||
@@ -314,6 +340,7 @@ int OpenFile(char const *fname)
|
||||
}
|
||||
} else {
|
||||
fp = fopen(fname, "r");
|
||||
if (fp) set_cloexec(fileno(fp));
|
||||
if (DebugFlag & DB_TRACE_FILES) {
|
||||
fprintf(ErrFp, "Reading `%s': Opening file on disk\n", fname);
|
||||
}
|
||||
@@ -325,7 +352,7 @@ int OpenFile(char const *fname)
|
||||
CLine = NULL;
|
||||
if (ShouldCache) {
|
||||
LineNo = 0;
|
||||
r = CacheFile(fname);
|
||||
r = CacheFile(fname, 0);
|
||||
if (r == OK) {
|
||||
fp = NULL;
|
||||
CLine = CachedFiles->cache;
|
||||
@@ -333,6 +360,7 @@ int OpenFile(char const *fname)
|
||||
if (strcmp(fname, "-")) {
|
||||
fp = fopen(fname, "r");
|
||||
if (!fp || !CheckSafety()) return E_CANT_OPEN;
|
||||
set_cloexec(fileno(fp));
|
||||
if (PurgeMode) OpenPurgeFile(fname, "w");
|
||||
} else {
|
||||
fp = stdin;
|
||||
@@ -353,7 +381,7 @@ int OpenFile(char const *fname)
|
||||
/* Returns an indication of success or failure. */
|
||||
/* */
|
||||
/***************************************************************/
|
||||
static int CacheFile(char const *fname)
|
||||
static int CacheFile(char const *fname, int use_pclose)
|
||||
{
|
||||
int r;
|
||||
CachedFile *cf;
|
||||
@@ -368,14 +396,22 @@ static int CacheFile(char const *fname)
|
||||
cf = NEW(CachedFile);
|
||||
if (!cf) {
|
||||
ShouldCache = 0;
|
||||
FCLOSE(fp);
|
||||
if (use_pclose) {
|
||||
PCLOSE(fp);
|
||||
} else {
|
||||
FCLOSE(fp);
|
||||
}
|
||||
return E_NO_MEM;
|
||||
}
|
||||
cf->cache = NULL;
|
||||
cf->filename = StrDup(fname);
|
||||
if (!cf->filename) {
|
||||
ShouldCache = 0;
|
||||
FCLOSE(fp);
|
||||
if (use_pclose) {
|
||||
PCLOSE(fp);
|
||||
} else {
|
||||
FCLOSE(fp);
|
||||
}
|
||||
free(cf);
|
||||
return E_NO_MEM;
|
||||
}
|
||||
@@ -388,11 +424,15 @@ static int CacheFile(char const *fname)
|
||||
|
||||
/* Read the file */
|
||||
while(fp) {
|
||||
r = ReadLineFromFile();
|
||||
r = ReadLineFromFile(use_pclose);
|
||||
if (r) {
|
||||
DestroyCache(cf);
|
||||
ShouldCache = 0;
|
||||
FCLOSE(fp);
|
||||
if (use_pclose) {
|
||||
PCLOSE(fp);
|
||||
} else {
|
||||
FCLOSE(fp);
|
||||
}
|
||||
return r;
|
||||
}
|
||||
/* Skip blank chars */
|
||||
@@ -406,7 +446,11 @@ static int CacheFile(char const *fname)
|
||||
DBufFree(&LineBuffer);
|
||||
DestroyCache(cf);
|
||||
ShouldCache = 0;
|
||||
FCLOSE(fp);
|
||||
if (use_pclose) {
|
||||
PCLOSE(fp);
|
||||
} else {
|
||||
FCLOSE(fp);
|
||||
}
|
||||
return E_NO_MEM;
|
||||
}
|
||||
cl = cf->cache;
|
||||
@@ -416,7 +460,11 @@ static int CacheFile(char const *fname)
|
||||
DBufFree(&LineBuffer);
|
||||
DestroyCache(cf);
|
||||
ShouldCache = 0;
|
||||
FCLOSE(fp);
|
||||
if (use_pclose) {
|
||||
PCLOSE(fp);
|
||||
} else {
|
||||
FCLOSE(fp);
|
||||
}
|
||||
return E_NO_MEM;
|
||||
}
|
||||
cl = cl->next;
|
||||
@@ -428,7 +476,11 @@ static int CacheFile(char const *fname)
|
||||
if (!cl->text) {
|
||||
DestroyCache(cf);
|
||||
ShouldCache = 0;
|
||||
FCLOSE(fp);
|
||||
if (use_pclose) {
|
||||
PCLOSE(fp);
|
||||
} else {
|
||||
FCLOSE(fp);
|
||||
}
|
||||
return E_NO_MEM;
|
||||
}
|
||||
}
|
||||
@@ -471,9 +523,6 @@ static int PopFile(void)
|
||||
{
|
||||
IncludeStruct *i;
|
||||
|
||||
/* Assume we own the file for now */
|
||||
RunDisabled &= ~RUN_NOTOWNER;
|
||||
|
||||
if (!Hush && NumIfs) Eprint("%s", ErrMsg[E_MISS_ENDIF]);
|
||||
if (!IStackPtr) return E_EOF;
|
||||
i = &IStack[IStackPtr-1];
|
||||
@@ -500,12 +549,15 @@ static int PopFile(void)
|
||||
STRSET(FileName, i->filename);
|
||||
if (!i->ownedByMe) {
|
||||
RunDisabled |= RUN_NOTOWNER;
|
||||
} else {
|
||||
RunDisabled &= ~RUN_NOTOWNER;
|
||||
}
|
||||
if (!CLine && (i->offset != -1L)) {
|
||||
if (!CLine && (i->offset != -1L || !strcmp(i->filename, "-"))) {
|
||||
/* We must open the file, then seek to specified position */
|
||||
if (strcmp(i->filename, "-")) {
|
||||
fp = fopen(i->filename, "r");
|
||||
if (!fp || !CheckSafety()) return E_CANT_OPEN;
|
||||
set_cloexec(fileno(fp));
|
||||
if (PurgeMode) OpenPurgeFile(i->filename, "a");
|
||||
} else {
|
||||
fp = stdin;
|
||||
@@ -525,16 +577,119 @@ static int PopFile(void)
|
||||
/* The INCLUDE command. */
|
||||
/* */
|
||||
/***************************************************************/
|
||||
int DoInclude(ParsePtr p)
|
||||
int DoInclude(ParsePtr p, enum TokTypes tok)
|
||||
{
|
||||
DynamicBuffer buf;
|
||||
DynamicBuffer fullname;
|
||||
DynamicBuffer path;
|
||||
int r, e;
|
||||
|
||||
r = OK;
|
||||
char const *s;
|
||||
DBufInit(&buf);
|
||||
DBufInit(&fullname);
|
||||
DBufInit(&path);
|
||||
if ( (r=ParseToken(p, &buf)) ) return r;
|
||||
e = VerifyEoln(p);
|
||||
if (e) Eprint("%s", ErrMsg[e]);
|
||||
if ( (r=IncludeFile(DBufValue(&buf))) ) {
|
||||
|
||||
if (tok == T_IncludeR && *(DBufValue(&buf)) != '/') {
|
||||
/* Relative include: Include relative to dir
|
||||
containing current file */
|
||||
if (DBufPuts(&path, FileName) != OK) {
|
||||
r = E_NO_MEM;
|
||||
goto bailout;
|
||||
}
|
||||
if (DBufLen(&path) == 0) {
|
||||
s = DBufValue(&buf);
|
||||
} else {
|
||||
char *t = DBufValue(&path) + DBufLen(&path) - 1;
|
||||
while (t > DBufValue(&path) && *t != '/') t--;
|
||||
if (*t == '/') {
|
||||
*t = 0;
|
||||
if (DBufPuts(&fullname, DBufValue(&path)) != OK) {
|
||||
r = E_NO_MEM;
|
||||
goto bailout;
|
||||
}
|
||||
if (DBufPuts(&fullname, "/") != OK) {
|
||||
r = E_NO_MEM;
|
||||
goto bailout;
|
||||
}
|
||||
if (DBufPuts(&fullname, DBufValue(&buf)) != OK) {
|
||||
r = E_NO_MEM;
|
||||
goto bailout;
|
||||
}
|
||||
s = DBufValue(&fullname);
|
||||
} else {
|
||||
s = DBufValue(&buf);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
s = DBufValue(&buf);
|
||||
}
|
||||
if ( (r=IncludeFile(s)) ) {
|
||||
goto bailout;
|
||||
}
|
||||
|
||||
NumIfs = 0;
|
||||
IfFlags = 0;
|
||||
|
||||
bailout:
|
||||
DBufFree(&buf);
|
||||
DBufFree(&path);
|
||||
DBufFree(&fullname);
|
||||
return r;
|
||||
}
|
||||
|
||||
/***************************************************************/
|
||||
/* */
|
||||
/* DoIncludeCmd */
|
||||
/* */
|
||||
/* The INCLUDECMD command. */
|
||||
/* */
|
||||
/***************************************************************/
|
||||
int DoIncludeCmd(ParsePtr p)
|
||||
{
|
||||
DynamicBuffer buf;
|
||||
int r;
|
||||
int ch;
|
||||
char append_buf[2];
|
||||
int seen_nonspace = 0;
|
||||
|
||||
append_buf[1] = 0;
|
||||
|
||||
DBufInit(&buf);
|
||||
|
||||
while(1) {
|
||||
ch = ParseChar(p, &r, 0);
|
||||
if (r) {
|
||||
DBufFree(&buf);
|
||||
return r;
|
||||
}
|
||||
if (!ch) {
|
||||
break;
|
||||
}
|
||||
if (isspace(ch) && !seen_nonspace) {
|
||||
continue;
|
||||
}
|
||||
seen_nonspace = 1;
|
||||
/* Convert \n to ' ' to better handle line continuation */
|
||||
if (ch == '\n') {
|
||||
ch = ' ';
|
||||
}
|
||||
append_buf[0] = (char) ch;
|
||||
if (DBufPuts(&buf, append_buf) != OK) {
|
||||
DBufFree(&buf);
|
||||
return E_NO_MEM;
|
||||
}
|
||||
}
|
||||
|
||||
if (RunDisabled) {
|
||||
DBufFree(&buf);
|
||||
return E_RUN_DISABLED;
|
||||
}
|
||||
|
||||
if ( (r=IncludeCmd(DBufValue(&buf))) ) {
|
||||
DBufFree(&buf);
|
||||
return r;
|
||||
}
|
||||
@@ -664,6 +819,128 @@ static int SetupGlobChain(char const *dirname, IncludeStruct *i)
|
||||
}
|
||||
#endif
|
||||
|
||||
/***************************************************************/
|
||||
/* */
|
||||
/* IncludeCmd */
|
||||
/* */
|
||||
/* Process the INCLUDECMD command - actually do the command */
|
||||
/* inclusion. */
|
||||
/* */
|
||||
/***************************************************************/
|
||||
static int IncludeCmd(char const *cmd)
|
||||
{
|
||||
IncludeStruct *i;
|
||||
DynamicBuffer buf;
|
||||
FILE *fp2;
|
||||
int r;
|
||||
CachedFile *h;
|
||||
char const *fname;
|
||||
int old_flag;
|
||||
|
||||
FreshLine = 1;
|
||||
clear_callstack();
|
||||
if (IStackPtr+1 >= INCLUDE_NEST) return E_NESTED_INCLUDE;
|
||||
i = &IStack[IStackPtr];
|
||||
|
||||
/* Use "cmd|" as the filename */
|
||||
DBufInit(&buf);
|
||||
if (DBufPuts(&buf, cmd) != OK) {
|
||||
DBufFree(&buf);
|
||||
return E_NO_MEM;
|
||||
}
|
||||
if (DBufPuts(&buf, "|") != OK) {
|
||||
DBufFree(&buf);
|
||||
return E_NO_MEM;
|
||||
}
|
||||
fname = DBufValue(&buf);
|
||||
|
||||
if (FileName) {
|
||||
i->filename = StrDup(FileName);
|
||||
if (!i->filename) {
|
||||
DBufFree(&buf);
|
||||
return E_NO_MEM;
|
||||
}
|
||||
} else {
|
||||
i->filename = NULL;
|
||||
}
|
||||
i->ownedByMe = 1;
|
||||
i->LineNo = LineNo;
|
||||
i->NumIfs = NumIfs;
|
||||
i->IfFlags = IfFlags;
|
||||
i->CLine = CLine;
|
||||
i->offset = -1L;
|
||||
i->chain = NULL;
|
||||
if (fp) {
|
||||
i->offset = ftell(fp);
|
||||
FCLOSE(fp);
|
||||
}
|
||||
IStackPtr++;
|
||||
|
||||
/* If the file is cached, use it */
|
||||
h = CachedFiles;
|
||||
while(h) {
|
||||
if (!strcmp(fname, h->filename)) {
|
||||
if (DebugFlag & DB_TRACE_FILES) {
|
||||
fprintf(ErrFp, "Reading command `%s': Found in cache\n", fname);
|
||||
}
|
||||
CLine = h->cache;
|
||||
STRSET(FileName, fname);
|
||||
DBufFree(&buf);
|
||||
LineNo = 0;
|
||||
if (!h->ownedByMe) {
|
||||
RunDisabled |= RUN_NOTOWNER;
|
||||
} else {
|
||||
RunDisabled &= ~RUN_NOTOWNER;
|
||||
}
|
||||
if (FileName) return OK; else return E_NO_MEM;
|
||||
}
|
||||
h = h->next;
|
||||
}
|
||||
|
||||
if (DebugFlag & DB_TRACE_FILES) {
|
||||
fprintf(ErrFp, "Executing `%s' for INCLUDECMD and caching as `%s'\n",
|
||||
cmd, fname);
|
||||
}
|
||||
|
||||
/* Not found in cache */
|
||||
|
||||
/* If cmd starts with !, then disable RUN within the cmd output */
|
||||
if (cmd[0] == '!') {
|
||||
fp2 = popen(cmd+1, "r");
|
||||
} else {
|
||||
fp2 = popen(cmd, "r");
|
||||
}
|
||||
if (!fp2) {
|
||||
DBufFree(&buf);
|
||||
return E_CANT_OPEN;
|
||||
}
|
||||
fp = fp2;
|
||||
LineNo = 0;
|
||||
|
||||
/* Temporarily turn of file tracing */
|
||||
old_flag = DebugFlag;
|
||||
DebugFlag &= (~DB_TRACE_FILES);
|
||||
|
||||
if (cmd[0] == '!') {
|
||||
RunDisabled |= RUN_NOTOWNER;
|
||||
}
|
||||
r = CacheFile(fname, 1);
|
||||
|
||||
DebugFlag = old_flag;
|
||||
if (r == OK) {
|
||||
fp = NULL;
|
||||
CLine = CachedFiles->cache;
|
||||
LineNo = 0;
|
||||
STRSET(FileName, fname);
|
||||
DBufFree(&buf);
|
||||
return OK;
|
||||
}
|
||||
DBufFree(&buf);
|
||||
/* We failed */
|
||||
PopFile();
|
||||
return E_CANT_OPEN;
|
||||
}
|
||||
|
||||
/***************************************************************/
|
||||
/* */
|
||||
/* IncludeFile */
|
||||
@@ -679,6 +956,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];
|
||||
|
||||
@@ -711,6 +989,11 @@ int IncludeFile(char const *fname)
|
||||
if (stat(fname, &statbuf) == 0) {
|
||||
FilenameChain *fc;
|
||||
if (S_ISDIR(statbuf.st_mode)) {
|
||||
/* Check safety */
|
||||
if (!CheckSafetyAux(&statbuf)) {
|
||||
PopFile();
|
||||
return E_NO_MATCHING_REMS;
|
||||
}
|
||||
if (SetupGlobChain(fname, i) == OK) { /* Glob succeeded */
|
||||
if (!i->chain) { /* Oops... no matching files */
|
||||
if (!Hush) {
|
||||
@@ -771,7 +1054,7 @@ int GetAccessDate(char const *file)
|
||||
if (t1->tm_year + 1900 < BASE)
|
||||
return 0;
|
||||
else
|
||||
return Julian(t1->tm_year+1900, t1->tm_mon, t1->tm_mday);
|
||||
return DSE(t1->tm_year+1900, t1->tm_mon, t1->tm_mday);
|
||||
}
|
||||
|
||||
/***************************************************************/
|
||||
@@ -824,11 +1107,12 @@ int TopLevel(void)
|
||||
/* CheckSafety */
|
||||
/* */
|
||||
/* Returns 1 if current file is safe to read; 0 otherwise. */
|
||||
/* Currently only meaningful for UNIX. If we are running as */
|
||||
/* root, we refuse to open files not owned by root. */
|
||||
/* If we are running as root, we refuse to open files not */
|
||||
/* owned by root. */
|
||||
/* We also reject world-writable files, no matter */
|
||||
/* who we're running as. */
|
||||
/* As a side effect, if we don't own the file, we disable RUN */
|
||||
/* As a side effect, if we don't own the file, or it's not */
|
||||
/* owned by a trusted user, we disable RUN */
|
||||
/***************************************************************/
|
||||
static int CheckSafety(void)
|
||||
{
|
||||
@@ -844,31 +1128,63 @@ static int CheckSafety(void)
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (!CheckSafetyAux(&statbuf)) {
|
||||
fclose(fp);
|
||||
fp = NULL;
|
||||
return 0;
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
/***************************************************************/
|
||||
/* */
|
||||
/* CheckSafetyAux */
|
||||
/* */
|
||||
/* Returns 1 if file whos info is in statbuf is safe to read; */
|
||||
/* 0 otherwise. If we are running as */
|
||||
/* root, we refuse to open files not owned by root. */
|
||||
/* We also reject world-writable files, no matter */
|
||||
/* who we're running as. */
|
||||
/* As a side effect, if we don't own the file, or it's not */
|
||||
/* owned by a trusted user, we disable RUN */
|
||||
/***************************************************************/
|
||||
|
||||
static int CheckSafetyAux(struct stat *statbuf)
|
||||
{
|
||||
/* Under UNIX, take extra precautions if running as root */
|
||||
if (!geteuid()) {
|
||||
/* Reject files not owned by root or group/world writable */
|
||||
if (statbuf.st_uid != 0) {
|
||||
fprintf(ErrFp, "SECURITY: Won't read non-root-owned file when running as root!\n");
|
||||
fclose(fp);
|
||||
fp = NULL;
|
||||
if (statbuf->st_uid != 0) {
|
||||
fprintf(ErrFp, "SECURITY: Won't read non-root-owned file or directory when running as root!\n");
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
/* Sigh... /dev/null is usually world-writable, so ignore devices,
|
||||
FIFOs, sockets, etc. */
|
||||
if (!S_ISREG(statbuf.st_mode)) {
|
||||
if (!S_ISREG(statbuf->st_mode) && !S_ISDIR(statbuf->st_mode)) {
|
||||
return 1;
|
||||
}
|
||||
if ((statbuf.st_mode & S_IWOTH)) {
|
||||
fprintf(ErrFp, "SECURITY: Won't read world-writable file!\n");
|
||||
fclose(fp);
|
||||
fp = NULL;
|
||||
if ((statbuf->st_mode & S_IWOTH)) {
|
||||
fprintf(ErrFp, "SECURITY: Won't read world-writable file or directory!\n");
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* If file is not owned by me, disable RUN command */
|
||||
if (statbuf.st_uid != geteuid()) {
|
||||
RunDisabled |= RUN_NOTOWNER;
|
||||
/* If file is not owned by me or a trusted user, disable RUN command */
|
||||
|
||||
/* Assume unsafe */
|
||||
RunDisabled |= RUN_NOTOWNER;
|
||||
if (statbuf->st_uid == geteuid()) {
|
||||
/* Owned by me... safe */
|
||||
RunDisabled &= ~RUN_NOTOWNER;
|
||||
} else {
|
||||
int i;
|
||||
for (i=0; i<NumTrustedUsers; i++) {
|
||||
if (statbuf->st_uid == TrustedUsers[i]) {
|
||||
/* Owned by a trusted user... safe */
|
||||
RunDisabled &= ~RUN_NOTOWNER;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return 1;
|
||||
|
||||
1144
src/funcs.c
1144
src/funcs.c
File diff suppressed because it is too large
Load Diff
@@ -8,15 +8,17 @@
|
||||
/* globals.h and err.h */
|
||||
/* */
|
||||
/* This file is part of REMIND. */
|
||||
/* Copyright (C) 1992-2020 by Dianne Skoll */
|
||||
/* Copyright (C) 1992-2024 by Dianne Skoll */
|
||||
/* SPDX-License-Identifier: GPL-2.0-only */
|
||||
/* */
|
||||
/***************************************************************/
|
||||
|
||||
#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"
|
||||
#define MK_GLOBALS
|
||||
#include "lang.h"
|
||||
#define MK_GLOBALS 1
|
||||
#include "globals.h"
|
||||
#include "err.h"
|
||||
|
||||
183
src/globals.h
183
src/globals.h
@@ -7,10 +7,12 @@
|
||||
/* MK_GLOBALS. Also contains useful macro definitions. */
|
||||
/* */
|
||||
/* This file is part of REMIND. */
|
||||
/* Copyright (C) 1992-2020 by Dianne Skoll */
|
||||
/* Copyright (C) 1992-2021 by Dianne Skoll */
|
||||
/* SPDX-License-Identifier: GPL-2.0-only */
|
||||
/* */
|
||||
/***************************************************************/
|
||||
|
||||
|
||||
#ifdef MK_GLOBALS
|
||||
#undef EXTERN
|
||||
#define EXTERN
|
||||
@@ -21,22 +23,37 @@
|
||||
#define INIT(var, val) var
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_SYS_TYPES_H
|
||||
#include <sys/types.h>
|
||||
#endif
|
||||
EXTERN FILE *ErrFp;
|
||||
|
||||
#include "dynbuf.h"
|
||||
#include "lang.h"
|
||||
|
||||
#define MAX_TRUSTED_USERS 20
|
||||
|
||||
#define MINUTES_PER_DAY 1440
|
||||
|
||||
#define DaysInYear(y) (((y) % 4) ? 365 : ((!((y) % 100) && ((y) % 400)) ? 365 : 366 ))
|
||||
#define IsLeapYear(y) (((y) % 4) ? 0 : ((!((y) % 100) && ((y) % 400)) ? 0 : 1 ))
|
||||
#define DaysInMonth(m, y) ((m) != 1 ? MonthDays[m] : 28 + IsLeapYear(y))
|
||||
|
||||
#define DestroyValue(x) (void) (((x).type == STR_TYPE && (x).v.str) ? (free((x).v.str),(x).type = ERR_TYPE) : 0)
|
||||
#define DestroyValue(x) (void) (((x).type == STR_TYPE && (x).v.str) ? (free((x).v.str),(x).v.str = NULL,(x).type = ERR_TYPE) : 0)
|
||||
|
||||
EXTERN int JulianToday;
|
||||
EXTERN int DSEToday;
|
||||
EXTERN int RealToday;
|
||||
EXTERN int CurDay;
|
||||
EXTERN int CurMon;
|
||||
EXTERN int CurYear;
|
||||
EXTERN int LineNo;
|
||||
EXTERN int FreshLine;
|
||||
EXTERN uid_t TrustedUsers[MAX_TRUSTED_USERS];
|
||||
|
||||
EXTERN INIT( int MaxLateMinutes, 0);
|
||||
EXTERN INIT( int NumTrustedUsers, 0);
|
||||
EXTERN INIT( char const *MsgCommand, NULL);
|
||||
EXTERN INIT( char const *QueuedMsgCommand, NULL);
|
||||
EXTERN INIT( int ShowAllErrors, 0);
|
||||
EXTERN INIT( int DebugFlag, 0);
|
||||
EXTERN INIT( int DoCalendar, 0);
|
||||
@@ -44,15 +61,17 @@ 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);
|
||||
EXTERN INIT( int NextMode, 0);
|
||||
EXTERN INIT( int InfiniteDelta, 0);
|
||||
EXTERN INIT( int DeltaOffset, 0);
|
||||
EXTERN INIT( int DefaultTDelta, 0);
|
||||
EXTERN INIT( int DeltaOverride, 0);
|
||||
EXTERN INIT( int RunDisabled, 0);
|
||||
EXTERN INIT( int IgnoreOnce, 0);
|
||||
EXTERN INIT( int SortByTime, 0);
|
||||
@@ -60,16 +79,20 @@ EXTERN INIT( int SortByDate, 0);
|
||||
EXTERN INIT( int SortByPrio, 0);
|
||||
EXTERN INIT( int UntimedBeforeTimed, 0);
|
||||
EXTERN INIT( int DefaultPrio, NO_PRIORITY);
|
||||
EXTERN INIT( long SysTime, -1L);
|
||||
EXTERN INIT( int SysTime, -1);
|
||||
EXTERN INIT( int ParseUntriggered, 1);
|
||||
|
||||
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);
|
||||
EXTERN INIT( int DontIssueAts, 0);
|
||||
EXTERN INIT( int Daemon, 0);
|
||||
EXTERN INIT( int DaemonJSON, 0);
|
||||
EXTERN INIT( char DateSep, DATESEP);
|
||||
EXTERN INIT( char TimeSep, TIMESEP);
|
||||
EXTERN INIT( char DateTimeSep, DATETIMESEP);
|
||||
@@ -78,13 +101,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( 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);
|
||||
@@ -96,11 +118,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);
|
||||
@@ -108,12 +132,15 @@ EXTERN INIT( int UseTrueColors, 0);
|
||||
EXTERN INIT( int TerminalBackground, TERMINAL_BACKGROUND_UNKNOWN);
|
||||
|
||||
/* Latitude and longitude */
|
||||
EXTERN INIT( int LatDeg, LAT_DEG);
|
||||
EXTERN INIT( int LatMin, LAT_MIN);
|
||||
EXTERN INIT( int LatSec, LAT_SEC);
|
||||
EXTERN INIT( int LongDeg, LON_DEG);
|
||||
EXTERN INIT( int LongMin, LON_MIN);
|
||||
EXTERN INIT( int LongSec, LON_SEC);
|
||||
EXTERN INIT( int LatDeg, 0);
|
||||
EXTERN INIT( int LatMin, 0);
|
||||
EXTERN INIT( int LatSec, 0);
|
||||
EXTERN INIT( int LongDeg, 0);
|
||||
EXTERN INIT( int LongMin, 0);
|
||||
EXTERN INIT( int LongSec, 0);
|
||||
EXTERN INIT( double Longitude, DEFAULT_LONGITUDE);
|
||||
EXTERN INIT( double Latitude, DEFAULT_LATITUDE);
|
||||
|
||||
EXTERN INIT( char *Location, LOCATION);
|
||||
|
||||
/* UTC calculation stuff */
|
||||
@@ -128,14 +155,12 @@ 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;
|
||||
|
||||
extern int NumFullOmits, NumPartialOmits;
|
||||
|
||||
/* List of months */
|
||||
EXTERN char *EnglishMonthName[]
|
||||
#ifdef MK_GLOBALS
|
||||
@@ -155,6 +180,17 @@ EXTERN char *MonthName[]
|
||||
;
|
||||
#endif
|
||||
|
||||
EXTERN char *DynamicMonthName[]
|
||||
#ifdef MK_GLOBALS
|
||||
#if LANG == ENGLISH
|
||||
= {"January", "February", "March", "April", "May", "June",
|
||||
"July", "August", "September", "October", "November", "December"}
|
||||
#else
|
||||
= {L_JAN, L_FEB, L_MAR, L_APR, L_MAY, L_JUN,
|
||||
L_JUL, L_AUG, L_SEP, L_OCT, L_NOV, L_DEC}
|
||||
#endif
|
||||
#endif
|
||||
;
|
||||
EXTERN char *EnglishDayName[]
|
||||
#ifdef MK_GLOBALS
|
||||
= {"Monday", "Tuesday", "Wednesday", "Thursday", "Friday",
|
||||
@@ -173,6 +209,18 @@ EXTERN char *DayName[]
|
||||
;
|
||||
#endif
|
||||
|
||||
EXTERN char *DynamicDayName []
|
||||
#ifdef MK_GLOBALS
|
||||
#if LANG == ENGLISH
|
||||
= {"Monday", "Tuesday", "Wednesday", "Thursday", "Friday",
|
||||
"Saturday", "Sunday"}
|
||||
#else
|
||||
= {L_MONDAY, L_TUESDAY, L_WEDNESDAY, L_THURSDAY, L_FRIDAY,
|
||||
L_SATURDAY, L_SUNDAY}
|
||||
#endif
|
||||
#endif
|
||||
;
|
||||
|
||||
EXTERN int MonthDays[]
|
||||
#ifdef MK_GLOBALS
|
||||
= {31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31}
|
||||
@@ -191,3 +239,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
|
||||
;
|
||||
|
||||
45
src/hbcal.c
45
src/hbcal.c
@@ -5,7 +5,8 @@
|
||||
/* Support for the Hebrew calendar */
|
||||
/* */
|
||||
/* This file is part of REMIND. */
|
||||
/* Copyright (C) 1992-2020 by Dianne Skoll */
|
||||
/* Copyright (C) 1992-2024 by Dianne Skoll */
|
||||
/* SPDX-License-Identifier: GPL-2.0-only */
|
||||
/* */
|
||||
/* Derived from code written by Amos Shapir in 1978; revised */
|
||||
/* 1985. */
|
||||
@@ -67,7 +68,7 @@ static char HebIsLeap[] = {0,0,1,0,0,1,0,1,0,0,1,0,0,1,0,0,1,0,1};
|
||||
/* */
|
||||
/* RoshHashana */
|
||||
/* */
|
||||
/* Return the Julian date for Rosh Hashana of specified */
|
||||
/* Return DSE date for Rosh Hashana of specified */
|
||||
/* Hebrew year. (ie, 5751, not 1990) */
|
||||
/* */
|
||||
/***************************************************************/
|
||||
@@ -155,14 +156,14 @@ char const *DaysInHebMonths(int ylen)
|
||||
|
||||
/***************************************************************/
|
||||
/* */
|
||||
/* HebToJul */
|
||||
/* HebToDSE */
|
||||
/* */
|
||||
/* Convert a Hebrew date to Julian. */
|
||||
/* Convert a Hebrew date to DSE. */
|
||||
/* Hebrew months range from 0-12, but Adar A has 0 length in */
|
||||
/* non-leap-years. */
|
||||
/* */
|
||||
/***************************************************************/
|
||||
int HebToJul(int hy, int hm, int hd)
|
||||
int HebToDSE(int hy, int hm, int hd)
|
||||
{
|
||||
int ylen;
|
||||
char const *monlens;
|
||||
@@ -188,39 +189,39 @@ int HebToJul(int hy, int hm, int hd)
|
||||
|
||||
/***************************************************************/
|
||||
/* */
|
||||
/* JulToHeb */
|
||||
/* DSEToHeb */
|
||||
/* */
|
||||
/* Convert a Julian date to Hebrew. */
|
||||
/* Convert a DSE to Hebrew. */
|
||||
/* Hebrew months range from 0-12, but Adar A has 0 length in */
|
||||
/* non-leap-years. */
|
||||
/* */
|
||||
/***************************************************************/
|
||||
void JulToHeb(int jul, int *hy, int *hm, int *hd)
|
||||
void DSEToHeb(int dse, int *hy, int *hm, int *hd)
|
||||
{
|
||||
int y, m, d;
|
||||
int rh;
|
||||
int ylen;
|
||||
char const *monlen;
|
||||
/* Get the common year */
|
||||
FromJulian(jul, &y, &m, &d);
|
||||
FromDSE(dse, &y, &m, &d);
|
||||
y += 3763; /* Over-estimate a bit to be on the safe side below... */
|
||||
|
||||
/* Find the RH just before desired date */
|
||||
while ((rh=RoshHashana(y))>jul) y--;
|
||||
while ((rh=RoshHashana(y))>dse) y--;
|
||||
|
||||
/* Got the year - now find the month */
|
||||
jul -= rh;
|
||||
dse -= rh;
|
||||
ylen = DaysInHebYear(y);
|
||||
monlen = DaysInHebMonths(ylen);
|
||||
m = 0;
|
||||
while((jul >= monlen[m]) || !monlen[m]) {
|
||||
jul -= monlen[m];
|
||||
while((dse >= monlen[m]) || !monlen[m]) {
|
||||
dse -= monlen[m];
|
||||
m++;
|
||||
}
|
||||
|
||||
*hy = y;
|
||||
*hm = m;
|
||||
*hd = jul+1;
|
||||
*hd = dse+1;
|
||||
}
|
||||
|
||||
/***************************************************************/
|
||||
@@ -389,20 +390,20 @@ int GetValidHebDate(int yin, int min, int din, int adarbehave,
|
||||
/* Returns 0 for success, non-zero for failure. */
|
||||
/* */
|
||||
/***************************************************************/
|
||||
int GetNextHebrewDate(int julstart, int hm, int hd,
|
||||
int GetNextHebrewDate(int dsestart, int hm, int hd,
|
||||
int jahr, int adarbehave, int *ans)
|
||||
{
|
||||
int r, yout, mout, dout, jul=1;
|
||||
int r, yout, mout, dout, dse=1;
|
||||
int adarflag = adarbehave;
|
||||
|
||||
/* I initialize jul above to stop gcc from complaining about
|
||||
/* I initialize dse above to stop gcc from complaining about
|
||||
possible use of uninitialized variable. You can take it
|
||||
out if the small inefficiency really bothers you. */
|
||||
|
||||
/* If adarbehave == ADAR2BOTH, set adarflag to ADAR2ADARA for now */
|
||||
if (adarbehave == ADAR2BOTH) adarflag = ADAR2ADARA;
|
||||
|
||||
JulToHeb(julstart, &yout, &mout, &dout);
|
||||
DSEToHeb(dsestart, &yout, &mout, &dout);
|
||||
|
||||
r = 1;
|
||||
while(r) {
|
||||
@@ -419,9 +420,9 @@ int GetNextHebrewDate(int julstart, int hm, int hd,
|
||||
} else yout++;
|
||||
continue;
|
||||
}
|
||||
jul = HebToJul(yout, mout, dout);
|
||||
if (jul < 0) return E_DATE_OVER;
|
||||
if (jul >= julstart) break;
|
||||
dse = HebToDSE(yout, mout, dout);
|
||||
if (dse < 0) return E_DATE_OVER;
|
||||
if (dse >= dsestart) break;
|
||||
else {
|
||||
if (adarbehave == ADAR2BOTH && hm == ADAR) {
|
||||
if (adarflag == ADAR2ADARA) {
|
||||
@@ -434,7 +435,7 @@ int GetNextHebrewDate(int julstart, int hm, int hd,
|
||||
r=1; /* Force loop to continue */
|
||||
}
|
||||
}
|
||||
*ans = jul;
|
||||
*ans = dse;
|
||||
return OK;
|
||||
}
|
||||
|
||||
|
||||
482
src/init.c
482
src/init.c
@@ -7,7 +7,8 @@
|
||||
/* in normal mode. */
|
||||
/* */
|
||||
/* This file is part of REMIND. */
|
||||
/* Copyright (C) 1992-2020 by Dianne Skoll */
|
||||
/* Copyright (C) 1992-2024 by Dianne Skoll */
|
||||
/* SPDX-License-Identifier: GPL-2.0-only */
|
||||
/* */
|
||||
/***************************************************************/
|
||||
|
||||
@@ -21,16 +22,33 @@
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/stat.h>
|
||||
#include <fcntl.h>
|
||||
#include <errno.h>
|
||||
#include <poll.h>
|
||||
#include <pwd.h>
|
||||
#include <unistd.h>
|
||||
#include <sys/ioctl.h>
|
||||
#include <termios.h>
|
||||
|
||||
#ifdef HAVE_INITGROUPS
|
||||
#include <grp.h>
|
||||
#endif
|
||||
|
||||
#include "types.h"
|
||||
#include "globals.h"
|
||||
#include "protos.h"
|
||||
#include "expr.h"
|
||||
#include "err.h"
|
||||
#include "globals.h"
|
||||
|
||||
static int should_guess_terminal_background = 1;
|
||||
|
||||
static void guess_terminal_background(int *r, int *g, int *b);
|
||||
static int tty_init(int fd);
|
||||
static void tty_raw(int fd);
|
||||
static void tty_reset(int fd);
|
||||
|
||||
static void ProcessLongOption(char const *arg);
|
||||
/***************************************************************
|
||||
*
|
||||
* Command line options recognized:
|
||||
@@ -39,7 +57,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
|
||||
@@ -72,9 +91,6 @@
|
||||
* A minus sign alone indicates to take input from stdin
|
||||
*
|
||||
**************************************************************/
|
||||
#if defined(__APPLE__) || defined(__CYGWIN__)
|
||||
static void rkrphgvba(int x);
|
||||
#endif
|
||||
|
||||
/* For parsing an integer */
|
||||
#define PARSENUM(var, s) \
|
||||
@@ -89,9 +105,29 @@ static void ChgUser(char const *u);
|
||||
static void InitializeVar(char const *str);
|
||||
|
||||
static char const *BadDate = "Illegal date on command line\n";
|
||||
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 */
|
||||
@@ -114,7 +150,7 @@ static char const *DefaultFilename(void)
|
||||
s = getenv("HOME");
|
||||
if (!s) {
|
||||
fprintf(stderr, "HOME environment variable not set. Unable to determine reminder file.\n");
|
||||
exit(1);
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
DBufPuts(&default_filename_buf, s);
|
||||
DBufPuts(&default_filename_buf, "/.reminders");
|
||||
@@ -138,27 +174,15 @@ void InitRemind(int argc, char const *argv[])
|
||||
char const *s;
|
||||
int weeks;
|
||||
int x;
|
||||
int jul;
|
||||
int dse;
|
||||
int ttyfd;
|
||||
|
||||
#if defined(__APPLE__)
|
||||
rkrphgvba(0);
|
||||
#elif defined(__CYGWIN__)
|
||||
rkrphgvba(1);
|
||||
#endif
|
||||
|
||||
jul = NO_DATE;
|
||||
dse = 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);
|
||||
@@ -172,7 +196,7 @@ void InitRemind(int argc, char const *argv[])
|
||||
if (getgid() != getegid() ||
|
||||
getuid() != geteuid()) {
|
||||
fprintf(ErrFp, "\nRemind should not be installed set-uid or set-gid.\nCHECK YOUR SYSTEM SECURITY.\n");
|
||||
exit(1);
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
|
||||
y = NO_YR;
|
||||
@@ -183,10 +207,13 @@ void InitRemind(int argc, char const *argv[])
|
||||
RealToday = SystemDate(&CurYear, &CurMon, &CurDay);
|
||||
if (RealToday < 0) {
|
||||
fprintf(ErrFp, ErrMsg[M_BAD_SYS_DATE], BASE);
|
||||
exit(1);
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
JulianToday = RealToday;
|
||||
FromJulian(JulianToday, &CurYear, &CurMon, &CurDay);
|
||||
DSEToday = RealToday;
|
||||
FromDSE(DSEToday, &CurYear, &CurMon, &CurDay);
|
||||
|
||||
/* Initialize Latitude and Longitude */
|
||||
set_components_from_lat_and_long();
|
||||
|
||||
/* See if we were invoked as "rem" rather than "remind" */
|
||||
if (argv[0]) {
|
||||
@@ -199,6 +226,9 @@ void InitRemind(int argc, char const *argv[])
|
||||
if (!strcmp(s, "rem")) {
|
||||
InvokedAsRem = 1;
|
||||
}
|
||||
} else {
|
||||
fprintf(stderr, "Invoked with a NULL argv[0]; bailing because that's just plain bizarre.\n");
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
|
||||
/* Parse the command-line options */
|
||||
@@ -217,6 +247,15 @@ void InitRemind(int argc, char const *argv[])
|
||||
}
|
||||
while (*arg) {
|
||||
switch(*arg++) {
|
||||
case '+':
|
||||
AddTrustedUser(arg);
|
||||
while(*arg) arg++;
|
||||
break;
|
||||
|
||||
case '-':
|
||||
ProcessLongOption(arg);
|
||||
while(*arg) arg++;
|
||||
break;
|
||||
|
||||
case '@':
|
||||
UseVTColors = 1;
|
||||
@@ -226,17 +265,45 @@ 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 != ',') {
|
||||
if (*arg == 't') {
|
||||
arg++;
|
||||
should_guess_terminal_background = 2;
|
||||
} else {
|
||||
PARSENUM(x, arg);
|
||||
if (x == 0) {
|
||||
should_guess_terminal_background = 0;
|
||||
TerminalBackground = TERMINAL_BACKGROUND_DARK;
|
||||
} else if (x == 1) {
|
||||
should_guess_terminal_background = 0;
|
||||
TerminalBackground = TERMINAL_BACKGROUND_LIGHT;
|
||||
} else if (x == 2) {
|
||||
should_guess_terminal_background = 0;
|
||||
TerminalBackground = TERMINAL_BACKGROUND_UNKNOWN;
|
||||
} else {
|
||||
fprintf(ErrFp, "%s: -@n,m,b: m must be t, 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':
|
||||
@@ -281,13 +348,30 @@ void InitRemind(int argc, char const *argv[])
|
||||
|
||||
case 't':
|
||||
case 'T':
|
||||
if (!*arg) {
|
||||
if (*arg == 'T' || *arg == 't') {
|
||||
arg++;
|
||||
if (!*arg) {
|
||||
DefaultTDelta = 5;
|
||||
} else {
|
||||
PARSENUM(DefaultTDelta, arg);
|
||||
if (DefaultTDelta < 0) {
|
||||
DefaultTDelta = 0;
|
||||
} else if (DefaultTDelta > 1440) {
|
||||
DefaultTDelta = 1440;
|
||||
}
|
||||
}
|
||||
} else if (!*arg) {
|
||||
InfiniteDelta = 1;
|
||||
} else {
|
||||
PARSENUM(DeltaOffset, arg);
|
||||
if (DeltaOffset < 0) {
|
||||
DeltaOffset = 0;
|
||||
}
|
||||
if (*arg == 'z') {
|
||||
DeltaOverride = -1;
|
||||
arg++;
|
||||
} else {
|
||||
PARSENUM(DeltaOverride, arg);
|
||||
if (DeltaOverride < 0) {
|
||||
DeltaOverride = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
break;
|
||||
case 'e':
|
||||
@@ -330,14 +414,22 @@ void InitRemind(int argc, char const *argv[])
|
||||
|
||||
case 'u':
|
||||
case 'U':
|
||||
ChgUser(arg);
|
||||
RunDisabled = RUN_CMDLINE;
|
||||
if (*arg == '+') {
|
||||
ChgUser(arg+1);
|
||||
} else {
|
||||
RunDisabled = RUN_CMDLINE;
|
||||
ChgUser(arg);
|
||||
}
|
||||
while (*arg) arg++;
|
||||
break;
|
||||
case 'z':
|
||||
case 'Z':
|
||||
DontFork = 1;
|
||||
if (*arg == '0') {
|
||||
if (*arg == 'j' || *arg == 'J') {
|
||||
while (*arg) arg++;
|
||||
Daemon = -1;
|
||||
DaemonJSON = 1;
|
||||
} else if (*arg == '0') {
|
||||
PARSENUM(Daemon, arg);
|
||||
if (Daemon == 0) Daemon = -1;
|
||||
else if (Daemon < 1) Daemon = 1;
|
||||
@@ -437,6 +529,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;
|
||||
@@ -449,7 +542,9 @@ void InitRemind(int argc, char const *argv[])
|
||||
} else {
|
||||
PsCal = PSCAL_LEVEL3;
|
||||
}
|
||||
}
|
||||
} else if (*arg == 'q' || *arg == 'Q') {
|
||||
DontSuppressQuoteMarkers = 1;
|
||||
}
|
||||
arg++;
|
||||
}
|
||||
PARSENUM(CalMonths, arg);
|
||||
@@ -464,11 +559,32 @@ 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 < 0) {
|
||||
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) {
|
||||
/* Cal width of 0 means obtain from stdout */
|
||||
if (isatty(STDOUT_FILENO)) {
|
||||
InitCalWidthAndFormWidth(STDOUT_FILENO);
|
||||
} else {
|
||||
CalWidth = 80;
|
||||
}
|
||||
}
|
||||
FormWidth = CalWidth - 8;
|
||||
if (FormWidth < 20) FormWidth = 20;
|
||||
if (FormWidth > 500) FormWidth = 500;
|
||||
}
|
||||
}
|
||||
if (*arg == ',') {
|
||||
arg++;
|
||||
@@ -520,7 +636,12 @@ void InitRemind(int argc, char const *argv[])
|
||||
|
||||
case 'k':
|
||||
case 'K':
|
||||
MsgCommand = arg;
|
||||
if (*arg == ':') {
|
||||
arg++;
|
||||
QueuedMsgCommand = arg;
|
||||
} else {
|
||||
MsgCommand = arg;
|
||||
}
|
||||
while (*arg) arg++; /* Chew up remaining chars in this arg */
|
||||
break;
|
||||
|
||||
@@ -535,7 +656,7 @@ void InitRemind(int argc, char const *argv[])
|
||||
if (!InvokedAsRem) {
|
||||
if (i >= argc) {
|
||||
Usage();
|
||||
exit(1);
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
InitialFile = argv[i++];
|
||||
} else {
|
||||
@@ -559,30 +680,30 @@ void InitRemind(int argc, char const *argv[])
|
||||
|
||||
case T_DateTime:
|
||||
if (SysTime != -1L) Usage();
|
||||
if (m != NO_MON || d != NO_DAY || y != NO_YR || jul != NO_DATE) Usage();
|
||||
if (m != NO_MON || d != NO_DAY || y != NO_YR || dse != NO_DATE) Usage();
|
||||
SysTime = (tok.val % MINUTES_PER_DAY) * 60;
|
||||
DontQueue = 1;
|
||||
Daemon = 0;
|
||||
jul = tok.val / MINUTES_PER_DAY;
|
||||
dse = tok.val / MINUTES_PER_DAY;
|
||||
break;
|
||||
|
||||
case T_Date:
|
||||
if (m != NO_MON || d != NO_DAY || y != NO_YR || jul != NO_DATE) Usage();
|
||||
jul = tok.val;
|
||||
if (m != NO_MON || d != NO_DAY || y != NO_YR || dse != NO_DATE) Usage();
|
||||
dse = tok.val;
|
||||
break;
|
||||
|
||||
case T_Month:
|
||||
if (m != NO_MON || jul != NO_DATE) Usage();
|
||||
if (m != NO_MON || dse != NO_DATE) Usage();
|
||||
else m = tok.val;
|
||||
break;
|
||||
|
||||
case T_Day:
|
||||
if (d != NO_DAY || jul != NO_DATE) Usage();
|
||||
if (d != NO_DAY || dse != NO_DATE) Usage();
|
||||
else d = tok.val;
|
||||
break;
|
||||
|
||||
case T_Year:
|
||||
if (y != NO_YR || jul != NO_DATE) Usage();
|
||||
if (y != NO_YR || dse != NO_DATE) Usage();
|
||||
else y = tok.val;
|
||||
break;
|
||||
|
||||
@@ -602,8 +723,8 @@ void InitRemind(int argc, char const *argv[])
|
||||
Daemon = 0;
|
||||
}
|
||||
|
||||
if (jul != NO_DATE) {
|
||||
FromJulian(jul, &y, &m, &d);
|
||||
if (dse != NO_DATE) {
|
||||
FromDSE(dse, &y, &m, &d);
|
||||
}
|
||||
/* Must supply date in the form: day, mon, yr OR mon, yr */
|
||||
if (m != NO_MON || y != NO_YR || d != NO_DAY) {
|
||||
@@ -621,21 +742,22 @@ void InitRemind(int argc, char const *argv[])
|
||||
fprintf(ErrFp, "%s", BadDate);
|
||||
Usage();
|
||||
}
|
||||
JulianToday = Julian(y, m, d);
|
||||
if (JulianToday == -1) {
|
||||
DSEToday = DSE(y, m, d);
|
||||
if (DSEToday == -1) {
|
||||
fprintf(ErrFp, "%s", BadDate);
|
||||
Usage();
|
||||
}
|
||||
CurYear = y;
|
||||
CurMon = m;
|
||||
CurDay = d;
|
||||
if (JulianToday != RealToday) IgnoreOnce = 1;
|
||||
if (DSEToday != RealToday) IgnoreOnce = 1;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/* Figure out the offset from UTC */
|
||||
if (CalculateUTC)
|
||||
(void) CalcMinsFromUTC(JulianToday, SystemTime(0)/60,
|
||||
(void) CalcMinsFromUTC(DSEToday, MinutesPastMidnight(0),
|
||||
&MinsFromUTC, NULL);
|
||||
}
|
||||
|
||||
@@ -649,7 +771,7 @@ void InitRemind(int argc, char const *argv[])
|
||||
#ifndef L_USAGE_OVERRIDE
|
||||
void Usage(void)
|
||||
{
|
||||
fprintf(ErrFp, "\nREMIND %s (%s version) Copyright 1992-2020 Dianne Skoll\n", VERSION, L_LANGNAME);
|
||||
fprintf(ErrFp, "\nREMIND %s (%s version) Copyright 1992-2024 Dianne Skoll\n", VERSION, L_LANGNAME);
|
||||
#ifdef BETA
|
||||
fprintf(ErrFp, ">>>> BETA VERSION <<<<\n");
|
||||
#endif
|
||||
@@ -657,7 +779,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");
|
||||
@@ -675,14 +797,14 @@ 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");
|
||||
fprintf(ErrFp, " -m Start calendar with Monday rather than Sunday\n");
|
||||
fprintf(ErrFp, " -y Synthesize tags for tagless reminders\n");
|
||||
fprintf(ErrFp, " -j[n] Run in 'purge' mode. [n = INCLUDE depth]\n");
|
||||
exit(1);
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
#endif /* L_USAGE_OVERRIDE */
|
||||
/***************************************************************/
|
||||
@@ -697,7 +819,7 @@ void Usage(void)
|
||||
/***************************************************************/
|
||||
static void ChgUser(char const *user)
|
||||
{
|
||||
uid_t myuid;
|
||||
uid_t myeuid;
|
||||
|
||||
struct passwd *pwent;
|
||||
static char *home;
|
||||
@@ -705,29 +827,38 @@ static void ChgUser(char const *user)
|
||||
static char *username;
|
||||
static char *logname;
|
||||
|
||||
myuid = getuid();
|
||||
myeuid = geteuid();
|
||||
|
||||
pwent = getpwnam(user);
|
||||
|
||||
if (!pwent) {
|
||||
fprintf(ErrFp, ErrMsg[M_BAD_USER], user);
|
||||
exit(1);
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
|
||||
if (!myuid && setgid(pwent->pw_gid)) {
|
||||
fprintf(ErrFp, ErrMsg[M_NO_CHG_GID], pwent->pw_gid);
|
||||
exit(1);
|
||||
}
|
||||
if (!myeuid) {
|
||||
/* Started as root, so drop privileges */
|
||||
#ifdef HAVE_INITGROUPS
|
||||
if (initgroups(pwent->pw_name, pwent->pw_gid) < 0) {
|
||||
fprintf(ErrFp, ErrMsg[M_NO_CHG_GID], pwent->pw_gid);
|
||||
exit(EXIT_FAILURE);
|
||||
};
|
||||
#endif
|
||||
if (setgid(pwent->pw_gid) < 0) {
|
||||
fprintf(ErrFp, ErrMsg[M_NO_CHG_GID], pwent->pw_gid);
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
|
||||
if (!myuid && setuid(pwent->pw_uid)) {
|
||||
fprintf(ErrFp, ErrMsg[M_NO_CHG_UID], pwent->pw_uid);
|
||||
exit(1);
|
||||
if (setuid(pwent->pw_uid) < 0) {
|
||||
fprintf(ErrFp, ErrMsg[M_NO_CHG_UID], pwent->pw_uid);
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
}
|
||||
|
||||
home = malloc(strlen(pwent->pw_dir) + 6);
|
||||
if (!home) {
|
||||
fprintf(ErrFp, "%s", ErrMsg[M_NOMEM_ENV]);
|
||||
exit(1);
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
sprintf(home, "HOME=%s", pwent->pw_dir);
|
||||
putenv(home);
|
||||
@@ -735,7 +866,7 @@ static void ChgUser(char const *user)
|
||||
shell = malloc(strlen(pwent->pw_shell) + 7);
|
||||
if (!shell) {
|
||||
fprintf(ErrFp, "%s", ErrMsg[M_NOMEM_ENV]);
|
||||
exit(1);
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
sprintf(shell, "SHELL=%s", pwent->pw_shell);
|
||||
putenv(shell);
|
||||
@@ -744,14 +875,14 @@ static void ChgUser(char const *user)
|
||||
username = malloc(strlen(pwent->pw_name) + 6);
|
||||
if (!username) {
|
||||
fprintf(ErrFp, "%s", ErrMsg[M_NOMEM_ENV]);
|
||||
exit(1);
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
sprintf(username, "USER=%s", pwent->pw_name);
|
||||
putenv(username);
|
||||
logname= malloc(strlen(pwent->pw_name) + 9);
|
||||
if (!logname) {
|
||||
fprintf(ErrFp, "%s", ErrMsg[M_NOMEM_ENV]);
|
||||
exit(1);
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
sprintf(logname, "LOGNAME=%s", pwent->pw_name);
|
||||
putenv(logname);
|
||||
@@ -824,6 +955,7 @@ static void InitializeVar(char const *str)
|
||||
|
||||
if (*varname == '$') {
|
||||
r=SetSysVar(varname+1, &val);
|
||||
DestroyValue(val);
|
||||
if (r) fprintf(ErrFp, ErrMsg[M_I_OPTION], ErrMsg[r]);
|
||||
return;
|
||||
}
|
||||
@@ -838,46 +970,158 @@ static void InitializeVar(char const *str)
|
||||
return;
|
||||
}
|
||||
|
||||
#if defined(__APPLE__) || defined(__CYGWIN__)
|
||||
static char const pmsg1[] = {
|
||||
0x4c, 0x62, 0x68, 0x20, 0x6e, 0x63, 0x63, 0x72, 0x6e, 0x65, 0x20,
|
||||
0x67, 0x62, 0x20, 0x6f, 0x72, 0x20, 0x65, 0x68, 0x61, 0x61, 0x76,
|
||||
0x61, 0x74, 0x20, 0x45, 0x72, 0x7a, 0x76, 0x61, 0x71, 0x20, 0x62,
|
||||
0x61, 0x20, 0x6e, 0x61, 0x20, 0x4e, 0x63, 0x63, 0x79, 0x72, 0x20,
|
||||
0x63, 0x65, 0x62, 0x71, 0x68, 0x70, 0x67, 0x2e, 0x20, 0x20, 0x56,
|
||||
0x27, 0x71, 0x20, 0x65, 0x6e, 0x67, 0x75, 0x72, 0x65, 0x20, 0x67,
|
||||
0x75, 0x6e, 0x67, 0x0a, 0x6c, 0x62, 0x68, 0x20, 0x71, 0x76, 0x71,
|
||||
0x61, 0x27, 0x67, 0x2e, 0x20, 0x20, 0x45, 0x72, 0x7a, 0x76, 0x61,
|
||||
0x71, 0x20, 0x72, 0x6b, 0x72, 0x70, 0x68, 0x67, 0x76, 0x62, 0x61,
|
||||
0x20, 0x6a, 0x76, 0x79, 0x79, 0x20, 0x70, 0x62, 0x61, 0x67, 0x76,
|
||||
0x61, 0x68, 0x72, 0x20, 0x7a, 0x62, 0x7a, 0x72, 0x61, 0x67, 0x6e,
|
||||
0x65, 0x76, 0x79, 0x6c, 0x2e, 0x0a, 0x00
|
||||
};
|
||||
static void
|
||||
AddTrustedUser(char const *username)
|
||||
{
|
||||
struct passwd *pwent;
|
||||
if (NumTrustedUsers >= MAX_TRUSTED_USERS) {
|
||||
fprintf(stderr, "Too many trusted users (%d max)\n",
|
||||
MAX_TRUSTED_USERS);
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
|
||||
static char const pmsg2[] = {
|
||||
0x4c, 0x62, 0x68, 0x20, 0x6e, 0x63, 0x63, 0x72, 0x6e, 0x65, 0x20,
|
||||
0x67, 0x62, 0x20, 0x6f, 0x72, 0x20, 0x65, 0x68, 0x61, 0x61, 0x76,
|
||||
0x61, 0x74, 0x20, 0x45, 0x72, 0x7a, 0x76, 0x61, 0x71, 0x20, 0x62,
|
||||
0x61, 0x20, 0x6e, 0x20, 0x5a, 0x76, 0x70, 0x65, 0x62, 0x66, 0x62,
|
||||
0x73, 0x67, 0x20, 0x66, 0x6c, 0x66, 0x67, 0x72, 0x7a, 0x2e, 0x20,
|
||||
0x20, 0x56, 0x27, 0x71, 0x20, 0x65, 0x6e, 0x67, 0x75, 0x72, 0x65,
|
||||
0x20, 0x67, 0x75, 0x6e, 0x67, 0x0a, 0x6c, 0x62, 0x68, 0x20, 0x71,
|
||||
0x76, 0x71, 0x61, 0x27, 0x67, 0x2e, 0x20, 0x20, 0x45, 0x72, 0x7a,
|
||||
0x76, 0x61, 0x71, 0x20, 0x72, 0x6b, 0x72, 0x70, 0x68, 0x67, 0x76,
|
||||
0x62, 0x61, 0x20, 0x6a, 0x76, 0x79, 0x79, 0x20, 0x70, 0x62, 0x61,
|
||||
0x67, 0x76, 0x61, 0x68, 0x72, 0x20, 0x7a, 0x62, 0x7a, 0x72, 0x61,
|
||||
0x67, 0x6e, 0x65, 0x76, 0x79, 0x6c, 0x2e, 0x0a, 0x00
|
||||
};
|
||||
pwent = getpwnam(username);
|
||||
if (!pwent) {
|
||||
fprintf(ErrFp, ErrMsg[M_BAD_USER], username);
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
TrustedUsers[NumTrustedUsers] = pwent->pw_uid;
|
||||
NumTrustedUsers++;
|
||||
}
|
||||
|
||||
static void
|
||||
rkrphgvba(int x)
|
||||
ProcessLongOption(char const *arg)
|
||||
{
|
||||
char const *s = (x ? pmsg2 : pmsg1);
|
||||
while(*s) {
|
||||
int c = (int) *s++;
|
||||
c=isalpha(c)?tolower(c)<0x6e?c+13:c-13:c;
|
||||
putchar(c);
|
||||
if (!strcmp(arg, "version")) {
|
||||
printf("%s\n", VERSION);
|
||||
exit(EXIT_SUCCESS);
|
||||
}
|
||||
sleep(5);
|
||||
fprintf(ErrFp, "%s: Unknown long option --%s\n", ArgV[0], arg);
|
||||
}
|
||||
|
||||
static void
|
||||
guess_terminal_background(int *r, int *g, int *b)
|
||||
{
|
||||
int ttyfd;
|
||||
struct pollfd p;
|
||||
int rr, gg, bb;
|
||||
char buf[128];
|
||||
int n;
|
||||
|
||||
*r = -1;
|
||||
*g = -1;
|
||||
*b = -1;
|
||||
|
||||
/* Don't guess if stdout not a terminal unless asked to by @,t */
|
||||
if (should_guess_terminal_background != 2) {
|
||||
if (!isatty(STDOUT_FILENO)) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
ttyfd = open("/dev/tty", O_RDWR);
|
||||
if (ttyfd < 0) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (!isatty(ttyfd)) {
|
||||
/* Not a TTY: Can't guess the color */
|
||||
close(ttyfd);
|
||||
return;
|
||||
}
|
||||
|
||||
if (!tty_init(ttyfd)) {
|
||||
return;
|
||||
}
|
||||
tty_raw(ttyfd);
|
||||
n = write(ttyfd, "\033]11;?\033\\", 8);
|
||||
|
||||
if (n != 8) {
|
||||
/* write failed... WTF? Not much we can do */
|
||||
return;
|
||||
}
|
||||
|
||||
/* Wait up to 0.1s for terminal to respond */
|
||||
p.fd = ttyfd;
|
||||
p.events = POLLIN;
|
||||
if (poll(&p, 1, 100) < 0) {
|
||||
tty_reset(ttyfd);
|
||||
close(ttyfd);
|
||||
return;
|
||||
}
|
||||
if (!(p.revents & POLLIN)) {
|
||||
tty_reset(ttyfd);
|
||||
close(ttyfd);
|
||||
return;
|
||||
}
|
||||
n = read(ttyfd, buf, 127);
|
||||
if (n <= 0) {
|
||||
tty_reset(ttyfd);
|
||||
close(ttyfd);
|
||||
return;
|
||||
}
|
||||
tty_reset(ttyfd);
|
||||
buf[n+1] = 0;
|
||||
if (n < 25) {
|
||||
/* Too short */
|
||||
return;
|
||||
}
|
||||
if (sscanf(buf+5, "rgb:%x/%x/%x", &rr, &gg, &bb) != 3) {
|
||||
/* Couldn't scan color codes */
|
||||
return;
|
||||
}
|
||||
*r = (rr >> 8) & 255;
|
||||
*g = (gg >> 8) & 255;
|
||||
*b = (bb >> 8) & 255;
|
||||
}
|
||||
|
||||
static struct termios orig_termios;
|
||||
|
||||
static int
|
||||
tty_init(int fd)
|
||||
{
|
||||
if (tcgetattr(fd, &orig_termios) < 0) {
|
||||
return 0;
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
static void
|
||||
tty_raw(int fd)
|
||||
{
|
||||
struct termios raw;
|
||||
|
||||
raw = orig_termios;
|
||||
|
||||
raw.c_iflag &= ~(BRKINT | ICRNL | INPCK | ISTRIP | IXON);
|
||||
raw.c_oflag &= ~(OPOST);
|
||||
raw.c_cflag |= (CS8);
|
||||
raw.c_lflag &= ~(ECHO | ICANON | IEXTEN | ISIG);
|
||||
|
||||
/* put terminal in raw mode after flushing */
|
||||
tcsetattr(fd,TCSAFLUSH,&raw);
|
||||
}
|
||||
|
||||
static void
|
||||
tty_reset(int fd)
|
||||
{
|
||||
tcsetattr(fd, TCSAFLUSH, &orig_termios);
|
||||
}
|
||||
|
||||
int
|
||||
GetTerminalBackground(void)
|
||||
{
|
||||
int r, g, b;
|
||||
if (should_guess_terminal_background) {
|
||||
guess_terminal_background(&r, &g, &b);
|
||||
if (r >= 0 && g >= 0 && b >= 0) {
|
||||
if (r+g+b <= 85*3 && r <= 128 && g <= 128 && b <= 128) {
|
||||
TerminalBackground = TERMINAL_BACKGROUND_DARK;
|
||||
} else {
|
||||
TerminalBackground = TERMINAL_BACKGROUND_LIGHT;
|
||||
}
|
||||
}
|
||||
should_guess_terminal_background = 0;
|
||||
}
|
||||
return TerminalBackground;
|
||||
}
|
||||
#endif
|
||||
|
||||
44
src/json.c
44
src/json.c
@@ -249,7 +249,7 @@ json_value * json_parse_ex (json_settings * settings,
|
||||
const json_char * end;
|
||||
json_value * top, * root, * alloc = 0;
|
||||
json_state state = { 0 };
|
||||
long flags = 0;
|
||||
long flags;
|
||||
double num_digits = 0, num_e = 0;
|
||||
double num_fraction = 0;
|
||||
|
||||
@@ -299,7 +299,7 @@ json_value * json_parse_ex (json_settings * settings,
|
||||
if (flags & flag_string)
|
||||
{
|
||||
if (!b)
|
||||
{ sprintf (error, "Unexpected EOF in string (at %d:%d)", line_and_col);
|
||||
{ sprintf (error, "Unexpected EOF in string (at %u:%u)", line_and_col);
|
||||
goto e_failed;
|
||||
}
|
||||
|
||||
@@ -325,7 +325,7 @@ json_value * json_parse_ex (json_settings * settings,
|
||||
(uc_b3 = hex_value (*++ state.ptr)) == 0xFF ||
|
||||
(uc_b4 = hex_value (*++ state.ptr)) == 0xFF)
|
||||
{
|
||||
sprintf (error, "Invalid character value `%c` (at %d:%d)", b, line_and_col);
|
||||
sprintf (error, "Invalid character value `%c` (at %u:%u)", b, line_and_col);
|
||||
goto e_failed;
|
||||
}
|
||||
|
||||
@@ -342,7 +342,7 @@ json_value * json_parse_ex (json_settings * settings,
|
||||
(uc_b3 = hex_value (*++ state.ptr)) == 0xFF ||
|
||||
(uc_b4 = hex_value (*++ state.ptr)) == 0xFF)
|
||||
{
|
||||
sprintf (error, "Invalid character value `%c` (at %d:%d)", b, line_and_col);
|
||||
sprintf (error, "Invalid character value `%c` (at %u:%u)", b, line_and_col);
|
||||
goto e_failed;
|
||||
}
|
||||
|
||||
@@ -472,7 +472,7 @@ json_value * json_parse_ex (json_settings * settings,
|
||||
if (flags & flag_block_comment)
|
||||
{
|
||||
if (!b)
|
||||
{ sprintf (error, "%d:%d: Unexpected EOF in block comment", line_and_col);
|
||||
{ sprintf (error, "%u:%u: Unexpected EOF in block comment", line_and_col);
|
||||
goto e_failed;
|
||||
}
|
||||
|
||||
@@ -488,12 +488,12 @@ json_value * json_parse_ex (json_settings * settings,
|
||||
else if (b == '/')
|
||||
{
|
||||
if (! (flags & (flag_seek_value | flag_done)) && top->type != json_object)
|
||||
{ sprintf (error, "%d:%d: Comment not allowed here", line_and_col);
|
||||
{ sprintf (error, "%u:%u: Comment not allowed here", line_and_col);
|
||||
goto e_failed;
|
||||
}
|
||||
|
||||
if (++ state.ptr == end)
|
||||
{ sprintf (error, "%d:%d: EOF unexpected", line_and_col);
|
||||
{ sprintf (error, "%u:%u: EOF unexpected", line_and_col);
|
||||
goto e_failed;
|
||||
}
|
||||
|
||||
@@ -508,7 +508,7 @@ json_value * json_parse_ex (json_settings * settings,
|
||||
continue;
|
||||
|
||||
default:
|
||||
sprintf (error, "%d:%d: Unexpected `%c` in comment opening sequence", line_and_col, b);
|
||||
sprintf (error, "%u:%u: Unexpected `%c` in comment opening sequence", line_and_col, b);
|
||||
goto e_failed;
|
||||
};
|
||||
}
|
||||
@@ -526,7 +526,7 @@ json_value * json_parse_ex (json_settings * settings,
|
||||
|
||||
default:
|
||||
|
||||
sprintf (error, "%d:%d: Trailing garbage: `%c`",
|
||||
sprintf (error, "%u:%u: Trailing garbage: `%c`",
|
||||
state.cur_line, state.cur_col, b);
|
||||
|
||||
goto e_failed;
|
||||
@@ -545,7 +545,7 @@ json_value * json_parse_ex (json_settings * settings,
|
||||
if (top && top->type == json_array)
|
||||
flags = (flags & ~ (flag_need_comma | flag_seek_value)) | flag_next;
|
||||
else
|
||||
{ sprintf (error, "%d:%d: Unexpected ]", line_and_col);
|
||||
{ sprintf (error, "%u:%u: Unexpected ]", line_and_col);
|
||||
goto e_failed;
|
||||
}
|
||||
|
||||
@@ -561,7 +561,7 @@ json_value * json_parse_ex (json_settings * settings,
|
||||
}
|
||||
else
|
||||
{
|
||||
sprintf (error, "%d:%d: Expected , before %c",
|
||||
sprintf (error, "%u:%u: Expected , before %c",
|
||||
state.cur_line, state.cur_col, b);
|
||||
|
||||
goto e_failed;
|
||||
@@ -576,7 +576,7 @@ json_value * json_parse_ex (json_settings * settings,
|
||||
}
|
||||
else
|
||||
{
|
||||
sprintf (error, "%d:%d: Expected : before %c",
|
||||
sprintf (error, "%u:%u: Expected : before %c",
|
||||
state.cur_line, state.cur_col, b);
|
||||
|
||||
goto e_failed;
|
||||
@@ -702,7 +702,7 @@ json_value * json_parse_ex (json_settings * settings,
|
||||
continue;
|
||||
}
|
||||
else
|
||||
{ sprintf (error, "%d:%d: Unexpected %c when seeking value", line_and_col, b);
|
||||
{ sprintf (error, "%u:%u: Unexpected %c when seeking value", line_and_col, b);
|
||||
goto e_failed;
|
||||
}
|
||||
};
|
||||
@@ -722,7 +722,7 @@ json_value * json_parse_ex (json_settings * settings,
|
||||
case '"':
|
||||
|
||||
if (flags & flag_need_comma)
|
||||
{ sprintf (error, "%d:%d: Expected , before \"", line_and_col);
|
||||
{ sprintf (error, "%u:%u: Expected , before \"", line_and_col);
|
||||
goto e_failed;
|
||||
}
|
||||
|
||||
@@ -747,7 +747,7 @@ json_value * json_parse_ex (json_settings * settings,
|
||||
}
|
||||
/* FALLTHROUGH */
|
||||
default:
|
||||
sprintf (error, "%d:%d: Unexpected `%c` in object", line_and_col, b);
|
||||
sprintf (error, "%u:%u: Unexpected `%c` in object", line_and_col, b);
|
||||
goto e_failed;
|
||||
};
|
||||
|
||||
@@ -765,7 +765,7 @@ json_value * json_parse_ex (json_settings * settings,
|
||||
if (! (flags & flag_num_e))
|
||||
{
|
||||
if (flags & flag_num_zero)
|
||||
{ sprintf (error, "%d:%d: Unexpected `0` before `%c`", line_and_col, b);
|
||||
{ sprintf (error, "%u:%u: Unexpected `0` before `%c`", line_and_col, b);
|
||||
goto e_failed;
|
||||
}
|
||||
|
||||
@@ -814,7 +814,7 @@ json_value * json_parse_ex (json_settings * settings,
|
||||
else if (b == '.' && top->type == json_integer)
|
||||
{
|
||||
if (!num_digits)
|
||||
{ sprintf (error, "%d:%d: Expected digit before `.`", line_and_col);
|
||||
{ sprintf (error, "%u:%u: Expected digit before `.`", line_and_col);
|
||||
goto e_failed;
|
||||
}
|
||||
|
||||
@@ -831,7 +831,7 @@ json_value * json_parse_ex (json_settings * settings,
|
||||
if (top->type == json_double)
|
||||
{
|
||||
if (!num_digits)
|
||||
{ sprintf (error, "%d:%d: Expected digit after `.`", line_and_col);
|
||||
{ sprintf (error, "%u:%u: Expected digit after `.`", line_and_col);
|
||||
goto e_failed;
|
||||
}
|
||||
|
||||
@@ -857,11 +857,11 @@ json_value * json_parse_ex (json_settings * settings,
|
||||
else
|
||||
{
|
||||
if (!num_digits)
|
||||
{ sprintf (error, "%d:%d: Expected digit after `e`", line_and_col);
|
||||
{ sprintf (error, "%u:%u: Expected digit after `e`", line_and_col);
|
||||
goto e_failed;
|
||||
}
|
||||
|
||||
top->u.dbl *= pow (10.0, (flags & flag_num_e_negative ? - num_e : num_e));
|
||||
top->u.dbl *= pow (10.0, ((flags & flag_num_e_negative) ? - num_e : num_e));
|
||||
}
|
||||
|
||||
if (flags & flag_num_negative)
|
||||
@@ -942,7 +942,7 @@ json_value * json_parse_ex (json_settings * settings,
|
||||
|
||||
e_unknown_value:
|
||||
|
||||
sprintf (error, "%d:%d: Unknown value", line_and_col);
|
||||
sprintf (error, "%u:%u: Unknown value", line_and_col);
|
||||
goto e_failed;
|
||||
|
||||
e_alloc_failure:
|
||||
@@ -952,7 +952,7 @@ e_alloc_failure:
|
||||
|
||||
e_overflow:
|
||||
|
||||
sprintf (error, "%d:%d: Too long (caught overflow)", line_and_col);
|
||||
sprintf (error, "%u:%u: Too long (caught overflow)", line_and_col);
|
||||
goto e_failed;
|
||||
|
||||
e_failed:
|
||||
|
||||
@@ -5,7 +5,8 @@
|
||||
/* Header file for language support for various languages. */
|
||||
/* */
|
||||
/* This file is part of REMIND. */
|
||||
/* Copyright (C) 1992-2020 by Dianne Skoll */
|
||||
/* Copyright (C) 1992-2024 by Dianne Skoll */
|
||||
/* SPDX-License-Identifier: GPL-2.0-only */
|
||||
/* */
|
||||
/***************************************************************/
|
||||
|
||||
@@ -23,7 +24,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
|
||||
|
||||
@@ -6,8 +6,9 @@
|
||||
/* */
|
||||
/* This file is part of REMIND. */
|
||||
/* */
|
||||
/* REMIND is Copyright (C) 1992-2020 by Dianne Skoll */
|
||||
/* REMIND is Copyright (C) 1992-2024 by Dianne Skoll */
|
||||
/* This file is Copyright (C) 1993 by Mogens Lynnerup. */
|
||||
/* SPDX-License-Identifier: GPL-2.0-only */
|
||||
/* */
|
||||
/***************************************************************/
|
||||
|
||||
@@ -15,21 +16,13 @@
|
||||
#define L_LANGNAME "Danish"
|
||||
|
||||
/* Day names */
|
||||
#if ISOLATIN1
|
||||
# define L_SUNDAY "S\370ndag"
|
||||
#else
|
||||
# define L_SUNDAY "Soendag"
|
||||
#endif
|
||||
#define L_SUNDAY "Søndag"
|
||||
#define L_MONDAY "Mandag"
|
||||
#define L_TUESDAY "Tirsdag"
|
||||
#define L_WEDNESDAY "Onsdag"
|
||||
#define L_THURSDAY "Torsdag"
|
||||
#define L_FRIDAY "Fredag"
|
||||
#if ISOLATIN1
|
||||
# define L_SATURDAY "L\370rdag"
|
||||
#else
|
||||
# define L_SATURDAY "Loerdag"
|
||||
#endif
|
||||
#define L_SATURDAY "Lørdag"
|
||||
|
||||
/* Month names */
|
||||
#define L_JAN "Januar"
|
||||
@@ -50,19 +43,12 @@
|
||||
#define L_TOMORROW "i morgen"
|
||||
|
||||
/* The default banner */
|
||||
#if ISOLATIN1
|
||||
# define L_BANNER "P\345mindelse for %w, %d. %m, %y%o:"
|
||||
#else
|
||||
# define L_BANNER "Paamindelse for %w, %d. %m, %y%o:"
|
||||
#endif
|
||||
#define L_BANNER "Påmindelse for %w, %d. %m, %y%o:"
|
||||
|
||||
/* "am" and "pm" */
|
||||
#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"
|
||||
@@ -71,11 +57,7 @@
|
||||
#define L_INXDAYS "om %d dage"
|
||||
|
||||
/* "on" as in "on date..." */
|
||||
#if ISOLATIN1
|
||||
# define L_ON "p\345"
|
||||
#else
|
||||
# define L_ON "paa"
|
||||
#endif
|
||||
#define L_ON "på"
|
||||
|
||||
/* Pluralizing - this is a problem for many languages and may require
|
||||
a more drastic fix */
|
||||
@@ -99,13 +81,11 @@
|
||||
|
||||
#define L_AMPM_OVERRIDE(ampm, hour) ampm = (hour < 12) ? (hour<5) ? " om natten" : " om formiddagen" : (hour > 17) ? " om aftenen" : " om eftermiddagen";
|
||||
#define L_ORDINAL_OVERRIDE plu = ".";
|
||||
#define L_A_OVER if (altmode == '*') { sprintf(s, "%s, den %d. %s %d", DayName[jul%7], d, MonthName[m], y); } else { sprintf(s, "%s %s, den %d. %s %d", L_ON, DayName[jul%7], d, MonthName[m], y); }
|
||||
#define L_A_OVER if (altmode == '*') { sprintf(s, "%s, den %d. %s %d", DayName[dse%7], d, MonthName[m], y); } else { sprintf(s, "%s %s, den %d. %s %d", L_ON, DayName[dse%7], d, MonthName[m], y); }
|
||||
#define L_E_OVER sprintf(s, "den %02d%c%02d%c%04d", d, DateSep, m+1, DateSep, y);
|
||||
#define L_F_OVER sprintf(s, "den %02d%c%02d%c%04d", m+1, DateSep, d, DateSep, y);
|
||||
#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_G_OVER if (altmode == '*') { sprintf(s, "%s, den %d. %s", DayName[dse%7], d, MonthName[m]); } else { sprintf(s, "%s %s, den %d. %s", L_ON, DayName[dse%7], d, MonthName[m]); }
|
||||
#define L_H_OVER sprintf(s, "den %02d%c%02d", d, DateSep, m+1);
|
||||
#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 */
|
||||
|
||||
@@ -11,7 +11,8 @@
|
||||
/* Further corrections by Erik-Jan Vens */
|
||||
/* */
|
||||
/* This file is part of REMIND. */
|
||||
/* Copyright (C) 1992-2020 by Dianne Skoll */
|
||||
/* Copyright (C) 1992-2024 by Dianne Skoll */
|
||||
/* SPDX-License-Identifier: GPL-2.0-only */
|
||||
/* */
|
||||
/***************************************************************/
|
||||
|
||||
@@ -52,9 +53,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 +89,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 */
|
||||
|
||||
|
||||
@@ -5,7 +5,8 @@
|
||||
/* Support for the English language. */
|
||||
/* */
|
||||
/* This file is part of REMIND. */
|
||||
/* Copyright (C) 1992-2020 by Dianne Skoll */
|
||||
/* Copyright (C) 1992-2024 by Dianne Skoll */
|
||||
/* SPDX-License-Identifier: GPL-2.0-only */
|
||||
/* */
|
||||
/***************************************************************/
|
||||
|
||||
@@ -46,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 "ago"
|
||||
#define L_FROMNOW "from now"
|
||||
@@ -72,11 +70,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 */
|
||||
|
||||
@@ -11,7 +11,8 @@
|
||||
/* */
|
||||
/* This file is part of REMIND. */
|
||||
/* This file is Copyright (C) 1993-1998 by Mikko Silvonen. */
|
||||
/* REMIND is Copyright (C) 1992-2020 by Dianne Skoll */
|
||||
/* REMIND is Copyright (C) 1992-2024 by Dianne Skoll */
|
||||
/* SPDX-License-Identifier: GPL-2.0-only */
|
||||
/* */
|
||||
/***************************************************************/
|
||||
|
||||
@@ -33,16 +34,8 @@
|
||||
#define L_MAR "maaliskuu"
|
||||
#define L_APR "huhtikuu"
|
||||
#define L_MAY "toukokuu"
|
||||
#if ISOLATIN1
|
||||
#define L_JUN "kes\xE4kuu"
|
||||
#define L_JUL "hein\xE4kuu"
|
||||
#elif IBMEXTENDED
|
||||
#define L_JUN "kes\x84kuu"
|
||||
#define L_JUL "hein\x84kuu"
|
||||
#else
|
||||
#define L_JUN "kes{kuu"
|
||||
#define L_JUL "hein{kuu"
|
||||
#endif
|
||||
#define L_JUN "kesäkuu"
|
||||
#define L_JUL "heinäkuu"
|
||||
#define L_AUG "elokuu"
|
||||
#define L_SEP "syyskuu"
|
||||
#define L_OCT "lokakuu"
|
||||
@@ -50,13 +43,7 @@
|
||||
#define L_DEC "joulukuu"
|
||||
|
||||
/* Today and tomorrow */
|
||||
#if ISOLATIN1
|
||||
#define L_TODAY "t\xE4n\xE4\xE4n"
|
||||
#elif IBMEXTENDED
|
||||
#define L_TODAY "t\x84n\x84\x84n"
|
||||
#else
|
||||
#define L_TODAY "t{n{{n"
|
||||
#endif
|
||||
#define L_TODAY "tänään"
|
||||
#define L_TOMORROW "huomenna"
|
||||
|
||||
/* The default banner */
|
||||
@@ -66,21 +53,12 @@
|
||||
#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"
|
||||
|
||||
/* "in %d days' time" */
|
||||
#if ISOLATIN1
|
||||
#define L_INXDAYS "%d p\xE4iv\xE4n kuluttua"
|
||||
#elif IBMEXTENDED
|
||||
#define L_INXDAYS "%d p\x84iv\x84n kuluttua"
|
||||
#else
|
||||
#define L_INXDAYS "%d p{iv{n kuluttua"
|
||||
#endif
|
||||
#define L_INXDAYS "%d päivän kuluttua"
|
||||
|
||||
/* "on" as in "on date...", but in Finnish it is a case ending;
|
||||
L_PARTIT is the partitive ending appended to -kuu and -tai */
|
||||
@@ -90,13 +68,7 @@
|
||||
/* Pluralizing - this is a problem for many languages and may require
|
||||
a more drastic fix */
|
||||
/* The partitive ending of "day" */
|
||||
#if ISOLATIN1
|
||||
#define L_PLURAL "\xE4"
|
||||
#elif IBMEXTENDED
|
||||
#define L_PLURAL "\x84"
|
||||
#else
|
||||
#define L_PLURAL "{"
|
||||
#endif
|
||||
#define L_PLURAL "ä"
|
||||
|
||||
/* Minutes, hours, at, etc */
|
||||
#define L_NOW "nyt"
|
||||
@@ -120,9 +92,8 @@
|
||||
/* Define any overrides here, such as L_ORDINAL_OVERRIDE, L_A_OVER, etc.
|
||||
See the file dosubst.c for more info. */
|
||||
|
||||
#if ISOLATIN1
|
||||
#define L_ORDINAL_OVERRIDE switch(d) { \
|
||||
case 1: plu = ":sen\xE4"; break; \
|
||||
case 1: plu = ":senä"; break; \
|
||||
case 2: plu = ":sena"; break; \
|
||||
default: \
|
||||
switch(d%10) { \
|
||||
@@ -130,49 +101,22 @@
|
||||
case 3: \
|
||||
case 6: \
|
||||
case 8: plu = ":ntena"; break; \
|
||||
default: plu = ":nten\xE4"; break; \
|
||||
default: plu = ":ntenä"; break; \
|
||||
} \
|
||||
}
|
||||
#elif IBMEXTENDED
|
||||
#define L_ORDINAL_OVERRIDE switch(d) { \
|
||||
case 1: plu = ":sen\x84"; break; \
|
||||
case 2: plu = ":sena"; break; \
|
||||
default: \
|
||||
switch(d%10) { \
|
||||
case 2: \
|
||||
case 3: \
|
||||
case 6: \
|
||||
case 8: plu = ":ntena"; break; \
|
||||
default: plu = ":nten\x84"; break; \
|
||||
} \
|
||||
}
|
||||
#else
|
||||
#define L_ORDINAL_OVERRIDE switch(d) { \
|
||||
case 1: plu = ":sen{"; break; \
|
||||
case 2: plu = ":sena"; break; \
|
||||
default: \
|
||||
switch(d%10) { \
|
||||
case 2: \
|
||||
case 3: \
|
||||
case 6: \
|
||||
case 8: plu = ":ntena"; break; \
|
||||
default: plu = ":nten{"; break; \
|
||||
} \
|
||||
}
|
||||
#endif
|
||||
#define L_A_OVER if (altmode == '*') { sprintf(s, "%s %d. %s %d", DayName[jul%7], d, MonthName[m], y); } else { sprintf(s, "%s%s %d. %s%s %d", DayName[jul%7], L_ON, d, MonthName[m], L_PARTIT, y); }
|
||||
#define L_C_OVER if (altmode == '*') { sprintf(s, "%s", DayName[jul%7]); } else { sprintf(s, "%s%s", DayName[jul%7], L_ON); }
|
||||
#define L_A_OVER if (altmode == '*') { sprintf(s, "%s %d. %s %d", DayName[dse%7], d, MonthName[m], y); } else { sprintf(s, "%s%s %d. %s%s %d", DayName[dse%7], L_ON, d, MonthName[m], L_PARTIT, y); }
|
||||
#define L_C_OVER if (altmode == '*') { sprintf(s, "%s", DayName[dse%7]); } else { sprintf(s, "%s%s", DayName[dse%7], L_ON); }
|
||||
#define L_E_OVER sprintf(s, "%02d%c%02d%c%04d", d, DateSep, m+1, DateSep, y);
|
||||
#define L_F_OVER sprintf(s, "%02d%c%02d%c%04d", m+1, DateSep, d, DateSep, y);
|
||||
#define L_G_OVER if (altmode == '*') { sprintf(s, "%s %d. %s", DayName[jul%7], d, MonthName[m]); } else { sprintf(s, "%s%s %d. %s%s", DayName[jul%7], L_ON, d, MonthName[m], L_PARTIT); }
|
||||
#define L_G_OVER if (altmode == '*') { sprintf(s, "%s %d. %s", DayName[dse%7], d, MonthName[m]); } else { sprintf(s, "%s%s %d. %s%s", DayName[dse%7], L_ON, d, MonthName[m], L_PARTIT); }
|
||||
#define L_H_OVER sprintf(s, "%02d%c%02d", d, DateSep, m+1);
|
||||
#define L_I_OVER sprintf(s, "%02d%c%02d", m+1, DateSep, d);
|
||||
#define L_J_OVER if (altmode == '*') { sprintf(s, "%s %sn %d%s %d", DayName[jul%7], MonthName[m], d, plu, y); } else { sprintf(s, "%s%s %sn %d%s %d", DayName[jul%7], L_ON, MonthName[m], d, plu, y); }
|
||||
#define L_K_OVER if (altmode == '*') { sprintf(s, "%s %sn %d%s", DayName[jul%7], MonthName[m], d, plu); } else { sprintf(s, "%s%s %sn %d%s", DayName[jul%7], L_ON, MonthName[m], d, plu); }
|
||||
#define L_J_OVER if (altmode == '*') { sprintf(s, "%s %sn %d%s %d", DayName[dse%7], MonthName[m], d, plu, y); } else { sprintf(s, "%s%s %sn %d%s %d", DayName[dse%7], L_ON, MonthName[m], d, plu, y); }
|
||||
#define L_K_OVER if (altmode == '*') { sprintf(s, "%s %sn %d%s", DayName[dse%7], MonthName[m], d, plu); } else { sprintf(s, "%s%s %sn %d%s", DayName[dse%7], L_ON, MonthName[m], d, plu); }
|
||||
#define L_L_OVER sprintf(s, "%04d%c%02d%c%02d", y, DateSep, m+1, DateSep, d);
|
||||
#define L_Q_OVER sprintf(s, "n");
|
||||
#define L_U_OVER if (altmode == '*') { sprintf(s, "%s %d%s %s %d", DayName[jul%7], d, plu, MonthName[m], y); } else { sprintf(s, "%s%s %d%s %s%s %d", DayName[jul%7], L_ON, d, plu, MonthName[m], L_PARTIT, y); }
|
||||
#define L_V_OVER if (altmode == '*') { sprintf(s, "%s %d%s %s", DayName[jul%7], d, plu, MonthName[m]); } else { sprintf(s, "%s%s %d%s %s%s", DayName[jul%7], L_ON, d, plu, MonthName[m], L_PARTIT); }
|
||||
#define L_U_OVER if (altmode == '*') { sprintf(s, "%s %d%s %s %d", DayName[dse%7], d, plu, MonthName[m], y); } else { sprintf(s, "%s%s %d%s %s%s %d", DayName[dse%7], L_ON, d, plu, MonthName[m], L_PARTIT, y); }
|
||||
#define L_V_OVER if (altmode == '*') { sprintf(s, "%s %d%s %s", DayName[dse%7], d, plu, MonthName[m]); } else { sprintf(s, "%s%s %d%s %s%s", DayName[dse%7], L_ON, d, plu, MonthName[m], L_PARTIT); }
|
||||
#define L_1_OVER \
|
||||
if (tdiff == 0) \
|
||||
sprintf(s, "%s", L_NOW); \
|
||||
@@ -192,111 +136,109 @@ else { \
|
||||
} \
|
||||
sprintf(s + strlen(s), when); \
|
||||
}
|
||||
#endif /* L_IN_DOSUBST */
|
||||
|
||||
/* The next ones are used only when MK_GLOBALS is set */
|
||||
#ifdef MK_GLOBALS
|
||||
#define L_ERR_OVERRIDE 1
|
||||
EXTERN char *ErrMsg[] =
|
||||
{
|
||||
#if ISOLATIN1
|
||||
"Ok",
|
||||
"Puuttuva ']'",
|
||||
"Puuttuva lainausmerkki",
|
||||
"Liian monimutkainen lauseke - liikaa operaattoreita",
|
||||
"Liian monimutkainen lauseke - liikaa operandeja",
|
||||
"Puuttuva ')'",
|
||||
"M\xE4\xE4rittelem\xE4t\xF6n funktio",
|
||||
"Määrittelemätön funktio",
|
||||
"Virheellinen merkki",
|
||||
"Kaksipaikkainen operaattori puuttuu",
|
||||
"Muisti loppui",
|
||||
"Virheellinen luku",
|
||||
"Operaattoripino tyhj\xE4 - sis\xE4inen virhe",
|
||||
"Muuttujapino tyhj\xE4 - sis\xE4inen virhe",
|
||||
"Operaattoripino tyhjä - sisäinen virhe",
|
||||
"Muuttujapino tyhjä - sisäinen virhe",
|
||||
"Tyyppimuunnos ei onnistu",
|
||||
"Virheellinen tyyppi",
|
||||
"Liian suuri p\xE4iv\xE4ys",
|
||||
"Pinovirhe - sis\xE4inen virhe",
|
||||
"Liian suuri päiväys",
|
||||
"Pinovirhe - sisäinen virhe",
|
||||
"Jako nollalla",
|
||||
"M\xE4\xE4rittelem\xE4t\xF6n funktio",
|
||||
"Määrittelemätön funktio",
|
||||
"Odottamaton rivin loppu",
|
||||
"Odottamaton tiedoston loppu",
|
||||
"Sy\xF6tt\xF6- tai tulostusvirhe",
|
||||
"Liian pitk\xE4 rivi",
|
||||
"Sis\xE4inen virhe",
|
||||
"Virheellinen p\xE4iv\xE4ys",
|
||||
"Liian v\xE4h\xE4n argumentteja",
|
||||
"Syöttö- tai tulostusvirhe",
|
||||
"Liian pitkä rivi",
|
||||
"Sisäinen virhe",
|
||||
"Virheellinen päiväys",
|
||||
"Liian vähän argumentteja",
|
||||
"Liian paljon argumentteja",
|
||||
"Virheellinen aika",
|
||||
"Liian suuri luku",
|
||||
"Liian pieni luku",
|
||||
"Tiedoston avaus ei onnistu",
|
||||
"Liian monta sis\xE4kk\xE4ist\xE4 INCLUDEa",
|
||||
"J\xE4sennysvirhe",
|
||||
"Liian monta sisäkkäistä INCLUDEa",
|
||||
"Jäsennysvirhe",
|
||||
"Laukaisuhetken laskenta ei onnistu",
|
||||
"Liian monta sis\xE4kk\xE4ist\xE4 IF-lausetta",
|
||||
"Liian monta sisäkkäistä IF-lausetta",
|
||||
"ELSE ilman IF-lausetta",
|
||||
"ENDIF ilman IF-lausetta",
|
||||
"Kaikkia viikonp\xE4ivi\xE4 ei voi j\xE4tt\xE4\xE4 pois",
|
||||
"Ylim\xE4\xE4r\xE4isi\xE4 merkkej\xE4 rivill\xE4",
|
||||
"Kaikkia viikonpäiviä ei voi jättää pois",
|
||||
"Ylimääräisiä merkkejä rivillä",
|
||||
"POP-OMIT-CONTEXT ilman PUSH-OMIT-CONTEXTia",
|
||||
"RUN-lauseen k\xE4ytt\xF6 estetty",
|
||||
"RUN-lauseen käyttö estetty",
|
||||
"Arvoaluevirhe",
|
||||
"Virheellinen tunniste",
|
||||
"Rekursiivinen funktiokutsu havaittu",
|
||||
"",
|
||||
"J\xE4rjestelm\xE4muuttujan muuttaminen ei onnistu",
|
||||
"C-kirjastofunktio ei pysty esitt\xE4m\xE4\xE4n p\xE4iv\xE4yst\xE4 tai aikaa",
|
||||
"Sis\xE4isen funktion m\xE4\xE4ritelm\xE4\xE4 yritettiin muuttaa",
|
||||
"Lausekkeessa ei voi olla sis\xE4kk\xE4isi\xE4 funktiom\xE4\xE4ritelmi\xE4",
|
||||
"P\xE4iv\xE4yksen t\xE4ytyy olla t\xE4ydellinen toistokertoimessa",
|
||||
"Järjestelmämuuttujan muuttaminen ei onnistu",
|
||||
"C-kirjastofunktio ei pysty esittämään päiväystä tai aikaa",
|
||||
"Sisäisen funktion määritelmää yritettiin muuttaa",
|
||||
"Lausekkeessa ei voi olla sisäkkäisiä funktiomääritelmiä",
|
||||
"Päiväyksen täytyy olla täydellinen toistokertoimessa",
|
||||
"Vuosi annettu kahdesti",
|
||||
"Kuukausi annettu kahdesti",
|
||||
"P\xE4iv\xE4 annettu kahdesti",
|
||||
"Päivä annettu kahdesti",
|
||||
"Tuntematon sana tai merkki",
|
||||
"OMIT-komennossa on annettava kuukausi ja p\xE4iv\xE4",
|
||||
"OMIT-komennossa on annettava kuukausi",
|
||||
"Liian monta osittaista OMIT-komentoa",
|
||||
"Liian monta t\xE4ydellist\xE4 OMIT-komentoa",
|
||||
"Liian monta täydellistä OMIT-komentoa",
|
||||
"Varoitus: PUSH-OMIT-CONTEXT ilman POP-OMIT-CONTEXTia",
|
||||
"Virhe tiedoston luvussa",
|
||||
"Pilkku puuttuu",
|
||||
"Virheellinen juutalainen p\xE4iv\xE4ys",
|
||||
"IIF vaatii parittoman m\xE4\xE4r\xE4n argumentteja",
|
||||
"Virheellinen juutalainen päiväys",
|
||||
"IIF vaatii parittoman määrän argumentteja",
|
||||
"Varoitus: puuttuva ENDIF",
|
||||
"Pilkku puuttuu",
|
||||
"Viikonp\xE4iv\xE4 annettu kahdesti",
|
||||
"K\xE4yt\xE4 vain yht\xE4 komennoista BEFORE, AFTER ja SKIP",
|
||||
"Sis\xE4kk\xE4isi\xE4 MSG-, MSF- ja RUN-lauseita ei voi k\xE4ytt\xE4\xE4 lausekkeessa",
|
||||
"Viikonpäivä annettu kahdesti",
|
||||
"Käytä vain yhtä komennoista BEFORE, AFTER ja SKIP",
|
||||
"Sisäkkäisiä MSG-, MSF- ja RUN-lauseita ei voi käyttää lausekkeessa",
|
||||
"Toistokerroin annettu kahdesti",
|
||||
"Delta-arvo annettu kahdesti",
|
||||
"Peruutusarvo annettu kahdesti",
|
||||
"ONCE-avainsanaa k\xE4ytetty kahdesti. (Hah.)",
|
||||
"AT-sanan per\xE4st\xE4 puuttuu aika",
|
||||
"THROUGH/UNTIL-sanaa k\xE4ytetty kahdesti",
|
||||
"Ep\xE4t\xE4ydellinen p\xE4iv\xE4ys",
|
||||
"FROM/SCANFROM-sanaa k\xE4ytetty kahdesti",
|
||||
"ONCE-avainsanaa käytetty kahdesti. (Hah.)",
|
||||
"AT-sanan perästä puuttuu aika",
|
||||
"THROUGH/UNTIL-sanaa käytetty kahdesti",
|
||||
"Epätäydellinen päiväys",
|
||||
"FROM/SCANFROM-sanaa käytetty kahdesti",
|
||||
"Muuttuja",
|
||||
"Arvo",
|
||||
"*M\xC4\xC4RITTELEM\xC4T\xD6N*",
|
||||
"Siirryt\xE4\xE4n funktioon",
|
||||
"*MÄÄRITTELEMÄTÖN*",
|
||||
"Siirrytään funktioon",
|
||||
"Poistutaan funktiosta",
|
||||
"Vanhentunut",
|
||||
"fork() ep\xE4onnistui - jonomuistutukset eiv\xE4t toimi",
|
||||
"fork() epäonnistui - jonomuistutukset eivät toimi",
|
||||
"Tiedoston avaus ei onnistu",
|
||||
"Virheellinen j\xE4rjestelm\xE4p\xE4iv\xE4ys: vuosi on v\xE4hemm\xE4n kuin %d\n",
|
||||
"Tuntematon virheenetsint\xE4tarkenne '%c'\n",
|
||||
"Virheellinen järjestelmäpäiväys: vuosi on vähemmän kuin %d\n",
|
||||
"Tuntematon virheenetsintätarkenne '%c'\n",
|
||||
"Tuntematon tarkenne '%c'\n",
|
||||
"Tuntematon k\xE4ytt\xE4j\xE4 '%s'\n",
|
||||
"Ryhm\xE4numeron vaihto %d:ksi ei onnistunut\n",
|
||||
"K\xE4ytt\xE4j\xE4numeron vaihto %d:ksi ei onnistunut\n",
|
||||
"Muisti ei riit\xE4 ymp\xE4rist\xF6lle\n",
|
||||
"Tuntematon käyttäjä '%s'\n",
|
||||
"Ryhmänumeron vaihto %d:ksi ei onnistunut\n",
|
||||
"Käyttäjänumeron vaihto %d:ksi ei onnistunut\n",
|
||||
"Muisti ei riitä ympäristölle\n",
|
||||
"Puuttuva '='-merkki",
|
||||
"Puuttuva muuttujanimi",
|
||||
"Puuttuva lauseke",
|
||||
"P\xE4iv\xE4n asetus %s:ksi ei onnitus\n",
|
||||
"Päivän asetus %s:ksi ei onnitus\n",
|
||||
"Remind: tarkenne '-i': %s\n",
|
||||
"Ei viestej\xE4.",
|
||||
"%d viesti(\xE4) t\xE4m\xE4n p\xE4iv\xE4n jonossa.\n",
|
||||
"Ei viestejä.",
|
||||
"%d viesti(ä) tämän päivän jonossa.\n",
|
||||
"Numero puuttuu",
|
||||
"Virheellinen funktio WARN-lausekkeessa",
|
||||
"Can't convert between time zones",
|
||||
@@ -304,221 +246,6 @@ EXTERN char *ErrMsg[] =
|
||||
"String too long",
|
||||
"Time specified twice",
|
||||
"Cannot specify DURATION without specifying AT"
|
||||
|
||||
#elif IBMEXTENDED
|
||||
"Ok",
|
||||
"Puuttuva ']'",
|
||||
"Puuttuva lainausmerkki",
|
||||
"Liian monimutkainen lauseke - liikaa operaattoreita",
|
||||
"Liian monimutkainen lauseke - liikaa operandeja",
|
||||
"Puuttuva ')'",
|
||||
"M\x84\x84rittelem\x84t\x94n funktio",
|
||||
"Virheellinen merkki",
|
||||
"Kaksipaikkainen operaattori puuttuu",
|
||||
"Muisti loppui",
|
||||
"Virheellinen luku",
|
||||
"Operaattoripino tyhj\x84 - sis\x84inen virhe",
|
||||
"Muuttujapino tyhj\x84 - sis\x84inen virhe",
|
||||
"Tyyppimuunnos ei onnistu",
|
||||
"Virheellinen tyyppi",
|
||||
"Liian suuri p\x84iv\x84ys",
|
||||
"Pinovirhe - sis\x84inen virhe",
|
||||
"Jako nollalla",
|
||||
"M\x84\x84rittelem\x84t\x94n funktio",
|
||||
"Odottamaton rivin loppu",
|
||||
"Odottamaton tiedoston loppu",
|
||||
"Sy\x94tt\x94- tai tulostusvirhe",
|
||||
"Liian pitk\x84 rivi",
|
||||
"Sis\x84inen virhe",
|
||||
"Virheellinen p\x84iv\x84ys",
|
||||
"Liian v\x84h\x84n argumentteja",
|
||||
"Liian paljon argumentteja",
|
||||
"Virheellinen aika",
|
||||
"Liian suuri luku",
|
||||
"Liian pieni luku",
|
||||
"Tiedoston avaus ei onnistu",
|
||||
"Liian monta sis\x84kk\x84ist\x84 INCLUDEa",
|
||||
"J\x84sennysvirhe",
|
||||
"Laukaisuhetken laskenta ei onnistu",
|
||||
"Liian monta sis\x84kk\x84ist\x84 IF-lausetta",
|
||||
"ELSE ilman IF-lausetta",
|
||||
"ENDIF ilman IF-lausetta",
|
||||
"Kaikkia viikonp\x84ivi\x84 ei voi j\x84tt\x84\x84 pois",
|
||||
"Ylim\x84\x84r\x84isi\x84 merkkej\x84 rivill\x84",
|
||||
"POP-OMIT-CONTEXT ilman PUSH-OMIT-CONTEXTia",
|
||||
"RUN-lauseen k\x84ytt\x94 estetty",
|
||||
"Arvoaluevirhe",
|
||||
"Virheellinen tunniste",
|
||||
"Rekursiivinen funktiokutsu havaittu",
|
||||
"",
|
||||
"J\x84rjestelm\x84muuttujan muuttaminen ei onnistu",
|
||||
"C-kirjastofunktio ei pysty esitt\x84m\x84\x84n p\x84iv\x84yst\x84 tai aikaa",
|
||||
"Sis\x84isen funktion m\x84\x84ritelm\x84\x84 yritettiin muuttaa",
|
||||
"Lausekkeessa ei voi olla sis\x84kk\x84isi\x84 funktiom\x84\x84ritelmi\x84",
|
||||
"P\x84iv\x84yksen t\x84ytyy olla t\x84ydellinen toistokertoimessa",
|
||||
"Vuosi annettu kahdesti",
|
||||
"Kuukausi annettu kahdesti",
|
||||
"P\x84iv\x84 annettu kahdesti",
|
||||
"Tuntematon sana tai merkki",
|
||||
"OMIT-komennossa on annettava kuukausi ja p\x84iv\x84",
|
||||
"Liian monta osittaista OMIT-komentoa",
|
||||
"Liian monta t\x84ydellist\x84 OMIT-komentoa",
|
||||
"Varoitus: PUSH-OMIT-CONTEXT ilman POP-OMIT-CONTEXTia",
|
||||
"Virhe tiedoston luvussa",
|
||||
"Pilkku puuttuu",
|
||||
"Virheellinen juutalainen p\x84iv\x84ys",
|
||||
"IIF vaatii parittoman m\x84\x84r\x84n argumentteja",
|
||||
"Varoitus: puuttuva ENDIF",
|
||||
"Pilkku puuttuu",
|
||||
"Viikonp\x84iv\x84 annettu kahdesti",
|
||||
"K\x84yt\x84 vain yht\x84 komennoista BEFORE, AFTER ja SKIP",
|
||||
"Sis\x84kk\x84isi\x84 MSG-, MSF- ja RUN-lauseita ei voi k\x84ytt\x84\x84 lausekkeessa",
|
||||
"Toistokerroin annettu kahdesti",
|
||||
"Delta-arvo annettu kahdesti",
|
||||
"Peruutusarvo annettu kahdesti",
|
||||
"ONCE-avainsanaa k\x84ytetty kahdesti. (Hah.)",
|
||||
"AT-sanan per\x84st\x84 puuttuu aika",
|
||||
"THROUGH/UNTIL-sanaa k\x84ytetty kahdesti",
|
||||
"Ep\x84t\x84ydellinen p\x84iv\x84ys",
|
||||
"FROM/SCANFROM-sanaa k\x84ytetty kahdesti",
|
||||
"Muuttuja",
|
||||
"Arvo",
|
||||
"*M\x8E\x8ERITTELEM\x8ET\x99N*",
|
||||
"Siirryt\x84\x84n funktioon",
|
||||
"Poistutaan funktiosta",
|
||||
"Vanhentunut",
|
||||
"fork() ep\x84onnistui - jonomuistutukset eiv\x84t toimi",
|
||||
"Tiedoston avaus ei onnistu",
|
||||
"Virheellinen j\x84rjestelm\x84p\x84iv\x84ys: vuosi on v\x84hemm\x84n kuin %d\n",
|
||||
"Tuntematon virheenetsint\x84tarkenne '%c'\n",
|
||||
"Tuntematon tarkenne '%c'\n",
|
||||
"Tuntematon k\x84ytt\x84j\x84 '%s'\n",
|
||||
"Ryhm\x84numeron vaihto %d:ksi ei onnistunut\n",
|
||||
"K\x84ytt\x84j\x84numeron vaihto %d:ksi ei onnistunut\n",
|
||||
"Muisti ei riit\x84 ymp\x84rist\x94lle\n",
|
||||
"Puuttuva '='-merkki",
|
||||
"Puuttuva muuttujanimi",
|
||||
"Puuttuva lauseke",
|
||||
"P\x84iv\x84n asetus %s:ksi ei onnitus\n",
|
||||
"Remind: tarkenne '-i': %s\n",
|
||||
"Ei viestej\x84.",
|
||||
"%d viesti(\x84) t\x84m\x84n p\x84iv\x84n jonossa.\n",
|
||||
"Numero puuttuu"
|
||||
"Virheellinen funktio WARN-lausekkeessa",
|
||||
"Can't convert between time zones",
|
||||
"No files matching *.rem",
|
||||
"String too long",
|
||||
"Time specified twice",
|
||||
"Cannot specify DURATION without specifying AT"
|
||||
|
||||
#else
|
||||
"Ok",
|
||||
"Puuttuva ']'",
|
||||
"Puuttuva lainausmerkki",
|
||||
"Liian monimutkainen lauseke - liikaa operaattoreita",
|
||||
"Liian monimutkainen lauseke - liikaa operandeja",
|
||||
"Puuttuva ')'",
|
||||
"M{{rittelem{t|n funktio",
|
||||
"Virheellinen merkki",
|
||||
"Kaksipaikkainen operaattori puuttuu",
|
||||
"Muisti loppui",
|
||||
"Virheellinen luku",
|
||||
"Operaattoripino tyhj{ - sis{inen virhe",
|
||||
"Muuttujapino tyhj{ - sis{inen virhe",
|
||||
"Tyyppimuunnos ei onnistu",
|
||||
"Virheellinen tyyppi",
|
||||
"Liian suuri p{iv{ys",
|
||||
"Pinovirhe - sis{inen virhe",
|
||||
"Jako nollalla",
|
||||
"M{{rittelem{t|n funktio",
|
||||
"Odottamaton rivin loppu",
|
||||
"Odottamaton tiedoston loppu",
|
||||
"Sy|tt|- tai tulostusvirhe",
|
||||
"Liian pitk{ rivi",
|
||||
"Sis{inen virhe",
|
||||
"Virheellinen p{iv{ys",
|
||||
"Liian v{h{n argumentteja",
|
||||
"Liian paljon argumentteja",
|
||||
"Virheellinen aika",
|
||||
"Liian suuri luku",
|
||||
"Liian pieni luku",
|
||||
"Tiedoston avaus ei onnistu",
|
||||
"Liian monta sis{kk{ist{ INCLUDEa",
|
||||
"J{sennysvirhe",
|
||||
"Laukaisuhetken laskenta ei onnistu",
|
||||
"Liian monta sis{kk{ist{ IF-lausetta",
|
||||
"ELSE ilman IF-lausetta",
|
||||
"ENDIF ilman IF-lausetta",
|
||||
"Kaikkia viikonp{ivi{ ei voi j{tt{{ pois",
|
||||
"Ylim{{r{isi{ merkkej{ rivill{",
|
||||
"POP-OMIT-CONTEXT ilman PUSH-OMIT-CONTEXTia",
|
||||
"RUN-lauseen k{ytt| estetty",
|
||||
"Arvoaluevirhe",
|
||||
"Virheellinen tunniste",
|
||||
"Rekursiivinen funktiokutsu havaittu",
|
||||
"",
|
||||
"J{rjestelm{muuttujan muuttaminen ei onnistu",
|
||||
"C-kirjastofunktio ei pysty esitt{m{{n p{iv{yst{ tai aikaa",
|
||||
"Sis{isen funktion m{{ritelm{{ yritettiin muuttaa",
|
||||
"Lausekkeessa ei voi olla sis{kk{isi{ funktiom{{ritelmi{",
|
||||
"P{iv{yksen t{ytyy olla t{ydellinen toistokertoimessa",
|
||||
"Vuosi annettu kahdesti",
|
||||
"Kuukausi annettu kahdesti",
|
||||
"P{iv{ annettu kahdesti",
|
||||
"Tuntematon sana tai merkki",
|
||||
"OMIT-komennossa on annettava kuukausi ja p{iv{",
|
||||
"Liian monta osittaista OMIT-komentoa",
|
||||
"Liian monta t{ydellist{ OMIT-komentoa",
|
||||
"Varoitus: PUSH-OMIT-CONTEXT ilman POP-OMIT-CONTEXTia",
|
||||
"Virhe tiedoston luvussa",
|
||||
"Pilkku puuttuu",
|
||||
"Virheellinen juutalainen p{iv{ys",
|
||||
"IIF vaatii parittoman m{{r{n argumentteja",
|
||||
"Varoitus: puuttuva ENDIF",
|
||||
"Pilkku puuttuu",
|
||||
"Viikonp{iv{ annettu kahdesti",
|
||||
"K{yt{ vain yht{ komennoista BEFORE, AFTER ja SKIP",
|
||||
"Sis{kk{isi{ MSG-, MSF- ja RUN-lauseita ei voi k{ytt{{ lausekkeessa",
|
||||
"Toistokerroin annettu kahdesti",
|
||||
"Delta-arvo annettu kahdesti",
|
||||
"Peruutusarvo annettu kahdesti",
|
||||
"ONCE-avainsanaa k{ytetty kahdesti. (Hah.)",
|
||||
"AT-sanan per{st{ puuttuu aika",
|
||||
"THROUGH/UNTIL-sanaa k{ytetty kahdesti",
|
||||
"Ep{t{ydellinen p{iv{ys",
|
||||
"FROM/SCANFROM-sanaa k{ytetty kahdesti",
|
||||
"Muuttuja",
|
||||
"Arvo",
|
||||
"*M[[RITTELEM[T\\N*",
|
||||
"Siirryt{{n funktioon",
|
||||
"Poistutaan funktiosta",
|
||||
"Vanhentunut",
|
||||
"fork() ep{onnistui - jonomuistutukset eiv{t toimi",
|
||||
"Tiedoston avaus ei onnistu",
|
||||
"Virheellinen j{rjestelm{p{iv{ys: vuosi on v{hemm{n kuin %d\n",
|
||||
"Tuntematon virheenetsint{tarkenne '%c'\n",
|
||||
"Tuntematon tarkenne '%c'\n",
|
||||
"Tuntematon k{ytt{j{ '%s'\n",
|
||||
"Ryhm{numeron vaihto %d:ksi ei onnistunut\n",
|
||||
"K{ytt{j{numeron vaihto %d:ksi ei onnistunut\n",
|
||||
"Muisti ei riit{ ymp{rist|lle\n",
|
||||
"Puuttuva '='-merkki",
|
||||
"Puuttuva muuttujanimi",
|
||||
"Puuttuva lauseke",
|
||||
"P{iv{n asetus %s:ksi ei onnitus\n",
|
||||
"Remind: tarkenne '-i': %s\n",
|
||||
"Ei viestej{.",
|
||||
"%d viesti({) t{m{n p{iv{n jonossa.\n",
|
||||
"Numero puuttuu",
|
||||
"Virheellinen funktio WARN-lausekkeessa",
|
||||
"Can't convert between time zones",
|
||||
"No files matching *.rem",
|
||||
"String too long",
|
||||
"Time specified twice",
|
||||
"Cannot specify DURATION without specifying AT"
|
||||
|
||||
|
||||
#endif
|
||||
};
|
||||
#endif /* MK_GLOBALS */
|
||||
|
||||
@@ -527,97 +254,37 @@ EXTERN char *ErrMsg[] =
|
||||
#define L_USAGE_OVERRIDE 1
|
||||
void Usage(void)
|
||||
{
|
||||
fprintf(ErrFp, "\nREMIND %s (%s version) Copyright 1992-2020 Dianne Skoll\n", VERSION, L_LANGNAME);
|
||||
fprintf(ErrFp, "\nREMIND %s (%s version) Copyright 1992-2024 Dianne Skoll\n", VERSION, L_LANGNAME);
|
||||
#ifdef BETA
|
||||
fprintf(ErrFp, ">>>> BETAVERSIO <<<<\n");
|
||||
#endif
|
||||
#if ISOLATIN1
|
||||
fprintf(ErrFp, "K\xE4ytt\xF6: remind [tarkenteet] tiedosto [p\xE4iv\xE4ys] [aika] [*toisto]\n");
|
||||
fprintf(ErrFp, "Käyttö: remind [tarkenteet] tiedosto [päiväys] [aika] [*toisto]\n");
|
||||
fprintf(ErrFp, "Tarkenteet:\n");
|
||||
fprintf(ErrFp, " -n Tulosta viestien seuraavat esiintymiskerrat yksink. muodossa\n");
|
||||
fprintf(ErrFp, " -r Est\xE4 RUN-lauseiden k\xE4ytt\xF6\n");
|
||||
fprintf(ErrFp, " -r Estä RUN-lauseiden käyttö\n");
|
||||
fprintf(ErrFp, " -c[n] Tulosta n:n kuukauden kalenteri (oletus 1)\n");
|
||||
fprintf(ErrFp, " -c+[n] Tulosta n:n viikon kalenteri (oletus 1)\n");
|
||||
fprintf(ErrFp, " -w[n[,p[,s]]] Aseta kalenterin leveys, tasaus ja v\xE4lit\n");
|
||||
fprintf(ErrFp, " -w[n[,p[,s]]] Aseta kalenterin leveys, tasaus ja välit\n");
|
||||
fprintf(ErrFp, " -s[+][n] Tulosta n:n kuukauden (viikon) 'yksink. kalenteri' (oletus 1)\n");
|
||||
fprintf(ErrFp, " -p[n] Kuten -s, mutta tulosta rem2ps:lle sopivassa muodossa\n");
|
||||
fprintf(ErrFp, " -v Laveat tulostukset\n");
|
||||
fprintf(ErrFp, " -o \xC4l\xE4 noudata ONCE-lauseita\n");
|
||||
fprintf(ErrFp, " -t Laukaise kaikki viestit deltan arvosta v\xE4litt\xE4m\xE4tt\xE4\n");
|
||||
fprintf(ErrFp, " -o Älä noudata ONCE-lauseita\n");
|
||||
fprintf(ErrFp, " -t Laukaise kaikki viestit deltan arvosta välittämättä\n");
|
||||
fprintf(ErrFp, " -h Suppeat tulostukset\n");
|
||||
#ifdef HAVE_QUEUED
|
||||
fprintf(ErrFp, " -a \xC4l\xE4 laukaise viestej\xE4 heti - lis\xE4\xE4 ne jonoon\n");
|
||||
fprintf(ErrFp, " -q \xC4l\xE4 lis\xE4\xE4 viestej\xE4 jonoon\n");
|
||||
fprintf(ErrFp, " -a Älä laukaise viestejä heti - lisää ne jonoon\n");
|
||||
fprintf(ErrFp, " -q Älä lisää viestejä jonoon\n");
|
||||
fprintf(ErrFp, " -f Laukaise viestit, pysy etualalla\n");
|
||||
fprintf(ErrFp, " -z[n] K\xE4ynnisty demonina, her\xE4tys n:n (5:n) minuutin v\xE4lein\n");
|
||||
fprintf(ErrFp, " -z[n] Käynnisty demonina, herätys n:n (5:n) minuutin välein\n");
|
||||
#endif
|
||||
fprintf(ErrFp, " -d... Virheenetsint\xE4: e=echo x=expr-eval t=trig v=dumpvars l=showline\n");
|
||||
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\xE4iv\xE4yksen, ajan ja t\xE4rkeyden mukaan\n");
|
||||
fprintf(ErrFp, " -ivar=val Alusta muuttuja var arvolla val ja s\xE4ilyt\xE4 var\n");
|
||||
fprintf(ErrFp, " -m Aloita kalenteri maanantaista eik\xE4 sunnuntaista\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");
|
||||
fprintf(ErrFp, " -m Aloita kalenteri maanantaista eikä sunnuntaista\n");
|
||||
exit(1);
|
||||
#elif IBMEXTENDED
|
||||
fprintf(ErrFp, "K\x84ytt\x94: remind [tarkenteet] tiedosto [p\x84iv\x84ys] [aika] [*toisto]\n");
|
||||
fprintf(ErrFp, "Tarkenteet:\n");
|
||||
fprintf(ErrFp, " -n Tulosta viestien seuraavat esiintymiskerrat yksink. muodossa\n");
|
||||
fprintf(ErrFp, " -r Est\x84 RUN-lauseiden k\x84ytt\x94\n");
|
||||
fprintf(ErrFp, " -c[n] Tulosta n:n kuukauden kalenteri (oletus 1)\n");
|
||||
fprintf(ErrFp, " -c+[n] Tulosta n:n viikon kalenteri (oletus 1)\n");
|
||||
fprintf(ErrFp, " -w[n[,p[,s]]] Aseta kalenterin leveys, tasaus ja v\x84lit\n");
|
||||
fprintf(ErrFp, " -s[+][n] Tulosta n:n kuukauden (viikon) 'yksink. kalenteri' (oletus 1)\n");
|
||||
fprintf(ErrFp, " -p[n] Kuten -s, mutta tulosta rem2ps:lle sopivassa muodossa\n");
|
||||
fprintf(ErrFp, " -v Laveat tulostukset\n");
|
||||
fprintf(ErrFp, " -o \x8El\x84 noudata ONCE-lauseita\n");
|
||||
fprintf(ErrFp, " -t Laukaise kaikki viestit deltan arvosta v\x84litt\x84m\x84tt\x84\n");
|
||||
fprintf(ErrFp, " -h Suppeat tulostukset\n");
|
||||
#ifdef HAVE_QUEUED
|
||||
fprintf(ErrFp, " -a \x8El\x84 laukaise viestej\x84 heti - lis\x84\x84 ne jonoon\n");
|
||||
fprintf(ErrFp, " -q \x8El\x84 lis\x84\x84 viestej\x84 jonoon\n");
|
||||
fprintf(ErrFp, " -f Laukaise viestit, pysy etualalla\n");
|
||||
fprintf(ErrFp, " -z[n] K\x84ynnisty demonina, her\x84tys n:n (5:n) minuutin v\x84lein\n");
|
||||
#endif
|
||||
fprintf(ErrFp, " -d... Virheenetsint\x84: 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, " -kcmd Suorita 'cmd' MSG-tyyppisille viesteille\n");
|
||||
fprintf(ErrFp, " -g[ddd] Lajittele viestit p\x84iv\x84yksen, ajan ja t\x84rkeyden mukaan\n");
|
||||
fprintf(ErrFp, " -ivar=val Alusta muuttuja var arvolla val ja s\x84ilyt\x84 var\n");
|
||||
fprintf(ErrFp, " -m Aloita kalenteri maanantaista eik\x84 sunnuntaista\n");
|
||||
exit(1);
|
||||
#else
|
||||
fprintf(ErrFp, "K{ytt|: remind [tarkenteet] tiedosto [p{iv{ys] [aika] [*toisto]\n");
|
||||
fprintf(ErrFp, "Tarkenteet:\n");
|
||||
fprintf(ErrFp, " -n Tulosta viestien seuraavat esiintymiskerrat yksink. muodossa\n");
|
||||
fprintf(ErrFp, " -r Est{ RUN-lauseiden k{ytt|\n");
|
||||
fprintf(ErrFp, " -c[n] Tulosta n:n kuukauden kalenteri (oletus 1)\n");
|
||||
fprintf(ErrFp, " -c+[n] Tulosta n:n viikon kalenteri (oletus 1)\n");
|
||||
fprintf(ErrFp, " -w[n[,p[,s]]] Aseta kalenterin leveys, tasaus ja v{lit\n");
|
||||
fprintf(ErrFp, " -s[+][n] Tulosta n:n kuukauden (viikon) 'yksink. kalenteri' (oletus 1)\n");
|
||||
fprintf(ErrFp, " -p[n] Kuten -s, mutta tulosta rem2ps:lle sopivassa muodossa\n");
|
||||
fprintf(ErrFp, " -v Laveat tulostukset\n");
|
||||
fprintf(ErrFp, " -o [l{ noudata ONCE-lauseita\n");
|
||||
fprintf(ErrFp, " -t Laukaise kaikki viestit deltan arvosta v{litt{m{tt{\n");
|
||||
fprintf(ErrFp, " -h Suppeat tulostukset\n");
|
||||
#ifdef HAVE_QUEUED
|
||||
fprintf(ErrFp, " -a [l{ laukaise viestej{ heti - lis{{ ne jonoon\n");
|
||||
fprintf(ErrFp, " -q [l{ lis{{ viestej{ jonoon\n");
|
||||
fprintf(ErrFp, " -f Laukaise viestit, pysy etualalla\n");
|
||||
fprintf(ErrFp, " -z[n] K{ynnisty demonina, her{tys n:n (5:n) minuutin v{lein\n");
|
||||
#endif
|
||||
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, " -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");
|
||||
fprintf(ErrFp, " -m Aloita kalenteri maanantaista eik{ sunnuntaista\n");
|
||||
exit(1);
|
||||
#endif
|
||||
}
|
||||
#endif /* L_IN_INIT */
|
||||
|
||||
@@ -8,9 +8,10 @@
|
||||
/* */
|
||||
/* This file is part of REMIND. */
|
||||
/* */
|
||||
/* REMIND is Copyright (C) 1992-2020 by Dianne Skoll */
|
||||
/* REMIND is Copyright (C) 1992-2024 by Dianne Skoll */
|
||||
/* This file is Copyright (C) 1993 by Laurent Duperval and */
|
||||
/* Dianne Skoll. */
|
||||
/* SPDX-License-Identifier: GPL-2.0-only */
|
||||
/* */
|
||||
/***************************************************************/
|
||||
|
||||
@@ -28,29 +29,18 @@
|
||||
|
||||
/* Month names */
|
||||
#define L_JAN "janvier"
|
||||
#if ISOLATIN1
|
||||
#define L_FEB "f\351vrier"
|
||||
#else
|
||||
#define L_FEB "fevrier"
|
||||
#endif
|
||||
#define L_FEB "février"
|
||||
#define L_MAR "mars"
|
||||
#define L_APR "avril"
|
||||
#define L_MAY "mai"
|
||||
#define L_JUN "juin"
|
||||
#define L_JUL "juillet"
|
||||
#if ISOLATIN1
|
||||
#define L_AUG "ao\373t"
|
||||
#else
|
||||
#define L_AUG "aout"
|
||||
#endif
|
||||
#define L_AUG "août"
|
||||
#define L_SEP "septembre"
|
||||
#define L_OCT "octobre"
|
||||
#define L_NOV "novembre"
|
||||
#if ISOLATIN1
|
||||
#define L_DEC "d\351cembre"
|
||||
#else
|
||||
#define L_DEC "decembre"
|
||||
#endif
|
||||
#define L_DEC "décembre"
|
||||
|
||||
/* Today and tomorrow */
|
||||
#define L_TODAY "aujourd'hui"
|
||||
#define L_TOMORROW "demain"
|
||||
@@ -62,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 "il y a"
|
||||
#define L_FROMNOW "dans"
|
||||
@@ -81,22 +68,14 @@
|
||||
|
||||
/* Minutes, hours, at, etc */
|
||||
#define L_NOW "maintenant"
|
||||
#if ISOLATIN1
|
||||
#define L_AT "\340"
|
||||
#else
|
||||
#define L_AT "a"
|
||||
#endif
|
||||
#define L_AT "à"
|
||||
#define L_MINUTE "minute"
|
||||
#define L_HOUR "heure"
|
||||
#define L_IS "est"
|
||||
#if ISOLATIN1
|
||||
#define L_WAS "\351tait"
|
||||
#else
|
||||
#define L_WAS "etait"
|
||||
#endif
|
||||
#define L_WAS "était"
|
||||
#define L_AND "et"
|
||||
/* 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"
|
||||
|
||||
@@ -128,229 +107,119 @@ else if (tdiff < 0) { \
|
||||
sprintf(s, "dans %d heure%s et %d minute%s", hdiff, hplu, mdiff, mplu); \
|
||||
}
|
||||
|
||||
#define L_J_OVER if (altmode == '*') { sprintf(s, "%s, %d%s %s, %d", DayName[jul%7], d, plu, MonthName[m], y); } else { sprintf(s, "%s %s, %d%s %s, %d", L_ON, DayName[jul%7], d, plu, MonthName[m], y); }
|
||||
#define L_J_OVER if (altmode == '*') { sprintf(s, "%s, %d%s %s, %d", DayName[dse%7], d, plu, MonthName[m], y); } else { sprintf(s, "%s %s, %d%s %s, %d", L_ON, DayName[dse%7], d, plu, MonthName[m], y); }
|
||||
|
||||
#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 */
|
||||
#define L_K_OVER if (altmode == '*') { sprintf(s, "%s, %d%s %s", DayName[dse%7], d, plu, MonthName[m]); } else { sprintf(s, "%s %s, %d%s %s", L_ON, DayName[dse%7], d, plu, MonthName[m]); }
|
||||
|
||||
/* The next ones are used only when MK_GLOBALS is set */
|
||||
#ifdef MK_GLOBALS
|
||||
#define L_ERR_OVERRIDE 1
|
||||
EXTERN char *ErrMsg[] =
|
||||
{
|
||||
#if ISOLATIN1
|
||||
"Ok",
|
||||
"']' manquant",
|
||||
"Apostrophe manquant",
|
||||
"Expression trop complexe - trop d'op\351rateurs",
|
||||
"Expression trop complexe - trop d'op\351randes",
|
||||
"Expression trop complexe - trop d'opérateurs",
|
||||
"Expression trop complexe - trop d'opérandes",
|
||||
"')' manquante",
|
||||
"Fonction non-d\351finie",
|
||||
"Caract\350re ill\351gal",
|
||||
"Op\351rateur binaire attendu",
|
||||
"Manque de m\351moire",
|
||||
"Nombre mal form\351",
|
||||
"Erreur interne - 'underflow' de la pile d'op\351rateurs",
|
||||
"Fonction non-définie",
|
||||
"Caractère illégal",
|
||||
"Opérateur binaire attendu",
|
||||
"Manque de mémoire",
|
||||
"Nombre mal formé",
|
||||
"Erreur interne - 'underflow' de la pile d'opérateurs",
|
||||
"Erreur interne - 'underflow' de la pile de variables",
|
||||
"Impossible de convertir",
|
||||
"Types non-\351quivalents",
|
||||
"D\351bordement de date",
|
||||
"Types non-équivalents",
|
||||
"Débordement de date",
|
||||
"Erreur interne - erreur de pile",
|
||||
"Division par z\351ro",
|
||||
"Variable non d\351finie",
|
||||
"Division par zéro",
|
||||
"Variable non définie",
|
||||
"Fin de ligne non attendue",
|
||||
"Fin de fichier non attendue",
|
||||
"Erreur I/O",
|
||||
"Ligne trop longue",
|
||||
"Erreur interne",
|
||||
"Mauvaise date sp\351cifi\351e",
|
||||
"Mauvaise date spécifiée",
|
||||
"Pas assez d'arguments",
|
||||
"Trop d'arguments",
|
||||
"Heure mal form\351e",
|
||||
"Nombre trop \351lev\351",
|
||||
"Heure mal formée",
|
||||
"Nombre trop élevé",
|
||||
"Nombre trop bas",
|
||||
"Impossible d'ouvrir le fichier",
|
||||
"Trop d'INCLUDE imbriqu\351s",
|
||||
"Trop d'INCLUDE imbriqués",
|
||||
"Erreur d'analyse",
|
||||
"Impossible de calculer le d\351clenchement",
|
||||
"Trop de IF imbriqu\351s",
|
||||
"Impossible de calculer le déclenchement",
|
||||
"Trop de IF imbriqués",
|
||||
"ELSE sans IF correspondant",
|
||||
"ENDIF sans IF correspondant",
|
||||
"Impossible d'omettre (OMIT) tous les jours",
|
||||
"El\351ment(s) \351tranger(s) sur la ligne",
|
||||
"Elément(s) étranger(s) sur la ligne",
|
||||
"POP-OMIT-CONTEXT sans PUSH-OMIT-CONTEXT correspondant",
|
||||
"RUN d\351activ\351",
|
||||
"RUN déactivé",
|
||||
"Erreur de domaine",
|
||||
"Identificateur invalide",
|
||||
"Appel r\351cursif d\351tect\351",
|
||||
"Appel récursif détecté",
|
||||
"",
|
||||
"Impossible de modifier une variable syst\350me",
|
||||
"Fonction de la librairie C ne peut repr\351senter la date/l'heure",
|
||||
"Tentative de red\351finition d'une fonction intrins\350que",
|
||||
"Impossible d'imbriquer une d\351finition de fonction dans une expression",
|
||||
"Pour utiliser le facteur de r\351p\351tition la date doit \352tre sp\351cifi\351e au complet",
|
||||
"Ann\351e sp\351cifi\351e deux fois",
|
||||
"Mois sp\351cifi\351 deux fois",
|
||||
"Jour sp\351cifi\351 deux fois",
|
||||
"El\351ment inconnu",
|
||||
"Mois et jour doivent \352tre sp\351cifi\351s dans commande OMIT",
|
||||
"Impossible de modifier une variable système",
|
||||
"Fonction de la librairie C ne peut représenter la date/l'heure",
|
||||
"Tentative de redéfinition d'une fonction intrinsèque",
|
||||
"Impossible d'imbriquer une définition de fonction dans une expression",
|
||||
"Pour utiliser le facteur de répétition la date doit être spécifiée au complet",
|
||||
"Année spécifiée deux fois",
|
||||
"Mois spécifié deux fois",
|
||||
"Jour spécifié deux fois",
|
||||
"Elément inconnu",
|
||||
"Mois et jour doivent être spécifiés dans commande OMIT",
|
||||
"Trop de OMITs partiels",
|
||||
"Trop de OMITs complets",
|
||||
"Attention: PUSH-OMIT-CONTEXT sans POP-OMIT-CONTEXT correspondant",
|
||||
"Erreur \340 la lecture du fichier",
|
||||
"Erreur à la lecture du fichier",
|
||||
"Fin de ligne attendue",
|
||||
"Date h\351breuse invalide",
|
||||
"Date hébreuse invalide",
|
||||
"IIF demande nombre d'arguments impair",
|
||||
"Attention: ENDIF manquant",
|
||||
"Virgule attendue",
|
||||
"Jour de la semaine sp\351cifi\351 deux fois",
|
||||
"Jour de la semaine spécifié deux fois",
|
||||
"Utiliser un seul parmi BEFORE, AFTER ou SKIP",
|
||||
"Impossible d'imbriquer MSG, MSF, RUN, etc. dans une expression",
|
||||
"Valeur de r\351p\351tition sp\351cifi\351e deux fois",
|
||||
"Valeur delta sp\351cifi\351e deux fois",
|
||||
"Valeur de retour sp\351cifi\351e deux fois",
|
||||
"Mot-cl\351 ONCE utilis\351 deux fois. (Hah.)",
|
||||
"Heure attendue apr\350s AT",
|
||||
"Mot-cl\351 THROUGH/UNTIL utilis\351 deux fois",
|
||||
"Sp\351cification de date incompl\350te",
|
||||
"Mot-cl\351 FROM/SCANFROM utilis\351 deux fois",
|
||||
"Valeur de répétition spécifiée deux fois",
|
||||
"Valeur delta spécifiée deux fois",
|
||||
"Valeur de retour spécifiée deux fois",
|
||||
"Mot-clé ONCE utilisé deux fois. (Hah.)",
|
||||
"Heure attendue après AT",
|
||||
"Mot-clé THROUGH/UNTIL utilisé deux fois",
|
||||
"Spécification de date incomplète",
|
||||
"Mot-clé FROM/SCANFROM utilisé deux fois",
|
||||
"Variable",
|
||||
"Valeur",
|
||||
"*NON-DEFINI*",
|
||||
"Entr\351e dans UserFN",
|
||||
"Entrée dans UserFN",
|
||||
"Sortie de UserFN",
|
||||
"Expir\351",
|
||||
"fork() \351chou\351 - impossible de faire les appels en queue",
|
||||
"Impossible d'acc\351der au fichier",
|
||||
"Date syst\350me ill\351gale: Ann\351e est inf\351rieure \340 %d\n",
|
||||
"Option de d\351verminage inconnue '%c'\n",
|
||||
"Expiré",
|
||||
"fork() échoué - impossible de faire les appels en queue",
|
||||
"Impossible d'accéder au fichier",
|
||||
"Date système illégale: Année est inférieure à %d\n",
|
||||
"Option de déverminage inconnue '%c'\n",
|
||||
"Option inconnue '%c'\n",
|
||||
"Usager inconnu '%s'\n",
|
||||
"Impossible de changer gid pour %d\n",
|
||||
"Impossible de changer uid pour %d\n",
|
||||
"Manque de m\351moire pour environnement\n",
|
||||
"Manque de mémoire pour environnement\n",
|
||||
"Signe '=' manquant",
|
||||
"Nom de variable absent",
|
||||
"Expression absente",
|
||||
"Impossible de changer la date d'acc\350s de %s\n",
|
||||
"Impossible de changer la date d'accès de %s\n",
|
||||
"Remind: '-i' option: %s\n",
|
||||
"Pas de rappels.",
|
||||
"%d rappel(s) en file pour aujourd'hui.\n",
|
||||
"Nombre attendu",
|
||||
"Fonction ill\351gale apr\350s WARN",
|
||||
"Fonction illégale après WARN",
|
||||
"Can't convert between time zones",
|
||||
"No files matching *.rem",
|
||||
"String too long",
|
||||
"Time specified twice",
|
||||
"Cannot specify DURATION without specifying AT"
|
||||
|
||||
#else /* ISOLATIN1 */
|
||||
"Ok",
|
||||
"']' manquant",
|
||||
"Apostrophe manquant",
|
||||
"Expression trop complexe - trop d'operateurs",
|
||||
"Expression trop complexe - trop d'operandes",
|
||||
"')' manquante",
|
||||
"Fonction non-definie",
|
||||
"Caractere illegal",
|
||||
"Operateur binaire attendu",
|
||||
"Manque de memoire",
|
||||
"Nombre mal forme",
|
||||
"Erreur interne - 'underflow' de la pile d'operateurs",
|
||||
"Erreur interne - 'underflow' de la pile de variables",
|
||||
"Impossible de convertir",
|
||||
"Types non-equivalents",
|
||||
"Debordement de date",
|
||||
"Erreur interne - erreur de pile",
|
||||
"Division par zero",
|
||||
"Variable non definie",
|
||||
"Fin de ligne non attendue",
|
||||
"Fin de fichier non attendue",
|
||||
"Erreur I/O",
|
||||
"Ligne trop longue",
|
||||
"Erreur interne",
|
||||
"Mauvaise date specifiee",
|
||||
"Pas assez d'arguments",
|
||||
"Trop d'arguments",
|
||||
"Heure mal formee",
|
||||
"Nombre trop eleve",
|
||||
"Nombre trop bas",
|
||||
"Impossible d'ouvrir le fichier",
|
||||
"Trop d'INCLUDE imbriques",
|
||||
"erreur d'analyse",
|
||||
"Impossible de calculer le declenchement",
|
||||
"Trop de IF imbriques",
|
||||
"ELSE sans IF correspondant",
|
||||
"ENDIF sans IF correspondant",
|
||||
"Impossible d'omettre (OMIT) tous les jours",
|
||||
"Element(s) etranger(s) sur la ligne",
|
||||
"POP-OMIT-CONTEXT sans PUSH-OMIT-CONTEXT correspondant",
|
||||
"RUN desactive",
|
||||
"Erreur de domaine",
|
||||
"Identificateur invalide",
|
||||
"Appel recursif detecte",
|
||||
"",
|
||||
"Impossible de modifier une variable systeme",
|
||||
"Fonction de la librairie C ne peut representer la date/l'heure",
|
||||
"Tentative de redefinition d'une fonction intrinseque",
|
||||
"Impossible d'imbriquer une definition de fonction dans une expression",
|
||||
"Pour utiliser le facteur de repetition la date doit etre specifiee au complet",
|
||||
"Annee specifiee deux fois",
|
||||
"Mois specifie deux fois",
|
||||
"Jour specifie deux fois",
|
||||
"Element inconnu",
|
||||
"Mois et jour doivent etre specifies dans commande OMIT",
|
||||
"Trop de OMITs partiels",
|
||||
"Trop de OMITs complets",
|
||||
"Attention: PUSH-OMIT-CONTEXT sans POP-OMIT-CONTEXT correspondant",
|
||||
"Erreur a la lecture du fichier",
|
||||
"Fin de ligne attendue",
|
||||
"Date hebreuse invalide",
|
||||
"IIF demande nombre d'arguments impair",
|
||||
"Attention: ENDIF manquant",
|
||||
"Virgule attendue",
|
||||
"Jour de la semaine specifie deux fois",
|
||||
"Utiliser un seul parmi BEFORE, AFTER ou SKIP",
|
||||
"Impossible d'imbriquer MSG, MSF, RUN, etc. dans une expression",
|
||||
"Valeur de repetition specifiee deux fois",
|
||||
"Valeur delta specifiee deux fois",
|
||||
"Valeur de retour specifiee deux fois",
|
||||
"Mot-cle ONCE utilise deux fois. (Hah.)",
|
||||
"Heure attendue apres AT",
|
||||
"Mot-cle THROUGH/UNTIL utilise deux fois",
|
||||
"Specification de date incomplete",
|
||||
"Mot-cle FROM/SCANFROM utilise deux fois",
|
||||
"Variable",
|
||||
"Valeur",
|
||||
"*NON-DEFINI*",
|
||||
"Entree dans UserFN",
|
||||
"Sortie de UserFN",
|
||||
"Expire",
|
||||
"fork() echoue - impossible de faire les appels en queue",
|
||||
"Impossible d'acceder au fichier",
|
||||
"Date systeme illegale: Annee est inferieure a %d\n",
|
||||
"Option de deverminage inconnue '%c'\n",
|
||||
"Option inconnue '%c'\n",
|
||||
"Usager inconnu '%s'\n",
|
||||
"Impossible de changer gid pour %d\n",
|
||||
"Impossible de changer uid pour %d\n",
|
||||
"Manque de memoire pour environnement\n",
|
||||
"Signe '=' manquant",
|
||||
"Nom de variable absent",
|
||||
"Expression absente",
|
||||
"Impossible de changer la date d'acces de %s\n",
|
||||
"Remind: '-i' option: %s\n",
|
||||
"Pas de rappels.",
|
||||
"%d rappel(s) en file pour aujourd'hui.\n",
|
||||
"Nombre attendu",
|
||||
"Fonction illegale apres WARN",
|
||||
"Can't convert between time zones",
|
||||
"No files matching *.rem",
|
||||
"String too long",
|
||||
"Time specified twice",
|
||||
"Cannot specify DURATION without specifying AT"
|
||||
#endif /* ISOLATIN1 */
|
||||
};
|
||||
#endif /* MK_GLOBALS */
|
||||
|
||||
@@ -359,67 +228,37 @@ EXTERN char *ErrMsg[] =
|
||||
#define L_USAGE_OVERRIDE 1
|
||||
void Usage(void)
|
||||
{
|
||||
fprintf(ErrFp, "\nREMIND %s (%s version) Copyright 1992-2020 Dianne Skoll\n", VERSION, L_LANGNAME);
|
||||
fprintf(ErrFp, "\nREMIND %s (%s version) Copyright 1992-2024 Dianne Skoll\n", VERSION, L_LANGNAME);
|
||||
#ifdef BETA
|
||||
fprintf(ErrFp, ">>>> BETA VERSION <<<<\n");
|
||||
#endif
|
||||
#if ISOLATIN1
|
||||
fprintf(ErrFp, "\nUtilisation: remind [options] fichier [date] [heure] [*r\351p\351tition]\n");
|
||||
fprintf(ErrFp, "\nUtilisation: remind [options] fichier [date] [heure] [*répétition]\n");
|
||||
fprintf(ErrFp, "Options:\n");
|
||||
fprintf(ErrFp, " -n Afficher la prochaine occurence des rappels en format simple\n");
|
||||
fprintf(ErrFp, " -r D\351sactiver les instructions RUN\n");
|
||||
fprintf(ErrFp, " -c[n] Produire un calendrier pour n (d\351faut 1) mois\n");
|
||||
fprintf(ErrFp, " -c+[n] Produire un calendrier pour n (d\351faut 1) semaines\n");
|
||||
fprintf(ErrFp, " -w[n[,p[,s]]] Sp\351cifier largeur, remplissage et espacement du calendrier\n");
|
||||
fprintf(ErrFp, " -r Désactiver les instructions RUN\n");
|
||||
fprintf(ErrFp, " -c[n] Produire un calendrier pour n (défaut 1) mois\n");
|
||||
fprintf(ErrFp, " -c+[n] Produire un calendrier pour n (défaut 1) semaines\n");
|
||||
fprintf(ErrFp, " -w[n[,p[,s]]] Spécifier largeur, remplissage et espacement du calendrier\n");
|
||||
fprintf(ErrFp, " -s[+][n] Produire un 'calendrier simple' pour n (1) mois (semaines)\n");
|
||||
fprintf(ErrFp, " -p[n] Comme -s, mais avec entr\351e compatible avec rem2ps\n");
|
||||
fprintf(ErrFp, " -p[n] Comme -s, mais avec entrée compatible avec rem2ps\n");
|
||||
fprintf(ErrFp, " -v Mode verbeux\n");
|
||||
fprintf(ErrFp, " -o Ignorer instructions ONCE\n");
|
||||
fprintf(ErrFp, " -t D\351clencher tous les rappels peu importe le delta\n");
|
||||
fprintf(ErrFp, " -t Déclencher tous les rappels peu importe le delta\n");
|
||||
fprintf(ErrFp, " -h Mode silencieux\n");
|
||||
#ifdef HAVE_QUEUED
|
||||
fprintf(ErrFp, " -a Ne pas d\351clencher les rappels minut\351s imm\351diatement - les mettre en file\n");
|
||||
fprintf(ErrFp, " -q Ne pas mettre les rappels minut\351s en file\n");
|
||||
fprintf(ErrFp, " -f D\351clencher les rappels minut\351s imm\351diatement en restant en avant-plan\n");
|
||||
fprintf(ErrFp, " -z[n] Entrer en mode 'daemon', r\351veil chaque n (5) minutes\n");
|
||||
fprintf(ErrFp, " -a Ne pas déclencher les rappels minutés immédiatement - les mettre en file\n");
|
||||
fprintf(ErrFp, " -q Ne pas mettre les rappels minutés en file\n");
|
||||
fprintf(ErrFp, " -f Déclencher les rappels minutés immédiatement en restant en avant-plan\n");
|
||||
fprintf(ErrFp, " -z[n] Entrer en mode 'daemon', réveil chaque n (5) minutes\n");
|
||||
#endif
|
||||
fprintf(ErrFp, " -d... Debug: e=echo x=expr-eval t=trig v=dumpvars l=showline\n");
|
||||
fprintf(ErrFp, " -e Envoyer les messages de stderr \340 stdout\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\351rations pour la clause SATISFY (def=150)\n");
|
||||
fprintf(ErrFp, " -kcmd Ex\351cuter 'cmd' pour les rappels de type MSG\n");
|
||||
fprintf(ErrFp, " -g[ddd] Trier les rappels par date, heure et priorit\351 avant d'\351mettre\n");
|
||||
fprintf(ErrFp, " -ivar=val Initialiser var \340 val et conserver var\n");
|
||||
fprintf(ErrFp, " -m Commencer le calendrier avec lundi plut\364t que dimanche\n");
|
||||
#else /* ISOLATIN1 */
|
||||
fprintf(ErrFp, "\nUtilisation: remind [options] fichier [date] [heure] [*repetition]\n");
|
||||
fprintf(ErrFp, "Options:\n");
|
||||
fprintf(ErrFp, " -n Afficher la prochaine occurence des rappels en format simple\n");
|
||||
fprintf(ErrFp, " -r Desactiver les instructions RUN\n");
|
||||
fprintf(ErrFp, " -c[n] Produire un calendrier pour n (defaut 1) mois\n");
|
||||
fprintf(ErrFp, " -c+[n] Produire un calendrier pour n (defaut 1) semaines\n");
|
||||
fprintf(ErrFp, " -w[n[,p[,s]]] Specifier largeur, remplissage et espacement du calendrier\n");
|
||||
fprintf(ErrFp, " -s[+][n] Produire un 'calendrier simple' pour n (1) mois (semaines)\n");
|
||||
fprintf(ErrFp, " -p[n] Comme -s, mais avec entree compatible avec rem2ps\n");
|
||||
fprintf(ErrFp, " -v Mode verbeux\n");
|
||||
fprintf(ErrFp, " -o Ignorer instructions ONCE\n");
|
||||
fprintf(ErrFp, " -t Declencher tous les rappels peu importe le delta\n");
|
||||
fprintf(ErrFp, " -h Mode silencieux\n");
|
||||
#ifdef HAVE_QUEUED
|
||||
fprintf(ErrFp, " -a Ne pas declencher les rappels minutes immediatement - les mettre en file\n");
|
||||
fprintf(ErrFp, " -q Ne pas mettre les rappels minutes en file\n");
|
||||
fprintf(ErrFp, " -f Declencher les rappels minutes immediatement en restant en avant-plan\n");
|
||||
fprintf(ErrFp, " -z[n] Entrer en mode 'daemon', reveil chaque n (5) minutes\n");
|
||||
#endif
|
||||
fprintf(ErrFp, " -d... Debug: e=echo x=expr-eval t=trig v=dumpvars l=showline\n");
|
||||
fprintf(ErrFp, " -e Envoyer les messages de stderr a 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'iterations pour la clause SATISFY (def=150)\n");
|
||||
fprintf(ErrFp, " -kcmd Executer 'cmd' pour les rappels de type MSG\n");
|
||||
fprintf(ErrFp, " -g[ddd] Trier les rappels par date, heure et priorite avant d'emettre\n");
|
||||
fprintf(ErrFp, " -ivar=val Initialiser var a val et conserver var\n");
|
||||
fprintf(ErrFp, " -m Commencer le calendrier avec lundi plutot que dimanche\n");
|
||||
#endif /* ISOLATIN1 */
|
||||
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");
|
||||
fprintf(ErrFp, " -m Commencer le calendrier avec lundi plutôt que dimanche\n");
|
||||
exit(1);
|
||||
}
|
||||
#endif /* L_IN_INIT */
|
||||
|
||||
@@ -9,7 +9,8 @@
|
||||
/* I don't speak German. */
|
||||
/* */
|
||||
/* This file is part of REMIND. */
|
||||
/* Copyright (C) 1992-2020 by Dianne Skoll */
|
||||
/* Copyright (C) 1992-2024 by Dianne Skoll */
|
||||
/* SPDX-License-Identifier: GPL-2.0-only */
|
||||
/* */
|
||||
/***************************************************************/
|
||||
|
||||
@@ -28,11 +29,7 @@
|
||||
/* Month names */
|
||||
#define L_JAN "Januar"
|
||||
#define L_FEB "Februar"
|
||||
#if ISOLATIN1
|
||||
# define L_MAR "M\344rz"
|
||||
#else
|
||||
# define L_MAR "Maerz"
|
||||
#endif
|
||||
#define L_MAR "März"
|
||||
#define L_APR "April"
|
||||
#define L_MAY "Mai"
|
||||
#define L_JUN "Juni"
|
||||
@@ -48,19 +45,12 @@
|
||||
#define L_TOMORROW "morgen"
|
||||
|
||||
/* The default banner */
|
||||
#if ISOLATIN1
|
||||
# define L_BANNER "Termine f\374r %w, den %d. %m %y%o:"
|
||||
#else
|
||||
# define L_BANNER "Termine fuer %w, den %d. %m %y%o:"
|
||||
#endif
|
||||
#define L_BANNER "Termine für %w, den %d. %m %y%o:"
|
||||
|
||||
/* "am" and "pm" */
|
||||
#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"
|
||||
@@ -92,9 +82,7 @@
|
||||
See the file dosubst.c for more info. */
|
||||
#define L_AMPM_OVERRIDE(ampm, hour) ampm = (hour < 12) ? (hour<5) ? " nachts" : " vormittags" : (hour > 17) ? " abends" : " nachmittags";
|
||||
#define L_ORDINAL_OVERRIDE plu = ".";
|
||||
#define L_A_OVER if (altmode == '*') { sprintf(s, "%s, den %d. %s %d", DayName[jul%7], d, MonthName[m], y); } else { sprintf(s, "%s %s, den %d. %s %d", L_ON, DayName[jul%7], d, MonthName[m], y); }
|
||||
#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_A_OVER if (altmode == '*') { sprintf(s, "%s, den %d. %s %d", DayName[dse%7], d, MonthName[m], y); } else { sprintf(s, "%s %s, den %d. %s %d", L_ON, DayName[dse%7], d, MonthName[m], y); }
|
||||
#define L_G_OVER if (altmode == '*') { sprintf(s, "%s, den %d. %s", DayName[dse%7], d, MonthName[m]); } else { sprintf(s, "%s %s, den %d. %s", L_ON, DayName[dse%7], d, MonthName[m]); }
|
||||
#define L_U_OVER L_A_OVER
|
||||
#define L_V_OVER L_G_OVER
|
||||
|
||||
#endif /* L_IN_DOSUBST */
|
||||
|
||||
@@ -5,8 +5,9 @@
|
||||
/* Support for the Icelandic language. */
|
||||
/* */
|
||||
/* This file is part of REMIND. */
|
||||
/* Copyright (C) 1992-2020 by Dianne Skoll */
|
||||
/* Translated by Björn Davíðsson (bjossi@snerpa.is) */
|
||||
/* Copyright (C) 1992-2024 by Dianne Skoll */
|
||||
/* Translated by Björn Davíðsson (bjossi@snerpa.is) */
|
||||
/* SPDX-License-Identifier: GPL-2.0-only */
|
||||
/* */
|
||||
/***************************************************************/
|
||||
|
||||
@@ -15,59 +16,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 +77,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 */
|
||||
|
||||
@@ -7,7 +7,8 @@
|
||||
/* This file is part of REMIND. */
|
||||
/* It is Copyright (C) 1996 by Valerio Aimale */
|
||||
/* */
|
||||
/* Remind is copyright (C) 1992-2020 by Dianne Skoll */
|
||||
/* Remind is copyright (C) 1992-2024 by Dianne Skoll */
|
||||
/* SPDX-License-Identifier: GPL-2.0-only */
|
||||
/* */
|
||||
/***************************************************************/
|
||||
|
||||
@@ -15,23 +16,13 @@
|
||||
#define L_LANGNAME "Italian"
|
||||
|
||||
/* Day names */
|
||||
#if ISOLATIN1
|
||||
#define L_SUNDAY "Domenica"
|
||||
#define L_MONDAY "Luned\354"
|
||||
#define L_TUESDAY "Marted\354"
|
||||
#define L_WEDNESDAY "Mercoled\354"
|
||||
#define L_THURSDAY "Gioved\354"
|
||||
#define L_FRIDAY "Venerd\354"
|
||||
#define L_MONDAY "Lunedì"
|
||||
#define L_TUESDAY "Martedì"
|
||||
#define L_WEDNESDAY "Mercoledì"
|
||||
#define L_THURSDAY "Giovedì"
|
||||
#define L_FRIDAY "Venerdì"
|
||||
#define L_SATURDAY "Sabato"
|
||||
#else /* ISOLATIN1 */
|
||||
#define L_SUNDAY "Domenica"
|
||||
#define L_MONDAY "Lunedi`"
|
||||
#define L_TUESDAY "Martedi`"
|
||||
#define L_WEDNESDAY "Mercoledi`"
|
||||
#define L_THURSDAY "Giovedi`"
|
||||
#define L_FRIDAY "Venerdi`"
|
||||
#define L_SATURDAY "Sabato"
|
||||
#endif /* ISOLATIN */
|
||||
|
||||
/* Month names */
|
||||
#define L_JAN "Gennaio"
|
||||
@@ -59,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 "fa"
|
||||
#define L_FROMNOW "da oggi"
|
||||
@@ -76,58 +64,51 @@
|
||||
a more drastic fix */
|
||||
|
||||
/* Minutes, hours, at, etc */
|
||||
#define L_NOW "ora"
|
||||
#define L_NOW "ora"
|
||||
#define L_AT "alle"
|
||||
#define L_MINUTE "minut"
|
||||
#define L_HOUR "or"
|
||||
#if ISOLATIN1
|
||||
#define L_IS "\350"
|
||||
#else /* ISOLATIN1 */
|
||||
#define L_IS "e`"
|
||||
#endif/* ISOLATIN1 */
|
||||
#define L_IS "è"
|
||||
#define L_WAS "era"
|
||||
#define L_AND "e"
|
||||
/* 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. */
|
||||
|
||||
#define L_P_OVER sprintf(s, (diff == 1 ? "o" : "i"));
|
||||
#define L_Q_OVER sprintf(s, (diff == 1 ? "a" : "e"));
|
||||
#define L_P_OVER sprintf(s, (diff == 1 ? "o" : "i"));
|
||||
#define L_Q_OVER sprintf(s, (diff == 1 ? "a" : "e"));
|
||||
|
||||
#define L_HPLU_OVER hplu = (hdiff == 1 ? "a" : "e");
|
||||
#define L_MPLU_OVER mplu = (mdiff == 1 ? "o" : "i");
|
||||
|
||||
#define L_A_OVER sprintf(s, "%s, %d %s %d", DayName[jul%7], d,\
|
||||
MonthName[m], y);
|
||||
#define L_C_OVER sprintf(s, "%s", DayName[jul%7]);
|
||||
#define L_A_OVER sprintf(s, "%s, %d %s %d", DayName[dse%7], d,\
|
||||
MonthName[m], y);
|
||||
#define L_C_OVER sprintf(s, "%s", DayName[dse%7]);
|
||||
|
||||
#define L_E_OVER sprintf(s, "%02d%c%02d%c%04d", d, DateSep,\
|
||||
m+1, DateSep, y);
|
||||
m+1, DateSep, y);
|
||||
|
||||
#define L_F_OVER sprintf(s, "%02d%c%02d%c%04d", m+1, DateSep, d, DateSep, y);
|
||||
#define L_F_OVER sprintf(s, "%02d%c%02d%c%04d", m+1, DateSep, d, DateSep, y);
|
||||
|
||||
#define L_G_OVER sprintf(s, "%s, %d %s", DayName[jul%7], d, MonthName[m]);
|
||||
#define L_G_OVER sprintf(s, "%s, %d %s", DayName[dse%7], d, MonthName[m]);
|
||||
|
||||
#define L_H_OVER sprintf(s, "%02d%c%02d", d, DateSep, m+1);
|
||||
#define L_H_OVER sprintf(s, "%02d%c%02d", d, DateSep, m+1);
|
||||
|
||||
#define L_I_OVER sprintf(s, "%02d%c%02d", m+1, DateSep, d);
|
||||
#define L_I_OVER sprintf(s, "%02d%c%02d", m+1, DateSep, d);
|
||||
|
||||
#define L_J_OVER sprintf(s, "%s, %d %s %d", DayName[jul%7], d, \
|
||||
MonthName[m], y);
|
||||
#define L_J_OVER sprintf(s, "%s, %d %s %d", DayName[dse%7], d, \
|
||||
MonthName[m], y);
|
||||
|
||||
#define L_K_OVER sprintf(s, "%s, %d %s", DayName[jul%7], d, \
|
||||
MonthName[m]);
|
||||
#define L_L_OVER sprintf(s, "%04d%c%02d%c%02d", y, DateSep, m+1, DateSep, d);
|
||||
#define L_K_OVER sprintf(s, "%s, %d %s", DayName[dse%7], d, \
|
||||
MonthName[m]);
|
||||
#define L_L_OVER sprintf(s, "%04d%c%02d%c%02d", y, DateSep, m+1, DateSep, d);
|
||||
|
||||
#define L_U_OVER sprintf(s, "%s, %d %s %d", DayName[jul%7], d, \
|
||||
MonthName[m], y);
|
||||
#define L_U_OVER sprintf(s, "%s, %d %s %d", DayName[dse%7], d, \
|
||||
MonthName[m], y);
|
||||
|
||||
#define L_V_OVER sprintf(s, "%s, %d %s", DayName[jul%7], d, \
|
||||
MonthName[m]);
|
||||
|
||||
|
||||
#endif /* L_IN_DOSUBST */
|
||||
#define L_V_OVER sprintf(s, "%s, %d %s", DayName[dse%7], d, \
|
||||
MonthName[m]);
|
||||
|
||||
@@ -6,7 +6,8 @@
|
||||
/* */
|
||||
/* This file is part of REMIND. */
|
||||
/* This file is Copyright (C) 1993 by Trygve Randen. */
|
||||
/* Remind is Copyright (C) 1992-2020 by Dianne Skoll */
|
||||
/* Remind is Copyright (C) 1992-2024 by Dianne Skoll */
|
||||
/* SPDX-License-Identifier: GPL-2.0-only */
|
||||
/* */
|
||||
/***************************************************************/
|
||||
|
||||
@@ -14,21 +15,13 @@
|
||||
#define L_LANGNAME "Norwegian"
|
||||
|
||||
/* Day names */
|
||||
#if ISOLATIN1
|
||||
# define L_SUNDAY "S\370ndag"
|
||||
#else
|
||||
# define L_SUNDAY "Soendag"
|
||||
#endif
|
||||
#define L_SUNDAY "Søndag"
|
||||
#define L_MONDAY "Mandag"
|
||||
#define L_TUESDAY "Tirsdag"
|
||||
#define L_WEDNESDAY "Onsdag"
|
||||
#define L_THURSDAY "Torsdag"
|
||||
#define L_FRIDAY "Fredag"
|
||||
#if ISOLATIN1
|
||||
# define L_SATURDAY "L\370rdag"
|
||||
#else
|
||||
# define L_SATURDAY "Loerdag"
|
||||
#endif
|
||||
#define L_SATURDAY "Lørdag"
|
||||
|
||||
/* Month names */
|
||||
#define L_JAN "Januar"
|
||||
@@ -49,26 +42,15 @@
|
||||
#define L_TOMORROW "i morgen"
|
||||
|
||||
/* The default banner */
|
||||
#if ISOLATIN1
|
||||
# define L_BANNER "P\345minnelse for %w, %d. %m, %y%o:"
|
||||
#else
|
||||
# define L_BANNER "Paaminnelse for %w, %d. %m, %y%o:"
|
||||
#endif
|
||||
#define L_BANNER "Påminnelse for %w, %d. %m, %y%o:"
|
||||
|
||||
/* "am" and "pm" */
|
||||
#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"
|
||||
#if ISOLATIN1
|
||||
# define L_FROMNOW "fra n\345"
|
||||
#else
|
||||
# define L_FROMNOW "fra naa"
|
||||
#endif
|
||||
#define L_FROMNOW "fra nå"
|
||||
|
||||
/* "in %d days' time" */
|
||||
#define L_INXDAYS "om %d dager"
|
||||
@@ -81,11 +63,7 @@
|
||||
#define L_PLURAL "er"
|
||||
|
||||
/* Minutes, hours, at, etc */
|
||||
#if ISOLATIN1
|
||||
# define L_NOW "n\345"
|
||||
#else
|
||||
# define L_NOW "naa"
|
||||
#endif
|
||||
#define L_NOW "nå"
|
||||
#define L_AT "kl."
|
||||
#define L_MINUTE "minutt"
|
||||
#define L_HOUR "time"
|
||||
@@ -93,17 +71,14 @@
|
||||
#define L_WAS "var"
|
||||
#define L_AND "og"
|
||||
/* What to add to make "hour" plural */
|
||||
#define L_HPLU "r"
|
||||
#define L_HPLU "r"
|
||||
/* What to add to make "minute" plural */
|
||||
#define L_MPLU "er"
|
||||
|
||||
/* Define any overrides here, such as L_ORDINAL_OVERRIDE, L_A_OVER, etc.
|
||||
See the file dosubst.c for more info. */
|
||||
#define L_ORDINAL_OVERRIDE plu = ".";
|
||||
#define L_A_OVER if (altmode == '*') { sprintf(s, "%s, den %d. %s %d", DayName[jul%7], d, MonthName[m], y); } else { sprintf(s, "%s %s, den %d. %s %d", L_ON, DayName[jul%7], d, MonthName[m], y); }
|
||||
#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_A_OVER if (altmode == '*') { sprintf(s, "%s, den %d. %s %d", DayName[dse%7], d, MonthName[m], y); } else { sprintf(s, "%s %s, den %d. %s %d", L_ON, DayName[dse%7], d, MonthName[m], y); }
|
||||
#define L_G_OVER if (altmode == '*') { sprintf(s, "%s, den %d. %s", DayName[dse%7], d, MonthName[m]); } else { sprintf(s, "%s %s, den %d. %s", L_ON, DayName[dse%7], d, MonthName[m]); }
|
||||
#define L_U_OVER L_A_OVER
|
||||
#define L_V_OVER L_G_OVER
|
||||
|
||||
|
||||
#endif /* L_IN_DOSUBST */
|
||||
|
||||
@@ -9,7 +9,8 @@
|
||||
/* Polish. */
|
||||
/* */
|
||||
/* This file is part of REMIND. */
|
||||
/* Copyright (C) 1992-2020 by Dianne Skoll */
|
||||
/* Copyright (C) 1992-2024 by Dianne Skoll */
|
||||
/* SPDX-License-Identifier: GPL-2.0-only */
|
||||
/* */
|
||||
/***************************************************************/
|
||||
|
||||
@@ -17,52 +18,27 @@
|
||||
#define L_LANGNAME "Polish"
|
||||
|
||||
/* Day names */
|
||||
#if ISOLATIN1
|
||||
# define L_SUNDAY "Niedziela"
|
||||
# define L_MONDAY "Poniedzia\263ek"
|
||||
# define L_MONDAY "Poniedziałek"
|
||||
# define L_TUESDAY "Wtorek"
|
||||
# define L_WEDNESDAY "\246roda"
|
||||
# define L_WEDNESDAY "Środa"
|
||||
# define L_THURSDAY "Czwartek"
|
||||
# define L_FRIDAY "Pi\261tek"
|
||||
# define L_FRIDAY "Piątek"
|
||||
# define L_SATURDAY "Sobota"
|
||||
#else
|
||||
# define L_SUNDAY "Niedziela"
|
||||
# define L_MONDAY "Poniedzialek"
|
||||
# define L_TUESDAY "Wtorek"
|
||||
# define L_WEDNESDAY "Sroda"
|
||||
# define L_THURSDAY "Czwartek"
|
||||
# define L_FRIDAY "Piatek"
|
||||
# define L_SATURDAY "Sobota"
|
||||
#endif
|
||||
|
||||
/* Month names */
|
||||
#if ISOLATIN1
|
||||
# define L_JAN "Stycze\361"
|
||||
# define L_JAN "Styczeń"
|
||||
# define L_FEB "Luty"
|
||||
# define L_MAR "Marzec"
|
||||
# define L_APR "Kwiecie\361"
|
||||
# define L_APR "Kwiecień"
|
||||
# define L_MAY "Maj"
|
||||
# define L_JUN "Czerwiec"
|
||||
# define L_JUL "Lipiec"
|
||||
# define L_AUG "Sierpie\361"
|
||||
# define L_SEP "Wrzesie\361"
|
||||
# define L_OCT "Pa\274dziernik"
|
||||
# define L_AUG "Sierpień"
|
||||
# define L_SEP "Wrzesień"
|
||||
# define L_OCT "Październik"
|
||||
# define L_NOV "Listopad"
|
||||
# define L_DEC "Grudzie\361"
|
||||
#else
|
||||
# define L_JAN "Styczen"
|
||||
# define L_FEB "Luty"
|
||||
# define L_MAR "Marzec"
|
||||
# define L_APR "Kwiecien"
|
||||
# define L_MAY "Maj"
|
||||
# define L_JUN "Czerwiec"
|
||||
# define L_JUL "Lipiec"
|
||||
# define L_AUG "Sierpien"
|
||||
# define L_SEP "Wrzesien"
|
||||
# define L_OCT "Pazdziernik"
|
||||
# define L_NOV "Listopad"
|
||||
# define L_DEC "Grudzien"
|
||||
#endif
|
||||
# define L_DEC "Grudzień"
|
||||
|
||||
/* Today and tomorrow */
|
||||
#define L_TODAY "dzisiaj"
|
||||
@@ -75,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 "temu"
|
||||
#define L_FROMNOW "od teraz"
|
||||
@@ -97,80 +70,61 @@
|
||||
#define L_AT "o"
|
||||
#define L_MINUTE "minut"
|
||||
#define L_HOUR "godzin"
|
||||
#if ISOLATIN1
|
||||
# define L_IS "b\352dzie"
|
||||
# define L_WAS "by\263o"
|
||||
#else
|
||||
# define L_IS "bedzie"
|
||||
# define L_WAS "bylo"
|
||||
#endif
|
||||
# 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 */
|
||||
#if ISOLATIN1
|
||||
#define L_NPLU( N ) ((N == 1) ? "\352" : ((N==12) || (N==13) || (N==14)) ? "" : \
|
||||
#define L_NPLU( N ) ((N == 1) ? "ę" : ((N==12) || (N==13) || (N==14)) ? "" : \
|
||||
((N%10==2) || (N%10==3) || (N%10==4)) ? "y" : "" )
|
||||
#else
|
||||
#define L_NPLU( N ) ((N == 1) ? "e" : ((N==12) || (N==13) || (N==14)) ? "" : \
|
||||
((N%10==2) || (N%10==3) || (N%10==4)) ? "y" : "" )
|
||||
#endif
|
||||
/* 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. */
|
||||
#if ISOLATIN1
|
||||
#define L_AMPM_OVERRIDE(ampm, hour) \
|
||||
ampm = (hour<12) ? \
|
||||
(hour<5) ? " w nocy" \
|
||||
: (hour<10) ? " rano" \
|
||||
: " przed po\263udniem" \
|
||||
: (hour<18) ? " po po\263udniu" \
|
||||
: " przed południem" \
|
||||
: (hour<18) ? " po południu" \
|
||||
: (hour<22) ? " wieczorem" \
|
||||
: " w nocy";
|
||||
#else
|
||||
#define L_AMPM_OVERRIDE(ampm, hour) \
|
||||
ampm = (hour<12) ? \
|
||||
(hour<5) ? " w nocy" \
|
||||
: (hour<10) ? " rano" \
|
||||
: " przed poludniem" \
|
||||
: (hour<18) ? " po poludniu" \
|
||||
: (hour<22) ? " wieczorem" \
|
||||
: " w nocy";
|
||||
#endif
|
||||
#define L_ORDINAL_OVERRIDE plu = "";
|
||||
#define L_A_OVER if (altmode == '*') { sprintf(s, "%s, %d. %s %d", DayName[jul%7], d, MonthName[m], y); } else { sprintf(s, "%s %s, %d. %s %d", L_ON, DayName[jul%7], d, MonthName[m], y); }
|
||||
#define L_G_OVER if (altmode == '*') { sprintf(s, "%s, %d. %s", DayName[jul%7], d, MonthName[m]); } else { sprintf(s, "%s %s, %d. %s", L_ON, DayName[jul%7], d, MonthName[m]); }
|
||||
#define L_A_OVER if (altmode == '*') { sprintf(s, "%s, %d. %s %d", DayName[dse%7], d, MonthName[m], y); } else { sprintf(s, "%s %s, %d. %s %d", L_ON, DayName[dse%7], d, MonthName[m], y); }
|
||||
#define L_G_OVER if (altmode == '*') { sprintf(s, "%s, %d. %s", DayName[dse%7], d, MonthName[m]); } else { sprintf(s, "%s %s, %d. %s", L_ON, DayName[dse%7], d, MonthName[m]); }
|
||||
#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 */
|
||||
@@ -178,104 +132,103 @@ else \
|
||||
#define L_ERR_OVERRIDE 1
|
||||
EXTERN char *ErrMsg[] =
|
||||
{
|
||||
#if ISOLATIN1
|
||||
"OK",
|
||||
"Brakuj\261cy ']'",
|
||||
"Brakuj\261cy nawias",
|
||||
"Zbyt skomplikowane wyra\277enie - za du\277o operator\363w",
|
||||
"Zbyt skomplikowane wyra\277enie - za du\277o argument\363w",
|
||||
"Brakuj\261cy ')'",
|
||||
"Brakujący ']'",
|
||||
"Brakujący nawias",
|
||||
"Zbyt skomplikowane wyrażenie - za dużo operatorów",
|
||||
"Zbyt skomplikowane wyrażenie - za dużo argumentów",
|
||||
"Brakujący ')'",
|
||||
"Nie zdefiniowana funkcja",
|
||||
"Nielegalny znak",
|
||||
"Spodziewany operator binarny",
|
||||
"Brak pami\352ci",
|
||||
"Brak pamięci",
|
||||
"Niepoprawny numer",
|
||||
"Pusty stos operator\363w - b\263\261d wewn\352trzny",
|
||||
"Pusty stos zmiennych - b\263\261d wewn\352trzny",
|
||||
"Niemo\277liwa konwersja",
|
||||
"B\263\261d typu",
|
||||
"Pusty stos operatorów - błąd wewnętrzny",
|
||||
"Pusty stos zmiennych - błąd wewnętrzny",
|
||||
"Niemożliwa konwersja",
|
||||
"Błąd typu",
|
||||
"Nadmiar daty",
|
||||
"B\263\261d stosu - b\263\261d wewn\352trzny",
|
||||
"Błąd stosu - błąd wewnętrzny",
|
||||
"Dzielenie przez zero",
|
||||
"Niezdefiniowana zmienna",
|
||||
"Niespodziewany koniec linii",
|
||||
"Niespodziewany koniec pliku",
|
||||
"B\263\261d wejscia/wyjscia",
|
||||
"Za d\263uga linia",
|
||||
"B\263\261d wewn\352trzny",
|
||||
"Z\263a specyfikacja daty",
|
||||
"Za ma\263o argument\363w",
|
||||
"Za du\277o argument\363w",
|
||||
"Nieprawid\263owy czas",
|
||||
"Liczba za du\277a",
|
||||
"Liczba za ma\263a",
|
||||
"Nie mog\352 otworzy\346 pliku",
|
||||
"Zbyt zagnie\277d\277one INCLUDE",
|
||||
"B\263\261d sk\263adniowy",
|
||||
"Nie mog\352 obliczy\346 przypomnienia",
|
||||
"Zbyt zagnie\277d\277one IF",
|
||||
"Błąd wejscia/wyjscia",
|
||||
"Za długa linia",
|
||||
"Błąd wewnętrzny",
|
||||
"Zła specyfikacja daty",
|
||||
"Za mało argumentów",
|
||||
"Za dużo argumentów",
|
||||
"Nieprawidłowy czas",
|
||||
"Liczba za duża",
|
||||
"Liczba za mała",
|
||||
"Nie mogę otworzyć pliku",
|
||||
"Zbyt zagnieżdżone INCLUDE",
|
||||
"Błąd składniowy",
|
||||
"Nie mogę obliczyć przypomnienia",
|
||||
"Zbyt zagnieżdżone IF",
|
||||
"ELSE bez IF do pary",
|
||||
"ENDIF bez IF do pary",
|
||||
"Nie mog\352 omin\261\346 (OMIT) wszystkich dni",
|
||||
"Nie mogę ominąć (OMIT) wszystkich dni",
|
||||
"Niespodziewany wyraz w lini",
|
||||
"POP-OMIT-CONTEXT bez PUSH-OMIT-CONTEXT",
|
||||
"Komenda RUN zablokowana",
|
||||
"B\263\261d dziedziny",
|
||||
"Błąd dziedziny",
|
||||
"Niepoprawny identyfikator",
|
||||
"Wykryto rekursywne wywo\263anie funkcji",
|
||||
"Wykryto rekursywne wywołanie funkcji",
|
||||
"",
|
||||
"Nie mog\352 zmieni\346 zmiennej systemowej",
|
||||
"Funkcja biblioteki C nie mo\277e reprezentowac daty/czasu",
|
||||
"Pr\363ba redefinicji funkcji wbudowanej",
|
||||
"Nie wolno zagnie\277d\277a\346 definicji funkcji w wyra\277eniu",
|
||||
"Aby u\277yc powt\363rzenia trzeba w pe\263ni wyspecyfikowa\346 dat\352",
|
||||
"Rok podany dw\363krotnie",
|
||||
"Miesi\261c podany dw\363krotnie",
|
||||
"Dzie\361 podany dw\363krotnie",
|
||||
"Nieznane s\263owo",
|
||||
"W komendzie OMIT trzeba poda\346 miesi\261c i dzie\361",
|
||||
"Za du\277o cz\352\266ciowych komend OMIT",
|
||||
"Za du\277o pe\263nych komend OMIT",
|
||||
"Ostrze\277enie: PUSH-OMIT-CONTEXT bez POP-OMIT-CONTEXT",
|
||||
"B\263\261d odczytu pliku",
|
||||
"Nie mogę zmienić zmiennej systemowej",
|
||||
"Funkcja biblioteki C nie może reprezentowac daty/czasu",
|
||||
"Próba redefinicji funkcji wbudowanej",
|
||||
"Nie wolno zagnieżdżać definicji funkcji w wyrażeniu",
|
||||
"Aby użyc powtórzenia trzeba w pełni wyspecyfikować datę",
|
||||
"Rok podany dwókrotnie",
|
||||
"Miesiąc podany dwókrotnie",
|
||||
"Dzień podany dwókrotnie",
|
||||
"Nieznane słowo",
|
||||
"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",
|
||||
"Błąd odczytu pliku",
|
||||
"Oczekiwany koniec linii",
|
||||
"B\263\352dna data hebrajska",
|
||||
"IIF wymaga nieparzystej liczby argument\363w",
|
||||
"Ostrze\277enie: Brakujacy ENDIF",
|
||||
"Błędna data hebrajska",
|
||||
"IIF wymaga nieparzystej liczby argumentów",
|
||||
"Ostrzeżenie: Brakujacy ENDIF",
|
||||
"Oczekiwany przecinek",
|
||||
"Dzie\361 tygodnia podany dw\363krotnie",
|
||||
"Dzień tygodnia podany dwókrotnie",
|
||||
"Dozwolone tylko jedno z: BEFORE, AFTER i SKIP",
|
||||
"Nie mo\277na zagnie\277d\277a\346 MSG, MSF, RUN, itp. w wyra\277eniu",
|
||||
"Warto\266\346 powtorzenia podana dw\363krotnie",
|
||||
"Warto\266\346 r\363\277nicy podana dw\363krotnie",
|
||||
"Warto\266\346 cofni\352cia podana dw\363krotnie",
|
||||
"S\263owo ONCE u\277yte dw\363krotnie.",
|
||||
"Nie można zagnieżdżać MSG, MSF, RUN, itp. w wyrażeniu",
|
||||
"Wartość powtorzenia podana dwókrotnie",
|
||||
"Wartość różnicy podana dwókrotnie",
|
||||
"Wartość cofnięcia podana dwókrotnie",
|
||||
"Słowo ONCE użyte dwókrotnie.",
|
||||
"Po AT oczekiwany jest czas",
|
||||
"S\263owo THROUGH/UNTIL u\277yte dw\363krotnie",
|
||||
"Słowo THROUGH/UNTIL użyte dwókrotnie",
|
||||
"Niekompletna specyfikacja daty",
|
||||
"S\263owo FROM/SCANFROM u\277yte dw\363krotnie",
|
||||
"Słowo FROM/SCANFROM użyte dwókrotnie",
|
||||
"Zmienna",
|
||||
"Warto\266\346",
|
||||
"Wartość",
|
||||
"*NIE ZDEFINIOWANE*",
|
||||
"Pocz\261tek UserFN",
|
||||
"Początek UserFN",
|
||||
"Koniec UserFN",
|
||||
"Przemine\263o",
|
||||
"Niepowodzenie w funkcji fork() - nie mog\352 kolejkowa\346 przypomnie\361",
|
||||
"Nie ma dost\352pu do pliku",
|
||||
"B\263\352dna data systemowa: Rok mniejszy ni\277 %d\n",
|
||||
"Przemineło",
|
||||
"Niepowodzenie w funkcji fork() - nie mogę kolejkować przypomnień",
|
||||
"Nie ma dostępu do pliku",
|
||||
"Błędna data systemowa: Rok mniejszy niż %d\n",
|
||||
"Nieznana flaga odpluskwiania '%c'\n",
|
||||
"Nieznana opcja '%c'\n",
|
||||
"Nieznany u\277ytkownik '%s'\n",
|
||||
"Nie mog\352 zmieni\346 gid na %d\n",
|
||||
"Nie mog\352 zmieni\346 uid na %d\n",
|
||||
"Brak pami\352ci na zmienne \266rodowiska\n",
|
||||
"Nieznany użytkownik '%s'\n",
|
||||
"Nie mogę zmienić gid na %d\n",
|
||||
"Nie mogę zmienić uid na %d\n",
|
||||
"Brak pamięci na zmienne środowiska\n",
|
||||
"Brak znaku '='",
|
||||
"Brak nazwy zmiennej",
|
||||
"Brak wyra\277enia",
|
||||
"Nie mog\352 zmieni\346 daty dost\352pu pliku %s\n",
|
||||
"Brak wyrażenia",
|
||||
"Nie mogę zmienić daty dostępu pliku %s\n",
|
||||
"Remind: '-i' option: %s\n",
|
||||
"Brak przypomnie\361.",
|
||||
"%d Przypomnienia zakolejkowane na p\363\274niej.\n",
|
||||
"Brak przypomnień.",
|
||||
"%d Przypomnienia zakolejkowane na później.\n",
|
||||
"Spodziewana liczba",
|
||||
"Illegal function in WARN clause (NEEDS TRANSLATION TO POLISH)",
|
||||
"Can't convert between time zones",
|
||||
@@ -283,112 +236,6 @@ EXTERN char *ErrMsg[] =
|
||||
"String too long",
|
||||
"Time specified twice",
|
||||
"Cannot specify DURATION without specifying AT"
|
||||
#else /* ISOLATIN1 */
|
||||
"OK",
|
||||
"Brakujacy ']'",
|
||||
"Brakujacy nawias",
|
||||
"Zbyt skomplikowane wyrazenie - za duzo operatorow",
|
||||
"Zbyt skomplikowane wyrazenie - za duzo argumentow",
|
||||
"Brakujacy ')'",
|
||||
"Niezdefiniowana funkcja",
|
||||
"Nielegalny znak",
|
||||
"Spodziewany operator binarny",
|
||||
"Brak pamieci",
|
||||
"Niepoprawny numer",
|
||||
"Pusty stos operatorow - blad wewnetrzny",
|
||||
"Pusty stos zmiennych - blad wewnetrzny",
|
||||
"Niemozliwa konwersja",
|
||||
"Blad typu",
|
||||
"Nadmiar daty",
|
||||
"Blad stosu - blad wewnetrzny",
|
||||
"Dzielenie przez zero",
|
||||
"Niezdefiniowana zmienna",
|
||||
"Niespodziewany koniec linii",
|
||||
"Niespodziewany koniec pliku",
|
||||
"Blad wejscia/wyjscia",
|
||||
"Za dluga linia",
|
||||
"Blad wewnetrzny",
|
||||
"Zla specyfikacja daty",
|
||||
"Za malo argumentow",
|
||||
"Za duzo argumentow",
|
||||
"Nieprawidlowy czas",
|
||||
"Liczba za duza",
|
||||
"Liczba za mala",
|
||||
"Nie moge otworzyc pliku",
|
||||
"INCLUDE zbyt zagniezdzone",
|
||||
"Blad skladniowy",
|
||||
"Nie moge obliczyc przypomnienia",
|
||||
"Zbyt zagniezdzone IF",
|
||||
"ELSE bez IF do pary",
|
||||
"ENDIF bez IF do pary",
|
||||
"Nie moge ominac (OMIT) wszystkich dni",
|
||||
"Niespodziewany wyraz w lini",
|
||||
"POP-OMIT-CONTEXT bez PUSH-OMIT-CONTEXT",
|
||||
"Komenda RUN zablokowana",
|
||||
"Blad dziedziny",
|
||||
"Niepoprawny identyfikator",
|
||||
"Wykryto rekursywne wywolanie funkcji",
|
||||
"",
|
||||
"Nie moga zmienic zmiennej systemowej",
|
||||
"Funkcja biblioteki C nie moze reprezentowac daty/czasu",
|
||||
"Proba redefinicji funkcji wbudowanej",
|
||||
"Nie wolno zagniezdzac definicji funkcji w wyrazeniu",
|
||||
"Aby uzyc powtorzenia trzeba w pelni wyspecyfikowac date",
|
||||
"Rok podany dwokrotnie",
|
||||
"Miesiac podany dwokrotnie",
|
||||
"Dzien podany dwokrotnie",
|
||||
"Nieznane slowo",
|
||||
"W komendzie OMIT trzeba podac miesiac i dzien",
|
||||
"Za duzo czesciowych komend OMIT",
|
||||
"Za duzo pelnych komend OMIT",
|
||||
"ostrzezenie: PUSH-OMIT-CONTEXT bez POP-OMIT-CONTEXT",
|
||||
"Blad odczytu pliku",
|
||||
"Oczekiwany koniec linii",
|
||||
"Bledna data hebrajska",
|
||||
"IIF wymaga nieparzystej liczby argumentow",
|
||||
"Ostrzezenie: Brakujacy ENDIF",
|
||||
"Oczekiwany przecinek",
|
||||
"Dzien tygodnia podany dwokrotnie",
|
||||
"Dozwolone tylko jedno z: BEFORE, AFTER i SKIP",
|
||||
"Nie mozna zagniezdzac MSG, MSF, RUN, itp. w wyrazeniu",
|
||||
"Wartosc powtorzenia podana dwokrotnie",
|
||||
"Wartosc roznicy podana dwokrotnie",
|
||||
"Wartosc cofniecia podana dwokrotnie",
|
||||
"Slowo ONCE uzyte dwokrotnie.",
|
||||
"Po AT oczekiwany jest czas",
|
||||
"Slowo THROUGH/UNTIL uzyte dwokrotnie",
|
||||
"Niekompletna specyfikacja daty",
|
||||
"Slowo FROM/SCANFROM uzyte dwokrotnie",
|
||||
"Zmienna",
|
||||
"Wartosc",
|
||||
"*UNDEFINED*",
|
||||
"Poczatek UserFN",
|
||||
"Koniec UserFN",
|
||||
"Przeminelo",
|
||||
"niepowodzenie w funkcji fork() - nie moge kolejkowac przypomnien",
|
||||
"Nie ma dostepu do pliku",
|
||||
"Bledna data systemowa: Rok mniejszy niz %d\n",
|
||||
"Nieznana flaga odpluskwiania '%c'\n",
|
||||
"Nieznana opcja '%c'\n",
|
||||
"Nieznany uzytkownik '%s'\n",
|
||||
"Nie moge zmienic gid na %d\n",
|
||||
"Nie moge zmienic uid na %d\n",
|
||||
"Brak pamieci na zmienne srodowiska\n",
|
||||
"Brak znaku '='",
|
||||
"Brak nazwy zmiennej",
|
||||
"Brak wyrazenia",
|
||||
"Nie moge zmienic daty dostepu pliku %s\n",
|
||||
"Remind: '-i' option: %s\n",
|
||||
"Brak przypomnien.",
|
||||
"%d Przypomnienia zakolejkowane na pozniej.\n",
|
||||
"Spodziewana liczba",
|
||||
"Illegal function in WARN clause (NEEDS TRANSLATION TO POLISH)",
|
||||
"Can't convert between time zones",
|
||||
"No files matching *.rem",
|
||||
"String too long",
|
||||
"Time specified twice",
|
||||
"Cannot specify DURATION without specifying AT"
|
||||
#endif /* ISOLATIN1 */
|
||||
};
|
||||
#endif /* MK_GLOBALS */
|
||||
|
||||
@@ -397,67 +244,37 @@ EXTERN char *ErrMsg[] =
|
||||
#define L_USAGE_OVERRIDE 1
|
||||
void Usage(void)
|
||||
{
|
||||
fprintf(ErrFp, "\nREMIND %s (%s version) Copyright 1992-2020 Dianne Skoll\n", VERSION, L_LANGNAME);
|
||||
fprintf(ErrFp, "\nREMIND %s (%s version) Copyright 1992-2024 Dianne Skoll\n", VERSION, L_LANGNAME);
|
||||
#ifdef BETA
|
||||
fprintf(ErrFp, ">>>> BETA VERSION <<<<\n");
|
||||
#endif
|
||||
#if ISOLATIN1
|
||||
fprintf(ErrFp, "\nSpos\363b u\277ycia: remind [opcje] plik [data] [czas] [*powt\363rzenie]\n");
|
||||
fprintf(ErrFp, "\nSposób użycia: remind [opcje] plik [data] [czas] [*powtórzenie]\n");
|
||||
fprintf(ErrFp, "Opcje:\n");
|
||||
fprintf(ErrFp, " -n Wypisz nast\352pne przypomnienia w prostym formacie\n");
|
||||
fprintf(ErrFp, " -n Wypisz następne przypomnienia w prostym formacie\n");
|
||||
fprintf(ErrFp, " -r Zablokuj dyrektywy RUN\n");
|
||||
fprintf(ErrFp, " -c[n] Wypisz kalendarz na n (domy\266lnie 1) miesi\352cy\n");
|
||||
fprintf(ErrFp, " -c+[n] Wypisz kalendarz na n (domy\266lnie 1) tygodni\n");
|
||||
fprintf(ErrFp, " -w[n[,p[,s]]] Ustaw szeroko\266\346, wype\263nienie i odst\352py w kalendarzu\n");
|
||||
fprintf(ErrFp, " -s[+][n] Wypisz uproszczony kalendarz na n (1) miesi\352cy (tygodni)\n");
|
||||
fprintf(ErrFp, " -c[n] Wypisz kalendarz na n (domyślnie 1) miesięcy\n");
|
||||
fprintf(ErrFp, " -c+[n] Wypisz kalendarz na n (domyślnie 1) tygodni\n");
|
||||
fprintf(ErrFp, " -w[n[,p[,s]]] Ustaw szerokość, wypełnienie i odstępy w kalendarzu\n");
|
||||
fprintf(ErrFp, " -s[+][n] Wypisz uproszczony kalendarz na n (1) miesięcy (tygodni)\n");
|
||||
fprintf(ErrFp, " -p[n] To samo co -s, ale kompatybilne z rem2ps\n");
|
||||
fprintf(ErrFp, " -v Obszerniejsze komentarze\n");
|
||||
fprintf(ErrFp, " -o Ignoruj instrukcje ONCE\n");
|
||||
fprintf(ErrFp, " -t Odpal wszystkie przysz\263e przypomnienia niezale\277nie od delty\n");
|
||||
fprintf(ErrFp, " -t Odpal wszystkie przyszłe przypomnienia niezależnie od delty\n");
|
||||
fprintf(ErrFp, " -h Praca bezszmerowa\n");
|
||||
#ifdef HAVE_QUEUED
|
||||
fprintf(ErrFp, " -a Nie odpalaj przyponie\361 czasowych - kolejkuj je\n");
|
||||
fprintf(ErrFp, " -q Nie kolejkuj przyponie\361 czasowych\n");
|
||||
fprintf(ErrFp, " -f Nie przechod\274 do pracy w tle\n");
|
||||
fprintf(ErrFp, " -z[n] Pracuj jako demon, budz\261c si\352 co n (5) minut\n");
|
||||
fprintf(ErrFp, " -a Nie odpalaj przyponień czasowych - kolejkuj je\n");
|
||||
fprintf(ErrFp, " -q Nie kolejkuj przyponień czasowych\n");
|
||||
fprintf(ErrFp, " -f Nie przechodź do pracy w tle\n");
|
||||
fprintf(ErrFp, " -z[n] Pracuj jako demon, budząc się co n (5) minut\n");
|
||||
#endif
|
||||
fprintf(ErrFp, " -d... Odpluskwianie: e=echo x=expr-eval t=trig v=dumpvars l=showline\n");
|
||||
fprintf(ErrFp, " -e Komunikaty o b\263\352dach skieruj na stdout\n");
|
||||
fprintf(ErrFp, " -b[n] Format czasu: 0=am/pm, 1=24godz., 2=\277aden\n");
|
||||
fprintf(ErrFp, " -x[n] Limit powt\363rze\361 klauzuli SATISFY (domy\266lnie=150)\n");
|
||||
fprintf(ErrFp, " -kcmd Wywo\263aj 'cmd' dla przypomnie\361 typu MSG\n");
|
||||
fprintf(ErrFp, " -g[ddd] Sortuj przypomnienia wed\263ug daty, czasu i priorytetu\n");
|
||||
fprintf(ErrFp, " -ivar=val Zainicjuj zmienn\261 var warto\266cia val i zachowaj ja\n");
|
||||
fprintf(ErrFp, " -m Rozpocznij kalendarz od poniedzia\263ku zamiast od niedzieli\n");
|
||||
#else /* ISOLATIN1 */
|
||||
fprintf(ErrFp, "\nSposob uzycia: remind [opcje] plik [data] [czas] [*powtorzenie]\n");
|
||||
fprintf(ErrFp, "Opcje:\n");
|
||||
fprintf(ErrFp, " -n Wypisz nastepne przypomnienia w prostym formacie\n");
|
||||
fprintf(ErrFp, " -r Zablokuj dyrektywy RUN\n");
|
||||
fprintf(ErrFp, " -c[n] Wypisz kalendarz na n (domyslnie 1) miesiecy\n");
|
||||
fprintf(ErrFp, " -c+[n] Wypisz kalendarz na n (domyslnie 1) tygodni\n");
|
||||
fprintf(ErrFp, " -w[n[,p[,s]]] Ustaw szerokosc, wypelnienie i odstepy w kalendarzu\n");
|
||||
fprintf(ErrFp, " -s[+][n] Wypisz uproszczony kalendarz na n (1) miesiecy (tygodni)\n");
|
||||
fprintf(ErrFp, " -p[n] To samo co -s, ale kompatybilne z rem2ps\n");
|
||||
fprintf(ErrFp, " -v Obszerniejsze komentarze\n");
|
||||
fprintf(ErrFp, " -o Ignoruj instrukcje ONCE\n");
|
||||
fprintf(ErrFp, " -t Odpal wszystkie przyszle przypomnienia niezaleznie od delty\n");
|
||||
fprintf(ErrFp, " -h Praca bezszmerowa\n");
|
||||
#ifdef HAVE_QUEUED
|
||||
fprintf(ErrFp, " -a Nie odpalaj przyponien czasowych - kolejkuj je\n");
|
||||
fprintf(ErrFp, " -q Nie kolejkuj przyponien czasowych\n");
|
||||
fprintf(ErrFp, " -f Nie przechodz do pracy w tle\n");
|
||||
fprintf(ErrFp, " -z[n] Pracuj jako demon, budzac sie co n (5) minut\n");
|
||||
#endif
|
||||
fprintf(ErrFp, " -d... Odpluskwianie: e=echo x=expr-eval t=trig v=dumpvars l=showline\n");
|
||||
fprintf(ErrFp, " -e Komunikaty o bledach skieruj na stdout\n");
|
||||
fprintf(ErrFp, " -b[n] Format czasu: 0=am/pm, 1=24godz., 2=zaden\n");
|
||||
fprintf(ErrFp, " -x[n] Limit powtorzen klauzuli SATISFY (domyslnie=150)\n");
|
||||
fprintf(ErrFp, " -kcmd Wywolaj 'cmd' dla przypomnien typu MSG\n");
|
||||
fprintf(ErrFp, " -g[ddd] Sortuj przypomnienia wedlug daty, czasu i priorytetu\n");
|
||||
fprintf(ErrFp, " -ivar=val Zainicjuj zmienna var wartoscia val i zachowaj ja\n");
|
||||
fprintf(ErrFp, " -m Rozpocznij kalendarz od poniedzialku zamiast od niedzieli\n");
|
||||
#endif /* ISOLATIN1 */
|
||||
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=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");
|
||||
fprintf(ErrFp, " -m Rozpocznij kalendarz od poniedziałku zamiast od niedzieli\n");
|
||||
exit(1);
|
||||
}
|
||||
#endif /* L_IN_INIT */
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user