Script 'mail_helper' called by obssrc Hello community, here is the log from the commit of package remind for openSUSE:Factory checked in at 2023-04-19 17:42:43 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Comparing /work/SRC/openSUSE:Factory/remind (Old) and /work/SRC/openSUSE:Factory/.remind.new.2023 (New) ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Package is "remind" Wed Apr 19 17:42:43 2023 rev:34 rq:1080148 version:4.2.5 Changes: -------- --- /work/SRC/openSUSE:Factory/remind/remind.changes 2023-02-13 16:42:56.932092829 +0100 +++ /work/SRC/openSUSE:Factory/.remind.new.2023/remind.changes 2023-04-19 17:42:46.788124797 +0200 @@ -1,0 +2,62 @@ +Tue Apr 11 13:40:47 UTC 2023 - Detlef Steuer <detlef.ste...@gmx.de> + +- 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. + +------------------------------------------------------------------- Old: ---- remind-04.02.03.tar.gz New: ---- remind-04.02.05.tar.gz ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Other differences: ------------------ ++++++ remind.spec ++++++ --- /var/tmp/diff_new_pack.I6Z5iy/_old 2023-04-19 17:42:47.296127749 +0200 +++ /var/tmp/diff_new_pack.I6Z5iy/_new 2023-04-19 17:42:47.304127795 +0200 @@ -17,9 +17,9 @@ Name: remind -Version: 4.2.3 +Version: 4.2.5 Release: 0 -%define tar_version 04.02.03 +%define tar_version 04.02.05 Summary: A sophisticated calendar and alarm program License: GPL-2.0-only Group: Productivity/Office/Organizers ++++++ remind-04.02.03.tar.gz -> remind-04.02.05.tar.gz ++++++ diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/remind-04.02.03/configure new/remind-04.02.05/configure --- old/remind-04.02.03/configure 2023-02-10 18:57:53.000000000 +0100 +++ new/remind-04.02.05/configure 2023-04-11 14:25:54.000000000 +0200 @@ -3817,7 +3817,7 @@ -for ac_header in sys/types.h sys/file.h glob.h wctype.h locale.h langinfo.h +for ac_header in sys/types.h glob.h wctype.h locale.h langinfo.h do : as_ac_Header=`$as_echo "ac_cv_header_$ac_header" | $as_tr_sh` ac_fn_c_check_header_mongrel "$LINENO" "$ac_header" "$as_ac_Header" "$ac_includes_default" @@ -4025,7 +4025,7 @@ fi done -VERSION=04.02.03 +VERSION=04.02.05 diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/remind-04.02.03/configure.in new/remind-04.02.05/configure.in --- old/remind-04.02.03/configure.in 2023-02-10 18:57:53.000000000 +0100 +++ new/remind-04.02.05/configure.in 2023-04-11 14:25:54.000000000 +0200 @@ -35,7 +35,7 @@ AC_CHECK_SIZEOF(unsigned long) dnl Checks for header files. -AC_CHECK_HEADERS(sys/types.h sys/file.h glob.h wctype.h locale.h langinfo.h) +AC_CHECK_HEADERS(sys/types.h glob.h wctype.h locale.h langinfo.h) dnl Checks for typedefs, structures, and compiler characteristics. AC_STRUCT_TM @@ -80,7 +80,7 @@ exit 1 fi AC_CHECK_FUNCS(setenv unsetenv glob mbstowcs setlocale initgroups) -VERSION=04.02.03 +VERSION=04.02.05 AC_SUBST(VERSION) AC_SUBST(PERL) AC_SUBST(PERLARTIFACTS) diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/remind-04.02.03/docs/WHATSNEW new/remind-04.02.05/docs/WHATSNEW --- old/remind-04.02.03/docs/WHATSNEW 2023-02-10 18:57:53.000000000 +0100 +++ new/remind-04.02.05/docs/WHATSNEW 2023-04-11 14:25:54.000000000 +0200 @@ -1,5 +1,64 @@ CHANGES TO REMIND +* 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 diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/remind-04.02.03/examples/defs.rem new/remind-04.02.05/examples/defs.rem --- old/remind-04.02.03/examples/defs.rem 2023-02-10 18:57:53.000000000 +0100 +++ new/remind-04.02.05/examples/defs.rem 2023-04-11 14:25:54.000000000 +0200 @@ -42,7 +42,6 @@ SET Week_2 8 SET Week_3 15 SET Week_4 22 -FSET _last(mo) "1 " + MON((mo%12)+1) + " --7" ################################################################# # Function that removes a single leading zero from a string... # @@ -126,6 +125,8 @@ # 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 @@ -189,7 +190,7 @@ 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 Last Thu in Nov SCANFROM -7 ADDOMIT MSG %"Thanksgiving 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 diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/remind-04.02.03/include/holidays/us.rem new/remind-04.02.05/include/holidays/us.rem --- old/remind-04.02.03/include/holidays/us.rem 2023-02-10 18:57:53.000000000 +0100 +++ new/remind-04.02.05/include/holidays/us.rem 2023-04-11 14:25:54.000000000 +0200 @@ -14,6 +14,9 @@ # 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 @@ -21,8 +24,8 @@ 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 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 @@ -49,14 +52,21 @@ 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 July 3 SCANFROM -7 ADDOMIT SATISFY [$Tw==5] MSG Independence Day (observed) +REM July 5 SCANFROM -7 ADDOMIT SATISFY [$Tw==1] MSG Independence Day (observed) REM Third Sun in June MSG Father's Day REM First Mon in Sep SCANFROM -7 ADDOMIT MSG Labor Day REM Second Mon in Oct MSG Columbus Day / Indigenous Peoples' Day -REM Nov 11 MSG Veterans Day + +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 @@ -64,8 +74,9 @@ 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) diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/remind-04.02.03/man/remind.1.in new/remind-04.02.05/man/remind.1.in --- old/remind-04.02.03/man/remind.1.in 2023-02-10 18:57:53.000000000 +0100 +++ new/remind-04.02.05/man/remind.1.in 2023-04-11 14:25:54.000000000 +0200 @@ -328,6 +328,18 @@ shell and whitespace characters are escaped, the program you execute with the \fB\-k\fR option must be prepared to handle the entire message as a single argument. +.PP +If you follow the \fB\-k\fR option with a colon, then the command is applied +only to queued timed reminders. Normal reminders are handled as usual. +In the above example, if you want normal reminders to simply be displayed +as usual, but queued reminders to be sent to notify-send, you could use: +.PP +.nf + remind '\-k:notify-send %s &' ... +.fi +.PP +You use both \fB\-k\fR\fIcmd1\fR and \fB\-k:\fR\fIcmd2\fR to use different +commands for queued versus non-queued reminders. .RE .TP \fB\-z\fR[\fIn\fR] Runs \fBRemind\fR in the daemon mode. If \fIn\fR @@ -1006,7 +1018,7 @@ the last day of the month, regardless of the \fBOMIT\fR. .PP If you locally omit weekdays but also have globally-omitted weekdays, then -the list of ommitted weekdays is the union of the two. Consider this +the list of omitted weekdays is the union of the two. Consider this example: .PP .nf @@ -3074,6 +3086,16 @@ .B hour(tq_time) Returns the hour component of \fItime\fR. .TP +.B htmlescape(s_str) +Returns a modified copy of \fIstr\fR where "<" is replaced with +"<"; ">" is replaced with ">" and "&" is replaced with "&" +.TP +.B htmlstriptags(s_str) +Returns a modified copy of \fIstr\fR where HTML tags are stripped +out. The stripping algorithm is fairly naive; the function starts +stripping characters when it encounters a "<" and it stops stripping +when it encounters a ">". +.TP .B iif(si_test1, x_arg1, [si_test2, x_arg2,...], x_default) If \fItest1\fR is not zero or the null string, returns \fIarg1\fR. Otherwise, if \fItest2\fR is not zero or the null string, returns @@ -4065,15 +4087,30 @@ \fBCAL\fR, etc.) of a \fBREM\fR command. You can paste expressions before and after the \fBMSG\fR, etc. keywords, but cannot do something like this: +.RS .PP .nf - REM ["12 Nov 1993 AT 13:05 " + "MSG" + " BOO!"] + REM ["12 Nov 1993 AT 13:05 " + "MSG" + " BOO!"] .fi .PP -.B COMMON PITFALLS IN EXPRESSION PASTING +However, as an escape hatch, the sequence \fBSPECIAL\fR \fItype\fR +means the same thing as just \fItype\fR where \fItype\fR is one +of MSG, MSF, RUN, CAL, PS and PSFILE. This lets you do something +like this: +.PP +.nf + SET type "MSG" + REM 12 Nov 2024 SPECIAL [type] Hello +.fi +.PP +You can use this to control the types of your reminders based on variables +you set, how Remind is invoked, etc. +.RE +.PP +.B COMMON PITFALLS WITH EXPRESSION PASTING .PP -Remember, when pasting in expressions, that extra spaces are not -inserted. Thus, something like: +Remember that extra spaces are not inserted when an expression is +pasted. Thus, something like: .PP .nf REM[expr]MSG[expr] diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/remind-04.02.03/man/tkremind.1.in new/remind-04.02.05/man/tkremind.1.in --- old/remind-04.02.03/man/tkremind.1.in 2023-02-10 18:57:53.000000000 +0100 +++ new/remind-04.02.05/man/tkremind.1.in 2023-04-11 14:25:54.000000000 +0200 @@ -3,7 +3,7 @@ .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 diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/remind-04.02.03/rem2pdf/bin/rem2pdf.in new/remind-04.02.05/rem2pdf/bin/rem2pdf.in --- old/remind-04.02.03/rem2pdf/bin/rem2pdf.in 2023-02-10 18:57:53.000000000 +0100 +++ new/remind-04.02.05/rem2pdf/bin/rem2pdf.in 2023-04-11 14:25:54.000000000 +0200 @@ -37,7 +37,7 @@ numbers_on_left => 0, small_calendars => 0, fill_entire_page => 0, - + wrap_calendar => 0, media => 'Letter', width => 0, height => 0, @@ -86,6 +86,7 @@ --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 @@ -114,6 +115,7 @@ '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}, @@ -431,6 +433,14 @@ 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 diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/remind-04.02.03/rem2pdf/lib/Remind/PDF.pm new/remind-04.02.05/rem2pdf/lib/Remind/PDF.pm --- old/remind-04.02.03/rem2pdf/lib/Remind/PDF.pm 2023-02-10 18:57:53.000000000 +0100 +++ new/remind-04.02.05/rem2pdf/lib/Remind/PDF.pm 2023-04-11 14:25:54.000000000 +0200 @@ -110,7 +110,6 @@ $self->{daysinnextmonth} = 0; $self->{prevmonthyear} = 0; $self->{nextmonthyear} = 0; - for (my $i=0; $i<=31; $i++) { $self->{entries}->[$i] = []; } @@ -244,6 +243,143 @@ return $hash; } +=head2 setup_daymap + +Set up the array that maps ($row, $col) to day number (or -1 +for rows/cols out of range.) + +=cut +sub setup_daymap +{ + my ($self, $settings) = @_; + # First column + my $first_col = $self->{firstwkday}; + if ($self->{mondayfirst}) { + $first_col--; + if ($first_col < 0) { + $first_col = 6; + } + } + + # Last column + my $last_col = ($first_col + $self->{daysinmonth} - 1) % 7; + + # Number of rows + my $rows = 1; + my $last_day_on_row = 7 - $first_col; + while ($last_day_on_row < $self->{daysinmonth}) { + $last_day_on_row += 7; + $rows++; + } + + # Add a row for small calendars if necessary + if (($settings->{small_calendars} != 0) && ($first_col == 0) && ($last_col == 6)) { + $rows++; + $self->{extra_row} = 1; + } else { + $self->{extra_row} = 0; + } + $self->{rows} = $rows; + $self->{daymap} = []; + $self->{first_col} = $first_col; + $self->{last_col} = $last_col; + for (my $row=0; $row<$rows; $row++) { + for (my $col=0; $col < 7; $col++) { + $self->{daymap}->[$row]->[$col] = -1; + } + } + $self->{nextcal_row} = -1; + $self->{prevcal_row} = -1; + $self->{nextcal_col} = 6; + $self->{prevcal_col} = 0; + # Figure out where to draw the small calendars + my $extra_row = $self->{extra_row}; + if ($settings->{small_calendars} == 1) { + if ($last_col <= 4 || ($last_col == 6 && $extra_row)) { + $self->{prevcal_row} = $rows-1; + $self->{prevcal_col} = 5; + $self->{nextcal_row} = $rows-1; + $self->{nextcal_col} = 6; + } else { + $self->{prevcal_row} = 0; + $self->{prevcal_col} = 0; + $self->{nextcal_row} = 0; + $self->{nextcal_col} = 1; + } + } elsif ($settings->{small_calendars} == 2) { + if ($first_col >= 2) { + $self->{prevcal_row} = 0; + $self->{prevcal_col} = 0; + $self->{nextcal_row} = 0; + $self->{nextcal_col} = 1; + } else { + $self->{prevcal_row} = $rows-1; + $self->{prevcal_col} = 5; + $self->{nextcal_row} = $rows-1; + $self->{nextcal_col} = 6; + } + } elsif ($settings->{small_calendars} == 3) { + if ($first_col >= 1 && $last_col <= 5) { + $self->{prevcal_row} = 0; + $self->{prevcal_col} = 0; + $self->{nextcal_row} = $rows-1; + $self->{nextcal_col} = 6; + } else { + if ($last_col <= 4 || ($last_col == 6 && $extra_row)) { + $self->{prevcal_row} = $rows-1; + $self->{prevcal_col} = 5; + $self->{nextcal_row} = $rows-1; + $self->{nextcal_col} = 6; + } else { + $self->{prevcal_row} = 0; + $self->{prevcal_col} = 0; + $self->{nextcal_row} = 0; + $self->{nextcal_col} = 1; + } + } + } + + my $col = $first_col; + my $row = 0; + my $day = 1; + while ($day <= $self->{daysinmonth}) { + $self->{daymap}->[$row]->[$col] = $day; + $day++; + $col++; + if ($col > 6) { + $row++; + $col = 0; + } + } + + # Check if we should wrap the calendar + if ($self->{rows} == 6 && $settings->{wrap_calendar}) { + # Move everything in the last row to the first row + my $occupied_col = 0; + for (my $col=0; $col<7; $col++) { + if ($self->{daymap}->[5]->[$col] > 0) { + $self->{daymap}->[0]->[$col] = $self->{daymap}->[5]->[$col]; + $occupied_col = $col; + } else { + last; + } + } + if ($settings->{small_calendars}) { + $self->{prevcal_row} = 0; + $self->{prevcal_col} = $occupied_col+1; + $self->{nextcal_row} = 0; + $self->{nextcal_col} = $occupied_col+2; + for (my $col = 6; $col > 0; $col--) { + if ($self->{daymap}->[0]->[$col] < 0) { + $self->{nextcal_col} = $col; + last; + } + } + } + $self->{rows} = 5; + } +} + =head2 read_one_month_pp($in, $specials_accepted) This function reads one month's worth of data from the file handle @@ -329,6 +465,7 @@ { my ($self, $cr, $settings) = @_; + $self->setup_daymap($settings); $self->{horiz_lines} = []; $cr->set_line_cap('square'); my $so_far = $self->draw_title($cr, $settings); @@ -347,111 +484,25 @@ $self->{remaining_space} = $settings->{height} - $settings->{margin_bottom} - $so_far; $self->{minimum_row_height} = $self->{remaining_space} / 9; - # First column - my $first_col = $self->{firstwkday}; - if ($self->{mondayfirst}) { - $first_col--; - if ($first_col < 0) { - $first_col = 6; - } - } - - # Last column - my $last_col = ($first_col + $self->{daysinmonth} - 1) % 7; - - # Number of rows - my $rows = 1; - my $last_day_on_row = 7 - $first_col; - while ($last_day_on_row < $self->{daysinmonth}) { - $last_day_on_row += 7; - $rows++; - } - - my $extra_row = 0; - # Add a row for small calendars if necessary - if (($settings->{small_calendars} != 0) && ($first_col == 0) && ($last_col == 6)) { - $rows++; - $extra_row++; - } - - # Figure out where to draw the small calendars - my $prevcal_top = 0; - my $nextcal_top = 0; - my $prevcal_bottom = 0; - my $nextcal_bottom = 0; - - if ($settings->{small_calendars} == 1) { - if ($last_col <= 4 || ($last_col == 6 && $extra_row)) { - $prevcal_bottom = 1; - $nextcal_bottom = 1; - } else { - $prevcal_top = 1; - $nextcal_top = 1; - } - } elsif ($settings->{small_calendars} == 2) { - if ($first_col >= 2) { - $prevcal_top = 1; - $nextcal_top = 1; - } else { - $prevcal_bottom = 1; - $nextcal_bottom = 1; - } - } elsif ($settings->{small_calendars} == 3) { - if ($first_col >= 1 && $last_col <= 5) { - $prevcal_top = 1; - $nextcal_bottom = 1; - } else { - if ($last_col <= 4 || ($last_col == 6 && $extra_row)) { - $prevcal_bottom = 1; - $nextcal_bottom = 1; - } else { - $prevcal_top = 1; - $nextcal_top = 1; - } - } - } # Row height if we are filling the page - $self->{row_height} = $self->{remaining_space} / $rows; + $self->{row_height} = $self->{remaining_space} / $self->{rows}; - my ($start_col, $start_day); - for (my $row = 0; $row < $rows; $row++) { - if ($row == 0) { - $start_day = 1; - $start_col = $first_col; - } else { - $start_col = 0; - } + for (my $row = 0; $row < $self->{rows}; $row++) { my $old_so_far = $so_far; - $so_far = $self->draw_row($cr, $settings, $so_far, $row, $start_day, $start_col); - $start_day += 7 - $start_col; + $so_far = $self->draw_row($cr, $settings, $so_far, $row); push(@{$self->{horiz_lines}}, $so_far); - if ($row == 0) { - if ($prevcal_top) { - my ($x1, $y1, $x2, $y2) = $self->col_box_coordinates($old_so_far, 0, $so_far - $old_so_far, $settings); - $self->draw_small_calendar($cr, $x1 + $settings->{border_size}, $y1 + $settings->{border_size}, - $x2 - $x1 - 2*$settings->{border_size}, $y2 - $y1 - 2*$settings->{border_size}, - $settings, $self->{prevmonthname}, $self->{daysinprevmonth}, ($first_col + 35 - $self->{daysinprevmonth}) % 7); - } - if ($nextcal_top) { - my ($x1, $y1, $x2, $y2) = $self->col_box_coordinates($old_so_far, 1, $so_far - $old_so_far, $settings); - $self->draw_small_calendar($cr, $x1 + $settings->{border_size}, $y1 + $settings->{border_size}, - $x2 - $x1 - 2*$settings->{border_size}, $y2 - $y1 - 2*$settings->{border_size}, - $settings, $self->{nextmonthname}, $self->{daysinnextmonth}, ($last_col + 1) % 7); - } - } elsif ($row == $rows-1) { - if ($prevcal_bottom) { - my ($x1, $y1, $x2, $y2) = $self->col_box_coordinates($old_so_far, 5, $so_far - $old_so_far, $settings); - $self->draw_small_calendar($cr, $x1 + $settings->{border_size}, $y1 + $settings->{border_size}, - $x2 - $x1 - 2*$settings->{border_size}, $y2 - $y1 - 2*$settings->{border_size}, - $settings, $self->{prevmonthname}, $self->{daysinprevmonth}, ($first_col + 35 - $self->{daysinprevmonth}) % 7); - } - if ($nextcal_bottom) { - my ($x1, $y1, $x2, $y2) = $self->col_box_coordinates($old_so_far, 6, $so_far - $old_so_far, $settings); - $self->draw_small_calendar($cr, $x1 + $settings->{border_size}, $y1 + $settings->{border_size}, - $x2 - $x1 - 2*$settings->{border_size}, $y2 - $y1 - 2*$settings->{border_size}, - $settings, $self->{nextmonthname}, $self->{daysinnextmonth}, ($last_col + 1) % 7); - } + if ($row == $self->{prevcal_row}) { + my ($x1, $y1, $x2, $y2) = $self->col_box_coordinates($old_so_far, $self->{prevcal_col}, $so_far - $old_so_far, $settings); + $self->draw_small_calendar($cr, $x1 + $settings->{border_size}, $y1 + $settings->{border_size}, + $x2 - $x1 - 2*$settings->{border_size}, $y2 - $y1 - 2*$settings->{border_size}, + $settings, $self->{prevmonthname}, $self->{daysinprevmonth}, ($self->{first_col} + 35 - $self->{daysinprevmonth}) % 7); + } + if ($row == $self->{nextcal_row}) { + my ($x1, $y1, $x2, $y2) = $self->col_box_coordinates($old_so_far, $self->{nextcal_col}, $so_far - $old_so_far, $settings); + $self->draw_small_calendar($cr, $x1 + $settings->{border_size}, $y1 + $settings->{border_size}, + $x2 - $x1 - 2*$settings->{border_size}, $y2 - $y1 - 2*$settings->{border_size}, + $settings, $self->{nextmonthname}, $self->{daysinnextmonth}, ($self->{last_col} + 1) % 7); } } @@ -495,23 +546,18 @@ =cut sub draw_row { - my ($self, $cr, $settings, $so_far, $row, $start_day, $start_col) = @_; + my ($self, $cr, $settings, $so_far, $row) = @_; - my $col = $start_col; - my $day = $start_day; my $height = 0; # Preview them to figure out the row height... if (!$settings->{fill_entire_page}) { - while ($col < 7) { + for (my $col=0; $col<7; $col++) { + my $day = $self->{daymap}->[$row]->[$col]; + next if ($day < 1); my $h = $self->draw_day($cr, $settings, $so_far, $day, $col, 0); $height = $h if ($h > $height); - $day++; - $col++; - last if ($day > $self->{daysinmonth}); } - $col = $start_col; - $day = $start_day; } else { $height = $self->{row_height} - $settings->{border_size} * 2; } @@ -520,10 +566,10 @@ $height = $self->{minimum_row_height}; } # Now draw for real - while ($col < 7 && $day <= $self->{daysinmonth}) { + for (my $col=0; $col<7; $col++) { + my $day = $self->{daymap}->[$row]->[$col]; + next if ($day < 1); $self->draw_day($cr, $settings, $so_far, $day, $col, $height); - $day++; - $col++; } return $so_far + $height + $settings->{border_size}; @@ -908,7 +954,7 @@ return(undef, 'Unable to parse JSON stream'); } -=head2 Remind::PDF::Multi->create_from_stream($json, $specials_accepted) +=head2 Remind::PDF::Multi->create_from_json($json, $specials_accepted) This method takes data from a JSON string <$json>. C<$specials_accepted> is a hashref of SPECIAL reminder types to accept; the key is the name of the diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/remind-04.02.03/scripts/tkremind new/remind-04.02.05/scripts/tkremind --- old/remind-04.02.03/scripts/tkremind 2023-02-10 18:57:53.000000000 +0100 +++ new/remind-04.02.05/scripts/tkremind 2023-04-11 14:25:54.000000000 +0200 @@ -240,6 +240,9 @@ set OptDescr(PrintFill) "(0/1) If 1, fill entire page when printing" set Option(PrintFill) 1 +set OptDescr(WrapCal) "(0/1) If 1, make printed calendars occupy at most 5 rows" +set Option(WrapCal) 0 + set OptDescr(PrintDaysRight) "(0/1) If 1, put day numbers in the top-right of each calendar box" set Option(PrintDaysRight) 1 @@ -1290,6 +1293,7 @@ radiobutton .p.portrait -text "Portrait" -variable Option(PrintOrient) -value portrait checkbutton .p.fill -text "Fill page" -variable Option(PrintFill) + checkbutton .p.wrap -text "Use at most 5 rows (PDF only)" -variable Option(WrapCal) checkbutton .p.right -text "Day numbers at top-right" -variable Option(PrintDaysRight) checkbutton .p.encoding -text "ISO 8859-1 PostScript encoding" -variable Option(PrintEncoding) checkbutton .p.calendars -text "Print small calendars" -variable Option(PrintSmallCalendars) @@ -1300,12 +1304,14 @@ if {$HaveRem2PDF} { pack .p.f1 .p.ff .p.f2 .p.f2a .p.f3 .p.f3a \ -side top -fill both -expand 1 -anchor w + pack .p.fill .p.wrap .p.right .p.encoding .p.calendars -in .p.f3a \ + -side top -anchor w -fill none -expand 0 } else { pack .p.f1 .p.f2 .p.f2a .p.f3 .p.f3a \ -side top -fill both -expand 1 -anchor w - } - pack .p.fill .p.right .p.encoding .p.calendars -in .p.f3a \ + pack .p.fill .p.right .p.encoding .p.calendars -in .p.f3a \ -side top -anchor w -fill none -expand 0 + } pack .p.f4 -side top -fill both -expand 1 -anchor w pack .p.f11 .p.f12 -in .p.f1 -side top -fill none -expand 0 -anchor w pack .p.tofile .p.filename .p.browse -in .p.f11 -side left -fill none -expand 0 -anchor w @@ -1398,6 +1404,11 @@ } } + if {$Option(WrapCal)} { + if {$Option(PrintFormat) == "pdf"} { + append cmd " --wrap" + } + } if {$Option(PrintOrient) == "landscape"} { append cmd " -l" } @@ -3326,7 +3337,9 @@ set c [$w tag cget $ctag -foreground] } if {"$c" != ""} { - $w tag configure $tag -underline 1 -underlinefg $c + $w tag configure $tag -underline 1 + # underlinefg not supported on older versions of Tk + eval { $w tag configure $tag -underlinefg $c } } else { $w tag configure $tag -underline 1 } @@ -3633,7 +3646,9 @@ #*********************************************************************** proc DoMoonSpecial { n stuff fntag day } { set msg "" - set num [scan $stuff "%d %d %d %s" phase junk1 junk2 msg] + # Yes, this is gross, but the odds of ctrl-A appearing + # in the text associated with a MOON are small. + set num [scan $stuff {%d %d %d %[^]} phase junk1 junk2 msg] if {$num < 1} { return } diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/remind-04.02.03/src/calendar.c new/remind-04.02.05/src/calendar.c --- old/remind-04.02.03/src/calendar.c 2023-02-10 18:57:53.000000000 +0100 +++ new/remind-04.02.05/src/calendar.c 2023-04-11 14:25:54.000000000 +0200 @@ -1811,8 +1811,12 @@ FindToken(DBufValue(&buf), &tok); DBufFree(&buf); if (tok.type == T_Empty || tok.type == T_Comment) { + r = OK; + if (trig.addomit) { + r = AddGlobalOmit(LastTriggerDate); + } FreeTrig(&trig); - return OK; + return r; } if (tok.type != T_RemType || tok.val == SAT_TYPE) { FreeTrig(&trig); @@ -1830,6 +1834,10 @@ DBufFree(&buf); } trig.typ = tok.val; + + /* Convert some SPECIALs back to plain types */ + FixSpecialType(&trig); + if (trig.typ == MSG_TYPE || trig.typ == CAL_TYPE || trig.typ == MSF_TYPE) { diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/remind-04.02.03/src/config.h.in new/remind-04.02.05/src/config.h.in --- old/remind-04.02.03/src/config.h.in 2023-02-10 18:57:53.000000000 +0100 +++ new/remind-04.02.05/src/config.h.in 2023-04-11 14:25:54.000000000 +0200 @@ -7,9 +7,6 @@ /* 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 diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/remind-04.02.03/src/dorem.c new/remind-04.02.05/src/dorem.c --- old/remind-04.02.03/src/dorem.c 2023-02-10 18:57:53.000000000 +0100 +++ new/remind-04.02.05/src/dorem.c 2023-04-11 14:25:54.000000000 +0200 @@ -123,8 +123,12 @@ } StrnCpy(trig.passthru, DBufValue(&buf), PASSTHRU_LEN); DBufFree(&buf); - } - trig.typ = tok.val; + } + trig.typ = tok.val; + + /* Convert some SPECIALs back to plain types */ + FixSpecialType(&trig); + dse = LastTriggerDate; if (!LastTrigValid || PurgeMode) { FreeTrig(&trig); @@ -188,7 +192,7 @@ r = OK; if (ShouldTriggerReminder(&trig, &tim, dse, &err)) { - if ( (r=TriggerReminder(p, &trig, &tim, dse)) ) { + if ( (r=TriggerReminder(p, &trig, &tim, dse, 0)) ) { FreeTrig(&trig); return r; } @@ -370,6 +374,7 @@ } StrnCpy(trig->passthru, DBufValue(&buf), PASSTHRU_LEN); } + FixSpecialType(trig); parsing = 0; break; @@ -893,7 +898,7 @@ /* Trigger the reminder if it's a RUN or MSG type. */ /* */ /***************************************************************/ -int TriggerReminder(ParsePtr p, Trigger *t, TimeTrig *tim, int dse) +int TriggerReminder(ParsePtr p, Trigger *t, TimeTrig *tim, int dse, int is_queued) { int r, y, m, d; char PrioExpr[VAR_NAME_LEN+25]; @@ -901,8 +906,21 @@ 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; @@ -947,7 +965,7 @@ } /* 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) - && !DidMsgReminder && !NextMode && !MsgCommand) { + && !DidMsgReminder && !NextMode && !msg_command) { DidMsgReminder = 1; if (!DoSubstFromString(DBufValue(&Banner), &buf, DSEToday, NO_TIME) && @@ -1091,7 +1109,7 @@ 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; @@ -1113,8 +1131,8 @@ switch(t->typ) { case MSG_TYPE: case PASSTHRU_TYPE: - if (MsgCommand) { - DoMsgCommand(MsgCommand, DBufValue(&buf)); + if (msg_command) { + DoMsgCommand(msg_command, DBufValue(&buf)); } else { printf("%s", DBufValue(&buf)); } @@ -1466,3 +1484,25 @@ } } } + +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; + } +} diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/remind-04.02.03/src/dosubst.c new/remind-04.02.05/src/dosubst.c --- old/remind-04.02.03/src/dosubst.c 2023-02-10 18:57:53.000000000 +0100 +++ new/remind-04.02.05/src/dosubst.c 2023-04-11 14:25:54.000000000 +0200 @@ -196,7 +196,7 @@ mode != CAL_MODE && mode != ADVANCE_MODE && t->typ != RUN_TYPE && - !MsgCommand) { + !(MsgCommand && *MsgCommand)) { if (DBufPutc(dbuf, '\n') != OK) return E_NO_MEM; } break; @@ -794,7 +794,7 @@ break; case '_': - if (PsCal == PSCAL_LEVEL2 || PsCal == PSCAL_LEVEL3 || (mode != CAL_MODE && mode != ADVANCE_MODE && !MsgCommand)) { + if (PsCal == PSCAL_LEVEL2 || PsCal == PSCAL_LEVEL3 || (mode != CAL_MODE && mode != ADVANCE_MODE && !(MsgCommand && *MsgCommand))) { snprintf(s, sizeof(s), "%s", NL); } else { snprintf(s, sizeof(s), " "); diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/remind-04.02.03/src/funcs.c new/remind-04.02.05/src/funcs.c --- old/remind-04.02.03/src/funcs.c 2023-02-10 18:57:53.000000000 +0100 +++ new/remind-04.02.05/src/funcs.c 2023-04-11 14:25:54.000000000 +0200 @@ -30,10 +30,6 @@ #include <fcntl.h> #include <unistd.h> -#ifdef HAVE_SYS_FILE_H -#include <sys/file.h> -#endif - #include <sys/types.h> #include <sys/stat.h> @@ -101,6 +97,8 @@ static int FHebmon (func_info *); static int FHebyear (func_info *); static int FHour (func_info *); +static int FHtmlEscape (func_info *); +static int FHtmlStriptags (func_info *); static int FIif (func_info *); static int FIndex (func_info *); static int FIsdst (func_info *); @@ -265,6 +263,8 @@ { "hebmon", 1, 1, 0, FHebmon }, { "hebyear", 1, 1, 0, FHebyear }, { "hour", 1, 1, 1, FHour }, + { "htmlescape", 1, 1, 1, FHtmlEscape }, + { "htmlstriptags",1, 1, 1, FHtmlStriptags }, { "iif", 1, NO_MAX, 1, FIif }, { "index", 2, 3, 1, FIndex }, { "isany", 1, NO_MAX, 1, FIsAny }, @@ -1167,15 +1167,27 @@ if (Nargs < 4 || !ARGV(3)) { /* Pad on the LEFT */ for (i=0; i<wantlen-len; i++) { - DBufPutc(&dbuf, *s++); + if (DBufPutc(&dbuf, *s++) != OK) { + DBufFree(&dbuf); + return E_NO_MEM; + } if (!*s) s = ARGSTR(1); } - DBufPuts(&dbuf, ARGSTR(0)); + if (DBufPuts(&dbuf, ARGSTR(0)) != OK) { + DBufFree(&dbuf); + return E_NO_MEM; + } } else { /* Pad on the RIGHT */ - DBufPuts(&dbuf, ARGSTR(0)); + if (DBufPuts(&dbuf, ARGSTR(0)) != OK) { + DBufFree(&dbuf); + return E_NO_MEM; + } for (i=0; i<wantlen-len; i++) { - DBufPutc(&dbuf, *s++); + if (DBufPutc(&dbuf, *s++) != OK) { + DBufFree(&dbuf); + return E_NO_MEM; + } if (!*s) s = ARGSTR(1); } } @@ -2248,6 +2260,92 @@ RETVAL = y; return OK; } + +/****************************************************************/ +/* */ +/* htmlescape - replace <. > and & by < > and & */ +/* */ +/****************************************************************/ +static int FHtmlEscape(func_info *info) +{ + DynamicBuffer dbuf; + char const *s; + int r; + + ASSERT_TYPE(0, STR_TYPE); + + DBufInit(&dbuf); + + s = ARGSTR(0); + while(*s) { + switch(*s) { + case '<': + r = DBufPuts(&dbuf, "<"); + break; + + case '>': + r = DBufPuts(&dbuf, ">"); + break; + + case '&': + r = DBufPuts(&dbuf, "&"); + break; + + default: + r = DBufPutc(&dbuf, *s); + break; + } + if (r != OK) { + DBufFree(&dbuf); + return r; + } + s++; + } + r = RetStrVal(DBufValue(&dbuf), info); + DBufFree(&dbuf); + return r; +} + +/****************************************************************/ +/* */ +/* htmlstriptags - strip out HTML tags from a string */ +/* */ +/****************************************************************/ +static int FHtmlStriptags(func_info *info) +{ + DynamicBuffer dbuf; + char const *s; + int r = OK; + + int in_tag = 0; + ASSERT_TYPE(0, STR_TYPE); + + DBufInit(&dbuf); + + s = ARGSTR(0); + while(*s) { + if (!in_tag) { + if (*s == '<') { + in_tag = 1; + } else { + r = DBufPutc(&dbuf, *s); + } + } else { + if (*s == '>') { + in_tag = 0; + } + } + if (r != OK) { + DBufFree(&dbuf); + return r; + } + s++; + } + r = RetStrVal(DBufValue(&dbuf), info); + DBufFree(&dbuf); + return r; +} + /****************************************************************/ /* */ /* FEasterdate - calc. easter Sunday from a year. */ diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/remind-04.02.03/src/globals.h new/remind-04.02.05/src/globals.h --- old/remind-04.02.03/src/globals.h 2023-02-10 18:57:53.000000000 +0100 +++ new/remind-04.02.05/src/globals.h 2023-04-11 14:25:54.000000000 +0200 @@ -52,6 +52,7 @@ 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); diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/remind-04.02.03/src/init.c new/remind-04.02.05/src/init.c --- old/remind-04.02.03/src/init.c 2023-02-10 18:57:53.000000000 +0100 +++ new/remind-04.02.05/src/init.c 2023-04-11 14:25:54.000000000 +0200 @@ -600,7 +600,12 @@ 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; diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/remind-04.02.03/src/omit.c new/remind-04.02.05/src/omit.c --- old/remind-04.02.03/src/omit.c 2023-02-10 18:57:53.000000000 +0100 +++ new/remind-04.02.05/src/omit.c 2023-04-11 14:25:54.000000000 +0200 @@ -377,8 +377,12 @@ break; default: - Eprint("%s: `%s' (OMIT)", ErrMsg[E_UNKNOWN_TOKEN], - DBufValue(&buf)); + if (tok.type == T_Until) { + Eprint("OMIT: UNTIL not allowed; did you mean THROUGH?"); + } else { + Eprint("%s: `%s' (OMIT)", ErrMsg[E_UNKNOWN_TOKEN], + DBufValue(&buf)); + } DBufFree(&buf); return E_UNKNOWN_TOKEN; } diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/remind-04.02.03/src/protos.h new/remind-04.02.05/src/protos.h --- old/remind-04.02.03/src/protos.h 2023-02-10 18:57:53.000000000 +0100 +++ new/remind-04.02.05/src/protos.h 2023-04-11 14:25:54.000000000 +0200 @@ -35,7 +35,7 @@ int DoFlush (ParsePtr p); void DoExit (ParsePtr p); int ParseRem (ParsePtr s, Trigger *trig, TimeTrig *tim, int save_in_globals); -int TriggerReminder (ParsePtr p, Trigger *t, TimeTrig *tim, int dse); +int TriggerReminder (ParsePtr p, Trigger *t, TimeTrig *tim, int dse, int is_queued); int ShouldTriggerReminder (Trigger *t, TimeTrig *tim, int dse, int *err); int DoSubst (ParsePtr p, DynamicBuffer *dbuf, Trigger *t, TimeTrig *tt, int dse, int mode); int DoSubstFromString (char const *source, DynamicBuffer *dbuf, int dse, int tim); @@ -177,6 +177,7 @@ void clear_callstack(void); int print_callstack(FILE *fp); void pop_call(void); +void FixSpecialType(Trigger *trig); #ifdef REM_USE_WCHAR #define _XOPEN_SOURCE 600 #include <wctype.h> diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/remind-04.02.03/src/queue.c new/remind-04.02.05/src/queue.c --- old/remind-04.02.03/src/queue.c 2023-02-10 18:57:53.000000000 +0100 +++ new/remind-04.02.05/src/queue.c 2023-04-11 14:25:54.000000000 +0200 @@ -267,7 +267,7 @@ /* Set up global variables so some functions like trigdate() and trigtime() work correctly */ SaveAllTriggerInfo(&(q->t), &(q->tt), DSEToday, q->tt.ttime, 1); - (void) TriggerReminder(&p, &trig, &q->tt, DSEToday); + (void) TriggerReminder(&p, &trig, &q->tt, DSEToday, 1); if (Daemon < 0) { printf("NOTE endreminder\n"); } diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/remind-04.02.03/src/sort.c new/remind-04.02.05/src/sort.c --- old/remind-04.02.03/src/sort.c 2023-02-10 18:57:53.000000000 +0100 +++ new/remind-04.02.05/src/sort.c 2023-04-11 14:25:54.000000000 +0200 @@ -135,7 +135,7 @@ next = cur->next; switch(cur->typ) { case MSG_TYPE: - if (MsgCommand) { + if (MsgCommand && *MsgCommand) { DoMsgCommand(MsgCommand, cur->text); } else { if (cur->trigdate != olddate) { diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/remind-04.02.03/src/userfns.c new/remind-04.02.05/src/userfns.c --- old/remind-04.02.03/src/userfns.c 2023-02-10 18:57:53.000000000 +0100 +++ new/remind-04.02.05/src/userfns.c 2023-04-11 14:25:54.000000000 +0200 @@ -124,7 +124,11 @@ DBufFree(&buf); return E_NO_MEM; } - func->filename = StrDup(FileName); + if (FileName) { + func->filename = StrDup(FileName); + } else { + func->filename = StrDup("[cmdline]"); + } if (!func->filename) { free(func); return E_NO_MEM; diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/remind-04.02.03/tests/test-rem new/remind-04.02.05/tests/test-rem --- old/remind-04.02.03/tests/test-rem 2023-02-10 18:57:53.000000000 +0100 +++ new/remind-04.02.05/tests/test-rem 2023-04-11 14:25:54.000000000 +0200 @@ -27,6 +27,10 @@ exit 1 fi +# Set a known timezone so moon phases show up in predictable places +TZ=UTC +export TZ + # If we're already in a utf-8 locale, do # nothing; otherwise, set LC_ALL OK=0 @@ -418,6 +422,9 @@ ../src/remind include_dir/ww >> ../tests/test.out 2>&1 rm -rf include_dir/ww +# This segfaulted in 04.02.03 +../src/remind -h '-imsgprefix(x)="foo"' /dev/null >> ../tests/test.out 2>&1 + # Remove references to SysInclude, which is build-specific grep -F -v '$SysInclude' < ../tests/test.out > ../tests/test.out.1 && mv -f ../tests/test.out.1 ../tests/test.out cmp -s ../tests/test.out ../tests/test.cmp @@ -428,7 +435,11 @@ echo "Remind: Acceptance test FAILED" echo "" echo "Examine the file test.out to see where it differs from the" - echo "reference file test.cmp." + echo "reference file test.cmp. Here are the first 200 lines of" + echo "diff -u test.out test.cmp" + echo "" + diff -u ../tests/test.out ../tests/test.cmp | head -n 200 + echo "" exit 1 fi diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/remind-04.02.03/tests/test.cmp new/remind-04.02.05/tests/test.cmp --- old/remind-04.02.03/tests/test.cmp 2023-02-10 18:57:53.000000000 +0100 +++ new/remind-04.02.05/tests/test.cmp 2023-04-11 14:25:54.000000000 +0200 @@ -1060,7 +1060,7 @@ "a05" + "6" => "a056" value("a056") => "SDFJHSDF KSJDFH KJSDFH KSJDFH" set a058 version() -version() => "04.02.03" +version() => "04.02.05" set a059 wkday(today()) today() => 1991-02-16 wkday(1991-02-16) => "Saturday" @@ -2644,7 +2644,7 @@ a109 2012-01-01 a128 2018-02-03@16:45 a039 "February" -a058 "04.02.03" +a058 "04.02.05" a077 "1992 92\n" a096 -4 a119 -1 @@ -4786,6 +4786,41 @@ SET a square(5) ../tests/test.rem(867): Undefined function: `square' +# htmlescape +set a htmlescape("foo") +htmlescape("foo") => "foo" +REM MSG [a] +../tests/test.rem(871): Trig = Saturday, 16 February, 1991 +a => "foo" +foo + +set a htmlescape("<&>") +htmlescape("<&>") => "<&>" +REM MSG [a] +../tests/test.rem(873): Trig = Saturday, 16 February, 1991 +a => "<&>" +<&> + +set a htmlescape("@&^#*@&^##$*&@><><@#@#><@#>%%_#$foobarquux") +htmlescape("@&^#*@&^##$*&@><><@#@#><@#>%%_#$foobarqu"...) => "@&^#*@&^##$*&@><>&l"... +REM MSG [a] +../tests/test.rem(875): Trig = Saturday, 16 February, 1991 +a => "@&^#*@&^##$*&@><>&l"... +@&^#*@&^##$*&@><><@#@#><@#>%_#$foobarquux + + +# htmlstriptags +set a htmlstriptags("foobar") +htmlstriptags("foobar") => "foobar" +set a htmlstriptags("This is <b>bold</b>") +htmlstriptags("This is <b>bold</b>") => "This is bold" +set a htmlstriptags("This is <unclosed whut?") +htmlstriptags("This is <unclosed whut?") => "This is " +set a htmlstriptags("this is > whut <b>foo</b>") +htmlstriptags("this is > whut <b>foo</b>") => "this is > whut foo" +set a htmlstriptags("<img src=\"foo\">") +htmlstriptags("<img src=\"foo\">") => "" + # Don't want Remind to queue reminders EXIT diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/remind-04.02.03/tests/test.rem new/remind-04.02.05/tests/test.rem --- old/remind-04.02.03/tests/test.rem 2023-02-10 18:57:53.000000000 +0100 +++ new/remind-04.02.05/tests/test.rem 2023-04-11 14:25:54.000000000 +0200 @@ -866,6 +866,21 @@ # Should fail SET a square(5) +# htmlescape +set a htmlescape("foo") +REM MSG [a] +set a htmlescape("<&>") +REM MSG [a] +set a htmlescape("@&^#*@&^##$*&@><><@#@#><@#>%%_#$foobarquux") +REM MSG [a] + +# htmlstriptags +set a htmlstriptags("foobar") +set a htmlstriptags("This is <b>bold</b>") +set a htmlstriptags("This is <unclosed whut?") +set a htmlstriptags("this is > whut <b>foo</b>") +set a htmlstriptags("<img src=\"foo\">") + # Don't want Remind to queue reminders EXIT