mirror of
https://salsa.debian.org/dskoll/remind.git
synced 2026-04-16 14:28:40 +02:00
Compare commits
49 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
3190f784d9 | ||
|
|
394ff55879 | ||
|
|
9b846835bc | ||
|
|
01776af167 | ||
|
|
0db10424ad | ||
|
|
bafd7ea073 | ||
|
|
0ab27fcb4b | ||
|
|
95d016712e | ||
|
|
fcb55001bb | ||
|
|
7bc6961101 | ||
|
|
450e88fad8 | ||
|
|
3222b4c311 | ||
|
|
1e0cc3605d | ||
|
|
129b7bfeb7 | ||
|
|
388811b684 | ||
|
|
f83257407b | ||
|
|
e4ced77340 | ||
|
|
92e0bc316a | ||
|
|
a4a55f35b2 | ||
|
|
ed1150c189 | ||
|
|
08080f4e86 | ||
|
|
de4ebb8be6 | ||
|
|
11e2ce5093 | ||
|
|
2c560e6f2b | ||
|
|
643f394e6a | ||
|
|
6d047c2856 | ||
|
|
be86746685 | ||
|
|
da429b9629 | ||
|
|
b21a206c26 | ||
|
|
85bde8ba3a | ||
|
|
f84e658e6b | ||
|
|
8f0eba8bcd | ||
|
|
2faaaf78a8 | ||
|
|
7f659dace2 | ||
|
|
54cdd566c7 | ||
|
|
e212df87f9 | ||
|
|
4fb4db15e8 | ||
|
|
9a15a25a7b | ||
|
|
c02cfb9b17 | ||
|
|
3e726f21f7 | ||
|
|
21d4faa26f | ||
|
|
1d13d0ee07 | ||
|
|
329d13e480 | ||
|
|
2161c09b1d | ||
|
|
3f2e396c3c | ||
|
|
412e242109 | ||
|
|
e827516b72 | ||
|
|
7f953e98d7 | ||
|
|
821d3fe783 |
@@ -61,7 +61,7 @@ AC_CHECK_SIZEOF(unsigned int)
|
||||
AC_CHECK_SIZEOF(unsigned long)
|
||||
|
||||
dnl Checks for header files.
|
||||
AC_CHECK_HEADERS(sys/file.h glob.h)
|
||||
AC_CHECK_HEADERS(sys/file.h glob.h wctype.h locale.h)
|
||||
|
||||
dnl Checks for typedefs, structures, and compiler characteristics.
|
||||
AC_STRUCT_TM
|
||||
@@ -74,7 +74,7 @@ if test "$GCC" = yes; then
|
||||
CFLAGS="$CFLAGS -Wall -Wstrict-prototypes"
|
||||
fi
|
||||
|
||||
AC_CHECK_FUNCS(setenv unsetenv glob)
|
||||
VERSION=03.01.09
|
||||
AC_CHECK_FUNCS(setenv unsetenv glob mbstowcs setlocale)
|
||||
VERSION=03.01.11
|
||||
AC_SUBST(VERSION)
|
||||
AC_OUTPUT(src/Makefile www/Makefile src/version.h)
|
||||
|
||||
@@ -109,10 +109,10 @@
|
||||
(sort
|
||||
(list "RUN" "REM" "ONCE" "SATISFY" "BEFORE" "UNSET" "OMIT"
|
||||
"OMIT" "DATE" "SKIP" "ONCE" "AFTER" "WARN" "PRIORITY" "AT" "SCHED" "IF" "ELSE" "ENDIF"
|
||||
"WARN" "UNTIL" "SCANFROM" "DURATION" "TAG" "MSG" "MSF" "CAL" "SPECIAL" "IFTRIG"
|
||||
"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")
|
||||
"EXIT" "FLUSH" "PRESERVE" "MOON" "COLOR" "COLOUR")
|
||||
#'(lambda (a b) (> (length a) (length b)))))
|
||||
|
||||
(defconst remind-type-keywords
|
||||
|
||||
@@ -1,5 +1,43 @@
|
||||
CHANGES TO REMIND
|
||||
|
||||
* Version 3.1 Patch 11 - 2011-12-16
|
||||
|
||||
- BUG FIX: For some inexplicable reason, dawn was considered to happen when
|
||||
the sun was 14 degrees below the horizon instead of the standard 6
|
||||
degrees for Civil Dawn. This has been fixed.
|
||||
|
||||
- BUG FIXES: Clarified the man pages and fixed some typos.
|
||||
|
||||
- BUG FIX: Add THROUGH to the remind.vim syntax highlighting file.
|
||||
|
||||
- ENHANCEMENT (?): Allow SPECIAL COLOR to be spelled SPECIAL COLOUR.
|
||||
|
||||
- BUG FIX: Apply minor Debian cleanups reported by Kurt B. Kaiser.
|
||||
|
||||
* Version 3.1 Patch 10 - 2010-11-01
|
||||
|
||||
- NOTE: This is the 20th anniversary of Remind's first public release.
|
||||
|
||||
- ENHANCEMENT: Add the THROUGH keyword. You can omit blocks of dates with:
|
||||
|
||||
OMIT start THROUGH end
|
||||
|
||||
and the syntax REM start THROUGH end is equivalent to REM start *1 UNTIL end
|
||||
|
||||
- ENHANCEMENT: Add support for multibyte characters (eg, UTF-8) in calendar
|
||||
output. Note that UTF-8 strings are still not supported in PostScript
|
||||
output.
|
||||
|
||||
- ENHANCEMENT: Add support for UTF-8 line-drawing characters in calendar
|
||||
output.
|
||||
|
||||
- ENHANCEMENT: You can have multiple TAG clauses in a REM statement.
|
||||
|
||||
- BUG FIX: Avoid spawning long-running background processes in "make test".
|
||||
|
||||
- BUG FIX: Don't declare variables in the middle of statements (old C
|
||||
compilers choke.)
|
||||
|
||||
* Version 3.1 Patch 9 - 2010-06-20
|
||||
|
||||
- MAJOR ENHANCEMENT: New "purge mode" to delete expired reminders. See
|
||||
|
||||
@@ -1,53 +1,79 @@
|
||||
" Vim syntax file
|
||||
" Language: Remind
|
||||
" Maintainer: Davide Alberani <alberanid@bigfoot.com>
|
||||
" Last change: 03 Dec 1999
|
||||
" Version: 0.1
|
||||
" URL: http://members.xoom.com/alberanid/vim/syntax/remind.vim
|
||||
" Maintainer: Davide Alberani <alberanid@libero.it>
|
||||
" Last Change: 18 Sep 2009
|
||||
" Version: 0.5
|
||||
" URL: http://erlug.linux.it/~da/vim/syntax/remind.vim
|
||||
"
|
||||
" remind is a sophisticated reminder service
|
||||
" you can download remind from ftp://ftp.doe.carleton.ca/pub/remind-3.0/
|
||||
" you can download remind from:
|
||||
" http://www.roaringpenguin.com/penguin/open_source_remind.php
|
||||
|
||||
" clear any unwanted syntax defs
|
||||
syn clear
|
||||
if version < 600
|
||||
syntax clear
|
||||
elseif exists("b:current_syntax")
|
||||
finish
|
||||
endif
|
||||
|
||||
" shut case off
|
||||
" shut case off.
|
||||
syn case ignore
|
||||
|
||||
syn keyword remindCommands REM OMIT SET FSET UNSET
|
||||
syn keyword remindExpiry UNTIL SCANFROM SCAN WARN SCHED
|
||||
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
|
||||
syn keyword remindSpecial INCLUDE INC BANNER PUSH-OMIT-CONTEXT PUSH CLEAR-OMIT-CONTEXT CLEAR POP-OMIT-CONTEXT POP COLOR COLOUR
|
||||
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
|
||||
syn match remindComment "#.*$"
|
||||
syn region remindString start=+'+ end=+'+ skip=+\\\\\|\\'+ oneline
|
||||
syn region remindString start=+"+ end=+"+ skip=+\\\\\|\\"+ oneline
|
||||
syn keyword remindDebug DEBUG DUMPVARS DUMP ERRMSG FLUSH PRESERVE
|
||||
syn match remindVar "\$[_a-zA-Z][_a-zA-Z0-9]*"
|
||||
syn match remindSubst "%[^ ]"
|
||||
syn match remindAdvanceNumber "\(\*\|+\|-\|++\|--\)[0-9]\+"
|
||||
" XXX: use different separators for dates and times?
|
||||
syn match remindDateSeparators "[/:@\.-]" contained
|
||||
syn match remindTimes "[0-9]\{1,2}[:\.][0-9]\{1,2}" contains=remindDateSeparators
|
||||
" XXX: why not match only valid dates? Ok, checking for 'Feb the 30' would
|
||||
" be impossible, but at least check for valid months and times.
|
||||
syn match remindDates "'[0-9]\{4}[/-][0-9]\{1,2}[/-][0-9]\{1,2}\(@[0-9]\{1,2}[:\.][0-9]\{1,2}\)\?'" contains=remindDateSeparators
|
||||
" This will match trailing whitespaces that seem to break rem2ps.
|
||||
" Courtesy of Michael Dunn.
|
||||
syn match remindWarning display excludenl "\S\s\+$"ms=s+1
|
||||
|
||||
if !exists("did_remind_syntax_inits")
|
||||
let did_remind_syntax_inits = 1
|
||||
hi link remindCommands Function
|
||||
hi link remindExpiry Repeat
|
||||
hi link remindTag Label
|
||||
hi link remindTimed Statement
|
||||
hi link remindMove Statement
|
||||
hi link remindSpecial Include
|
||||
hi link remindRun Function
|
||||
hi link remindConditional Conditional
|
||||
hi link remindComment Comment
|
||||
hi link remindString String
|
||||
hi link remindDebug Debug
|
||||
hi link remindVar Identifier
|
||||
hi link remindSubst Constant
|
||||
hi link remindAdvanceNumber Number
|
||||
|
||||
if version >= 508 || !exists("did_remind_syn_inits")
|
||||
if version < 508
|
||||
let did_remind_syn_inits = 1
|
||||
command -nargs=+ HiLink hi link <args>
|
||||
else
|
||||
command -nargs=+ HiLink hi def link <args>
|
||||
endif
|
||||
|
||||
HiLink remindCommands Function
|
||||
HiLink remindExpiry Repeat
|
||||
HiLink remindTag Label
|
||||
HiLink remindTimed Statement
|
||||
HiLink remindMove Statement
|
||||
HiLink remindSpecial Include
|
||||
HiLink remindRun Function
|
||||
HiLink remindConditional Conditional
|
||||
HiLink remindComment Comment
|
||||
HiLink remindTimes String
|
||||
HiLink remindString String
|
||||
HiLink remindDebug Debug
|
||||
HiLink remindVar Identifier
|
||||
HiLink remindSubst Constant
|
||||
HiLink remindAdvanceNumber Number
|
||||
HiLink remindDateSeparators Comment
|
||||
HiLink remindDates String
|
||||
HiLink remindWarning Error
|
||||
|
||||
delcommand HiLink
|
||||
endif
|
||||
|
||||
let b:current_syntax = "remind"
|
||||
|
||||
"EOF vim: ts=8 noet tw=100 sw=8 sts=0
|
||||
" vim: ts=8 sw=2
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
.TH CM2REM 1 "18 October 1999"
|
||||
.UC4
|
||||
.UC 4
|
||||
.SH NAME
|
||||
cm2rem.tcl \- Convert Sun's "cm" input file to Remind format
|
||||
.SH SYNOPSIS
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
.TH REM 1 "30 August 2007"
|
||||
.UC4
|
||||
.UC 4
|
||||
.SH NAME
|
||||
rem \- Invoke Remind with a default filename
|
||||
.SH SYNOPSIS
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
.TH REM2PS 1 "11 April 2005"
|
||||
.UC4
|
||||
.UC 4
|
||||
.SH NAME
|
||||
rem2ps \- draw a PostScript calendar from Remind output
|
||||
.SH SYNOPSIS
|
||||
@@ -362,7 +362,10 @@ Other back-ends may understand other specials. A back end should
|
||||
\fIsilently ignore\fR a reminder with a special it doesn't understand.
|
||||
.PP
|
||||
\fItag\fR is whatever tag the user provided with the \fBTAG\fR clause,
|
||||
or "*" if no tag was provided.
|
||||
or "*" if no tag was provided. If there is more than one \fBTAG\fR clause,
|
||||
the tags appear in a comma-separated list. For example, the command
|
||||
\fBREM TAG foo TAG bar TAG quux\fR would result in \fBfoo,bar,quux\fR
|
||||
in the \fItag\fR field.
|
||||
.PP
|
||||
\fIdur\fR is the \fBDURATION\fR value in minutes, or "*" if no duration
|
||||
was provided.
|
||||
|
||||
125
man/remind.1
125
man/remind.1
@@ -61,6 +61,11 @@ causes \fBRemind\fR to use VT100 line-drawing characters to draw
|
||||
the calendar. The characters are hard-coded and will only work
|
||||
on terminals that emulate the VT00 line-drawing character set.
|
||||
.TP
|
||||
.B 'u'
|
||||
is similar to 'l', but causes \fBRemind\fR to use UNICODE line-drawing
|
||||
characters to draw the calendar. The characters are hard-coded and will
|
||||
only work on terminals that are set to UTF-8 character encoding.
|
||||
.TP
|
||||
.B 'c'
|
||||
causes \fBRemind\fR to use VT100 escape sequences to approximate
|
||||
SPECIAL COLOR reminders. The approximation is (of necessity) very
|
||||
@@ -220,7 +225,7 @@ As an example, suppose you have an X Window program called \fBxmessage\fR that
|
||||
pops up a window and displays its invocation arguments. You could use:
|
||||
.PP
|
||||
.nf
|
||||
remind '-kxmessage %s &' ...
|
||||
remind '\-kxmessage %s &' ...
|
||||
.fi
|
||||
.PP
|
||||
to have all of your \fBMSG\fR-type reminders processed using xmessage.
|
||||
@@ -330,6 +335,16 @@ wish to pass a \fBRemind\fR script through the C pre-processor, which
|
||||
interprets the '#' character as the start of a pre-processing
|
||||
directive.
|
||||
.PP
|
||||
Note that \fBRemind\fR processes line continuations before anything else.
|
||||
For example:
|
||||
.PP
|
||||
.nf
|
||||
# This is a comment \\
|
||||
This line is part of the comment because of line continuation \\
|
||||
and so on.
|
||||
REM MSG This line is not ignored (no \\ above)
|
||||
.fi
|
||||
.PP
|
||||
\fBRemind\fR is not case sensitive; you can generally use any mixture of upper-
|
||||
or lower-case for commands, parameters, invocation options, etc.
|
||||
.SH THE REM COMMAND
|
||||
@@ -350,7 +365,7 @@ Its syntax is:
|
||||
[\fBAT\fR \fItime\fR [\fItdelta\fR] [\fItrepeat\fR]]
|
||||
[\fBSCHED\fR \fIsched_function\fR]
|
||||
[\fBWARN\fR \fIwarn_function\fR]
|
||||
[\fBUNTIL\fR \fIexpiry_date\fR]
|
||||
[\fBUNTIL\fR \fIexpiry_date\fR | \fBTHROUGH\fR \fIlast_date\fR]
|
||||
[\fBSCANFROM\fR \fIscan_date\fR | \fBFROM\fR \fIstart_date\fR]
|
||||
[\fBDURATION\fR \fIduration\fR]
|
||||
[\fBTAG\fR \fItag\fR]
|
||||
@@ -691,7 +706,7 @@ month is computed as the first Monday in the next month, minus 7 days.
|
||||
The \fIback\fR specification in the reminder is used in this case:
|
||||
.PP
|
||||
.nf
|
||||
REM Mon 1 -7 MSG Last Monday of every month.
|
||||
REM Mon 1 \-7 MSG Last Monday of every month.
|
||||
.fi
|
||||
.PP
|
||||
A \fIback\fR is specified with one or two dashes followed by an integer.
|
||||
@@ -786,6 +801,15 @@ of your jury duty, as well as 2 days ahead of time:
|
||||
Note that the \fIrepeat\fR of *1 is necessary; without it, the reminder
|
||||
would be issued only on 30 November (and the two days preceding.)
|
||||
.PP
|
||||
As a special case, you can use the \fBTHROUGH\fR keyword instead of
|
||||
*1 and \fBUNTIL\fR. The following two \fBREM\fR commands are equivalent:
|
||||
.PP
|
||||
.nf
|
||||
REM 1992-11-30 *1 +2 UNTIL 1992-12-04 MSG Jury duty
|
||||
|
||||
REM 1992-11-30 +2 THROUGH 1992-12-04 MSG Jury duty
|
||||
.fi
|
||||
.PP
|
||||
.B THE ONCE KEYWORD
|
||||
.PP
|
||||
Sometimes, it is necessary to ensure that reminders are run only once
|
||||
@@ -833,7 +857,7 @@ the reminder is triggered on the first of each month, as well as the day
|
||||
preceding it. The omitted days are counted.
|
||||
.PP
|
||||
.nf
|
||||
REM 1 -1 OMIT Sat Sun MSG Last working day of month
|
||||
REM 1 \-1 OMIT Sat Sun MSG Last working day of month
|
||||
.fi
|
||||
.PP
|
||||
Again, in the above example, the \fIback\fR of \-1 normally causes the
|
||||
@@ -961,7 +985,7 @@ command-line option. This is useful, for example, in .xinitrc
|
||||
scripts, where you can use the command:
|
||||
.PP
|
||||
.nf
|
||||
remind -fa myreminders &
|
||||
remind \-fa myreminders &
|
||||
.fi
|
||||
.PP
|
||||
This ensures that when you exit X-Windows, the \fBRemind\fR process is killed.
|
||||
@@ -989,11 +1013,11 @@ expressions and user-defined functions are explained. See the subsection
|
||||
The \fBTAG\fR keyword lets you "tag" certain reminders. This facility
|
||||
is used by certain back-ends or systems built around \fBRemind\fR,
|
||||
such as \fBTkRemind\fR. These back-ends have specific rules about
|
||||
tags; you should \fInot\fR use the \fBTAG\fR keyword yourself, or
|
||||
your script will interact badly with back-ends.
|
||||
tags; see their documentation for details.
|
||||
.PP
|
||||
The \fBTAG\fR keyword is followed by a tag consisting of up to
|
||||
48 characters.
|
||||
48 characters. You can have as many TAG clauses as you like in
|
||||
a given REM statement.
|
||||
.PP
|
||||
If you supply the \fB\-y\fR option to \fBRemind\fR, then any
|
||||
reminder that lacks a \fBTAG\fR will have one synthesized. The
|
||||
@@ -1289,6 +1313,10 @@ In addition to being a keyword in the \fBREM\fR command,
|
||||
.PP
|
||||
.RS
|
||||
\fBOMIT\fR \fIday\fR \fImonth\fR [\fIyear\fR]
|
||||
.PP
|
||||
or:
|
||||
.PP
|
||||
\fBOMIT\fR \fIday1\fR \fImonth1\fR \fIyear1\fR \fBTHROUGH\fR \fIday2\fR \fImonth2\fR \fIyear2\fR
|
||||
.RE
|
||||
.PP
|
||||
The \fBOMIT\fR command is used to "globally" omit certain days
|
||||
@@ -1316,7 +1344,7 @@ the following are equivalent:
|
||||
.fi
|
||||
.PP
|
||||
For convenience, you can use a \fIdelta\fR and \fBMSG\fR or \fBRUN\fR
|
||||
keyword in the \fBOMIT\fR command. The following sequences are exactly
|
||||
keyword in the \fBOMIT\fR command. The following sequences are
|
||||
equivalent:
|
||||
.PP
|
||||
.nf
|
||||
@@ -1328,6 +1356,36 @@ equivalent:
|
||||
OMIT 1 Jan +4 MSG New year's day is %b!
|
||||
.fi
|
||||
.PP
|
||||
The \fBTHROUGH\fR keyword lets you conveniently OMIT a range of days.
|
||||
The starting and ending points must be fully-specified (ie, they must
|
||||
include day, month and year.). For example, the following sequences
|
||||
are equivalent:
|
||||
.PP
|
||||
.nf
|
||||
OMIT 3 Jan 2011
|
||||
OMIT 4 Jan 2011
|
||||
OMIT 5 Jan 2011
|
||||
|
||||
and
|
||||
|
||||
OMIT 3 Jan 2011 THROUGH 5 Jan 2011
|
||||
.fi
|
||||
.PP
|
||||
You can make a THROUGH \fBOMIT\fR do double-duty as a \fBREM\fR command:
|
||||
.PP
|
||||
.nf
|
||||
OMIT 6 Sep 2010 THROUGH 10 Sep 2010 MSG Vacation
|
||||
.fi
|
||||
|
||||
.PP
|
||||
You can debug your global OMITs with the following command:
|
||||
.PP
|
||||
.nf
|
||||
OMIT DUMP
|
||||
.fi
|
||||
.PP
|
||||
The OMIT DUMP command prints the current global omits to standard output.
|
||||
.PP
|
||||
.B THE BEFORE, AFTER AND SKIP KEYWORDS
|
||||
.PP
|
||||
Normally, days that are omitted, whether by a global \fBOMIT\fR
|
||||
@@ -1895,7 +1953,7 @@ If non-zero, then the \fB\-t\fR option was supplied on the command line.
|
||||
.TP
|
||||
.B $LatDeg, $LatMin, $LatSec
|
||||
These specify the latitude of your location. \fB$LatDeg\fR can
|
||||
range from -90 to 90, and the others from -59 to 59. Northern latitudes
|
||||
range from \-90 to 90, and the others from \-59 to 59. Northern latitudes
|
||||
are positive; southern ones are negative. For southern latitudes, all
|
||||
three components should be negative.
|
||||
.TP
|
||||
@@ -1907,8 +1965,10 @@ the latitude and longitude system variables.
|
||||
.TP
|
||||
.B $LongDeg, $LongMin, $LongSec
|
||||
These specify the longitude of your location. \fB$LongDeg\fR can
|
||||
range from -180 to 180. Western longitudes are positive; eastern
|
||||
ones are negative.
|
||||
range from \-180 to 180. Western longitudes are positive; eastern
|
||||
ones are negative. Note that all three components should have the
|
||||
same sign: All positive for Western longitudes and all negative
|
||||
for Eastern longitudes.
|
||||
.RS
|
||||
.PP
|
||||
The latitude and longitude information is required for the functions
|
||||
@@ -2056,11 +2116,11 @@ be a string, containing a mix of the characters "rwx" for read,
|
||||
write and execute permission testing. Alternatively, \fImode\fR can
|
||||
be a number as described in the UNIX \fBaccess\fR(2) system call. The
|
||||
function returns 0 if the file can be accessed with the specified \fImode\fR,
|
||||
and -1 otherwise.
|
||||
and \-1 otherwise.
|
||||
.TP
|
||||
.B args(s_fname)
|
||||
Returns the number of arguments expected by the user-defined function
|
||||
\fIfname\fR, or -1 if no such user-defined function exists. Note that
|
||||
\fIfname\fR, or \-1 if no such user-defined function exists. Note that
|
||||
this function examines only user-defined functions, not built-in functions.
|
||||
Its main use is to determine whether or not a particular user-defined
|
||||
function has been defined previously. The \fBargs()\fR function is
|
||||
@@ -2566,7 +2626,7 @@ does not check for this.) For example, if you want the time of each new
|
||||
moon displayed, you could use this in your reminder script:
|
||||
.PP
|
||||
.nf
|
||||
REM [moondate(0)] PS [psmoon(0, -1, moontime(0)+"")]
|
||||
REM [moondate(0)] PS [psmoon(0, \-1, moontime(0)+"")]
|
||||
.fi
|
||||
.PP
|
||||
Note how the time is coerced to a string by concatenating the null string.
|
||||
@@ -2608,7 +2668,7 @@ Returns the date as provided by the operating system. This is in contrast to
|
||||
in calendar mode, or if a date has been supplied on the command line.
|
||||
.TP
|
||||
.B sgn(i_num)
|
||||
Returns -1 if \fInum\fR is negative, 1 if \fInum\fR is positive,
|
||||
Returns \-1 if \fInum\fR is negative, 1 if \fInum\fR is positive,
|
||||
and 0 if \fInum\fR is zero.
|
||||
.TP
|
||||
.B shell(s_cmd [,i_maxlen])
|
||||
@@ -2645,7 +2705,7 @@ May 16 and 17. You can go backwards, too, so:
|
||||
.PP
|
||||
.nf
|
||||
OMIT 14 May 2009
|
||||
SET a slide('2009-05-21', -5, "Sat", "Sun")
|
||||
SET a slide('2009-05-21', \-5, "Sat", "Sun")
|
||||
.fi
|
||||
.PP
|
||||
takes \fIa\fR back to 2009-05-13.
|
||||
@@ -2863,7 +2923,7 @@ exceptions:
|
||||
o
|
||||
If \fBRemind\fR is expecting an expression, as in the \fBSET\fR command,
|
||||
or the \fBIF\fR command, you should \fBnot\fR include square brackets.
|
||||
FOr example, use:
|
||||
For example, use:
|
||||
.PP
|
||||
.nf
|
||||
SET a 4+5
|
||||
@@ -2987,7 +3047,7 @@ to true if a corresponding \fBREM\fR command would trigger. Examples:
|
||||
; Executed except on 1 Nov
|
||||
ENDIF
|
||||
|
||||
IFTRIG 1 -1 OMIT Sat Sun +4
|
||||
IFTRIG 1 \-1 OMIT Sat Sun +4
|
||||
; Executed on last working day of month,
|
||||
; and the 4 working days preceding it
|
||||
ELSE
|
||||
@@ -3015,7 +3075,7 @@ you define a function taking no parameters. Here are some examples:
|
||||
.nf
|
||||
FSET double(x) 2*x
|
||||
FSET yeardiff(date1, date2) year(date1) - year(date2)
|
||||
FSET since(x) ord(year(trigdate())-x)
|
||||
FSET since(x) ord(year(trigdate())\-x)
|
||||
.fi
|
||||
.PP
|
||||
The last function is useful in birthday reminders. For example:
|
||||
@@ -3139,7 +3199,7 @@ clause to do anything.
|
||||
Here's an example:
|
||||
.PP
|
||||
.nf
|
||||
FSET _sfun(x) choose(x, -60, 30, 15, 10, 3, 1, 1, 1, 1, 0)
|
||||
FSET _sfun(x) choose(x, \-60, 30, 15, 10, 3, 1, 1, 1, 1, 0)
|
||||
REM AT 13:00 SCHED _sfun MSG foo
|
||||
.fi
|
||||
.PP
|
||||
@@ -3391,7 +3451,7 @@ program to produce a calendar in PostScript format. For example, the
|
||||
following command will send PostScript code to standard output:
|
||||
.PP
|
||||
.nf
|
||||
remind -p .reminders | rem2ps
|
||||
remind \-p .reminders | rem2ps
|
||||
.fi
|
||||
.PP
|
||||
You can print a PostScript calendar by piping this to the \fBlpr\fR command.
|
||||
@@ -3400,7 +3460,7 @@ If you have a reminder script called ".reminders", and you
|
||||
execute this command:
|
||||
.PP
|
||||
.nf
|
||||
remind -c .reminders jan 1993
|
||||
remind \-c .reminders jan 1993
|
||||
.fi
|
||||
.PP
|
||||
then \fBRemind\fR executes the script 31 times, once for each day in
|
||||
@@ -3633,7 +3693,7 @@ In daemon mode, \fBRemind\fR acts as if the \fB\-f\fR option had been used,
|
||||
so to run in the daemon mode in the background, use:
|
||||
.PP
|
||||
.nf
|
||||
remind -z .reminders &
|
||||
remind \-z .reminders &
|
||||
.fi
|
||||
.PP
|
||||
If you use \fBsh\fR or \fBbash\fR, you may have to use the "nohup" command
|
||||
@@ -4048,7 +4108,7 @@ Calculations" by E. M. Reingold and Nachum Dershowitz.
|
||||
.PP
|
||||
The \fBSPECIAL\fR keyword is used to transmit "out-of-band" information
|
||||
to \fBRemind\fR backends, such as \fBtkremind\fR or \fBRem2PS\fR.
|
||||
They are used only when piping data from a \fBremind -p\fR line.
|
||||
They are used only when piping data from a \fBremind \-p\fR line.
|
||||
(Note that the COLOR special is an exception; it downgrades to the
|
||||
equivalent of MSG in \fBremind's\fR normal mode of operation.)
|
||||
.PP
|
||||
@@ -4089,7 +4149,7 @@ of the \fBMOON\fR special is as follows:
|
||||
1 the first quarter, 2 a full moon and 3 the last quarter.
|
||||
.PP
|
||||
\fImoonsize\fR is the diameter in PostScript units of the moon to
|
||||
draw. If omitted or supplied as -1, the backend chooses an appropriate
|
||||
draw. If omitted or supplied as \-1, the backend chooses an appropriate
|
||||
size.
|
||||
.PP
|
||||
\fIfontsize\fR is the font size in PostScript units of the \fImsg\fR
|
||||
@@ -4107,6 +4167,9 @@ calendar. Use it like this:
|
||||
REM ... SPECIAL COLOR 0 128 0 This is a dark green reminder
|
||||
.fi
|
||||
|
||||
You can spell COLOR either the American way ("COLOR") or the British
|
||||
way ("COLOUR"). This manual will use the American way.
|
||||
|
||||
Immediately following COLOR should be three decimal numbers ranging
|
||||
from 0 to 255 specifying red, green and blue intensities, respectively.
|
||||
The rest of the line is the text to put in the calendar.
|
||||
@@ -4163,7 +4226,7 @@ This section is a sampling of what you can do with \fBRemind\fR.
|
||||
.PP
|
||||
.nf
|
||||
REM 5 Feb 1991 AT 14:00 +45 *30 \\
|
||||
RUN mail -s "Meeting at %2" $LOGNAME </dev/null &
|
||||
RUN mail \-s "Meeting at %2" $LOGNAME </dev/null &
|
||||
.fi
|
||||
.PP
|
||||
On 5 February, 1991, this reminder will mail
|
||||
@@ -4172,14 +4235,14 @@ you reminders of a 2:00pm meeting at 1:15,
|
||||
and the body of the message will be blank.
|
||||
.PP
|
||||
.nf
|
||||
REM AT 17:00 RUN echo "5:00pm - GO HOME!" | xless -g +0+0 &
|
||||
REM AT 17:00 RUN echo "5:00pm - GO HOME!" | xless \-g +0+0 &
|
||||
.fi
|
||||
.PP
|
||||
This reminder will pop up an xless window at 5:00pm every day. The xless
|
||||
window will contain the line "5:00pm - GO HOME!"
|
||||
.PP
|
||||
.nf
|
||||
REM AT 23:59 RUN (sleep 120; remind -a [filename()]) &
|
||||
REM AT 23:59 RUN (sleep 120; remind \-a [filename()]) &
|
||||
.fi
|
||||
.PP
|
||||
This reminder will run at one minute to midnight. It will cause a new
|
||||
@@ -4197,7 +4260,7 @@ This invocation of \fBRemind\fR will cause it to print a calendar for
|
||||
1993, with all entries left blank.
|
||||
.PP
|
||||
.nf
|
||||
REM CAL [trigdate()-date(year(trigdate()), 1, 1)+1]
|
||||
REM CAL [trigdate()\-date(year(trigdate()), 1, 1)+1]
|
||||
.fi
|
||||
.PP
|
||||
This example puts an entry in each box of a calendar showing the number
|
||||
@@ -4257,7 +4320,7 @@ in September. It can move over a range of 7 days. Consider the
|
||||
following sequence:
|
||||
.PP
|
||||
.nf
|
||||
REM Mon 1 Sept SCANFROM [today()-7] SATISFY 1
|
||||
REM Mon 1 Sept SCANFROM [today()\-7] SATISFY 1
|
||||
OMIT [trigdate()]
|
||||
|
||||
REM Mon AFTER MSG Hello
|
||||
|
||||
@@ -74,7 +74,7 @@ The next control specifies an expiry date for the reminder. Select
|
||||
the check button to enable an expiry date, and fill in the values
|
||||
using pull-down menus.
|
||||
|
||||
The third control specifes how much advance notice you want (if any),
|
||||
The third control specifies how much advance notice you want (if any),
|
||||
and whether or not weekends and holidays are counted when computing advance
|
||||
notice.
|
||||
|
||||
@@ -179,7 +179,7 @@ it starts up in a normal window.
|
||||
.TP
|
||||
.B Show Today's Reminders on Startup
|
||||
If this is selected, \fBTkRemind\fR shows a text window containing reminders
|
||||
which would be issued by "remind -q -a -r" on startup, and when the date
|
||||
which would be issued by "remind \-q \-a \-r" on startup, and when the date
|
||||
changes at midnight.
|
||||
|
||||
.TP
|
||||
@@ -268,7 +268,7 @@ the body. Furthermore, if you use expression-pasting in the body,
|
||||
When \fBTkRemind\fR invokes \fBRemind\fR, it supplies the option:
|
||||
.PP
|
||||
.nf
|
||||
-itkremind=1
|
||||
\-itkremind=1
|
||||
.fi
|
||||
.PP
|
||||
on the command line. So, in your \fBRemind\fR file, you can include:
|
||||
@@ -289,7 +289,9 @@ file to store additional state. You can certainly mix
|
||||
if you are aware of the following rules and limitations:
|
||||
.TP
|
||||
o
|
||||
Do not use the \fBTAG\fR keyword in hand-crafted reminders.
|
||||
\fBTkRemind\fR uses \fBTAG\fRs of the form \fBTKTAG\fR\fInnn\fR
|
||||
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
|
||||
|
||||
@@ -392,11 +392,7 @@ proc ConfigureCalFrame { w firstDay numDays } {
|
||||
set first [expr $offset+1]
|
||||
set last [expr $offset+$numDays]
|
||||
|
||||
if {$tk_version >= 8.5} {
|
||||
set bg "#d9d9d9"
|
||||
} else {
|
||||
set bg [lindex [$w.t0 configure -background] 3]
|
||||
}
|
||||
set bg [lindex [. configure -background] 3]
|
||||
|
||||
for {set i 0} {$i < $first} {incr i} {
|
||||
grid $w.l$i $w.t$i
|
||||
@@ -800,6 +796,7 @@ proc FillCalWindow {} {
|
||||
DoMoonSpecial $n $stuff
|
||||
continue
|
||||
}
|
||||
"COLOUR" -
|
||||
"COLOR" {
|
||||
if {[regexp {^ *([0-9]+) +([0-9]+) +([0-9]+) +(.*)$} $stuff all r g b rest]} {
|
||||
if {$r > 255} {
|
||||
@@ -826,7 +823,7 @@ proc FillCalWindow {} {
|
||||
}
|
||||
}
|
||||
}
|
||||
if { $type != "*" && $type != "COLOR"} {
|
||||
if { $type != "*" && $type != "COLOR" && $type != "COLOUR"} {
|
||||
continue
|
||||
}
|
||||
.cal.t$n configure -state normal
|
||||
|
||||
502
src/calendar.c
502
src/calendar.c
@@ -18,6 +18,10 @@
|
||||
|
||||
#include <stdlib.h>
|
||||
|
||||
#ifdef REM_USE_WCHAR
|
||||
#include <wctype.h>
|
||||
#endif
|
||||
|
||||
#include "types.h"
|
||||
#include "protos.h"
|
||||
#include "expr.h"
|
||||
@@ -30,11 +34,15 @@ typedef struct cal_entry {
|
||||
struct cal_entry *next;
|
||||
char const *text;
|
||||
char const *pos;
|
||||
#ifdef REM_USE_WCHAR
|
||||
wchar_t const *wc_text;
|
||||
wchar_t const *wc_pos;
|
||||
#endif
|
||||
int is_color;
|
||||
int r, g, b;
|
||||
int time;
|
||||
int priority;
|
||||
char tag[TAG_LEN+1];
|
||||
DynamicBuffer tags;
|
||||
char passthru[PASSTHRU_LEN+1];
|
||||
int duration;
|
||||
char const *filename;
|
||||
@@ -45,17 +53,32 @@ typedef struct cal_entry {
|
||||
struct line_drawing {
|
||||
char const *graphics_on;
|
||||
char const *graphics_off;
|
||||
char tlr, bl, tbl, blr, tblr, tr, tb, br, tbr, tl, lr;
|
||||
char *tlr, *bl, *tbl, *blr, *tblr, *tr, *tb, *br, *tbr, *tl, *lr;
|
||||
};
|
||||
|
||||
static struct line_drawing NormalDrawing = {
|
||||
"", "", '+', '+', '+', '+', '+', '+', '|', '+', '+', '+', '-'
|
||||
"", "", "+", "+", "+", "+", "+", "+", "|", "+", "+", "+", "-"
|
||||
};
|
||||
|
||||
static struct line_drawing VT100Drawing = {
|
||||
"\x1B(0", "\x1B(B",
|
||||
'\x76', '\x6b', '\x75', '\x77', '\x6e', '\x6d', '\x78',
|
||||
'\x6c', '\x74', '\x6a', '\x71'
|
||||
"\x76", "\x6b", "\x75", "\x77", "\x6e", "\x6d", "\x78",
|
||||
"\x6c", "\x74", "\x6a", "\x71"
|
||||
};
|
||||
|
||||
static struct line_drawing UTF8Drawing = {
|
||||
"", "",
|
||||
"\xe2\x94\xb4",
|
||||
"\xe2\x94\x90",
|
||||
"\xe2\x94\xa4",
|
||||
"\xe2\x94\xac",
|
||||
"\xe2\x94\xbc",
|
||||
"\xe2\x94\x94",
|
||||
"\xe2\x94\x82",
|
||||
"\xe2\x94\x8c",
|
||||
"\xe2\x94\x9c",
|
||||
"\xe2\x94\x98",
|
||||
"\xe2\x94\x80"
|
||||
};
|
||||
|
||||
static char *VT100Colors[2][2][2][2] /* [Br][R][G][B] */ = {
|
||||
@@ -108,7 +131,7 @@ static char *VT100Colors[2][2][2][2] /* [Br][R][G][B] */ = {
|
||||
};
|
||||
|
||||
static struct line_drawing *linestruct;
|
||||
#define DRAW(x) putchar(linestruct->x)
|
||||
#define DRAW(x) fputs(linestruct->x, stdout)
|
||||
|
||||
/* Global variables */
|
||||
static CalEntry *CalColumn[7];
|
||||
@@ -124,7 +147,7 @@ static int WriteCalendarRow (void);
|
||||
static void WriteWeekHeaderLine (void);
|
||||
static void WritePostHeaderLine (void);
|
||||
static void PrintLeft (char const *s, int width, char pad);
|
||||
static void PrintCentered (char const *s, int width, char pad);
|
||||
static void PrintCentered (char const *s, int width, char *pad);
|
||||
static int WriteOneCalLine (void);
|
||||
static int WriteOneColLine (int col);
|
||||
static void GenerateCalEntries (int col);
|
||||
@@ -137,6 +160,40 @@ static void WriteBottomCalLine (void);
|
||||
static void WriteIntermediateCalLine (void);
|
||||
static void WriteCalDays (void);
|
||||
|
||||
#ifdef REM_USE_WCHAR
|
||||
static void PutWideChar(wchar_t const wc)
|
||||
{
|
||||
char buf[MB_CUR_MAX+1];
|
||||
int len;
|
||||
|
||||
len = wctomb(buf, wc);
|
||||
if (len > 0) {
|
||||
buf[len] = 0;
|
||||
fputs(buf, stdout);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
static int make_wchar_versions(CalEntry *e)
|
||||
{
|
||||
#ifdef REM_USE_WCHAR
|
||||
size_t len;
|
||||
wchar_t *buf;
|
||||
len = mbstowcs(NULL, e->text, 0);
|
||||
if (len == (size_t) -1) return 0;
|
||||
|
||||
buf = calloc(len+1, sizeof(wchar_t));
|
||||
if (!buf) return 0;
|
||||
|
||||
(void) mbstowcs(buf, e->text, len+1);
|
||||
e->wc_text = buf;
|
||||
e->wc_pos = buf;
|
||||
return 1;
|
||||
#else
|
||||
return 1;
|
||||
#endif
|
||||
}
|
||||
|
||||
static void gon(void)
|
||||
{
|
||||
printf("%s", linestruct->graphics_on);
|
||||
@@ -179,7 +236,9 @@ void ProduceCalendar(void)
|
||||
{
|
||||
int y, m, d;
|
||||
|
||||
if (UseVTChars) {
|
||||
if (UseUTF8Chars) {
|
||||
linestruct = &UTF8Drawing;
|
||||
} else if (UseVTChars) {
|
||||
linestruct = &VT100Drawing;
|
||||
} else {
|
||||
linestruct = &NormalDrawing;
|
||||
@@ -460,20 +519,55 @@ static void PrintLeft(char const *s, int width, char pad)
|
||||
/* */
|
||||
/* PrintCentered */
|
||||
/* */
|
||||
/* Center a piec of text */
|
||||
/* Center a piece of text */
|
||||
/* */
|
||||
/***************************************************************/
|
||||
static void PrintCentered(char const *s, int width, char pad)
|
||||
static void PrintCentered(char const *s, int width, char *pad)
|
||||
{
|
||||
#ifndef REM_USE_WCHAR
|
||||
int len = strlen(s);
|
||||
int d = (width - len) / 2;
|
||||
int i;
|
||||
|
||||
for (i=0; i<d; i++) PutChar(pad);
|
||||
for (i=0; i<d; i++) fputs(pad, stdout);
|
||||
for (i=0; i<width; i++) {
|
||||
if (*s) PutChar(*s++); else break;
|
||||
}
|
||||
for (i=d+len; i<width; i++) PutChar(pad);
|
||||
for (i=d+len; i<width; i++) fputs(pad, stdout);
|
||||
#else
|
||||
size_t len = mbstowcs(NULL, s, 0);
|
||||
int i;
|
||||
wchar_t static_buf[128];
|
||||
wchar_t *buf;
|
||||
wchar_t *ws;
|
||||
int d;
|
||||
|
||||
if (!len) {
|
||||
for (i=0; i<width; i++) {
|
||||
fputs(pad, stdout);
|
||||
}
|
||||
return;
|
||||
}
|
||||
if (len + 1 <= 128) {
|
||||
buf = static_buf;
|
||||
} else {
|
||||
buf = calloc(len+1, sizeof(wchar_t));
|
||||
if (!buf) {
|
||||
/* Uh-oh... cannot recover */
|
||||
fprintf(stderr, "%s\n", ErrMsg[E_NO_MEM]);
|
||||
exit(1);
|
||||
}
|
||||
}
|
||||
(void) mbstowcs(buf, s, len+1);
|
||||
d = (width - len) / 2;
|
||||
ws = buf;
|
||||
for (i=0; i<d; i++) fputs(pad, stdout);
|
||||
for (i=0; i<width; i++) {
|
||||
if (*ws) PutWideChar(*ws++); else break;
|
||||
}
|
||||
for (i=d+len; i<width; i++) fputs(pad, stdout);
|
||||
if (buf != static_buf) free(buf);
|
||||
#endif
|
||||
}
|
||||
|
||||
/***************************************************************/
|
||||
@@ -494,7 +588,7 @@ static int WriteOneCalLine(void)
|
||||
if (CalColumn[i]) {
|
||||
if (WriteOneColLine(i)) done = 0;
|
||||
} else {
|
||||
PrintCentered("", ColSpaces, ' ');
|
||||
PrintCentered("", ColSpaces, " ");
|
||||
}
|
||||
gon();
|
||||
DRAW(tb);
|
||||
@@ -519,74 +613,158 @@ static int WriteOneColLine(int col)
|
||||
CalEntry *e = CalColumn[col];
|
||||
char const *s;
|
||||
char const *space;
|
||||
|
||||
#ifdef REM_USE_WCHAR
|
||||
wchar_t const *ws;
|
||||
wchar_t const *wspace;
|
||||
#endif
|
||||
|
||||
int numwritten = 0;
|
||||
|
||||
/* Print as many characters as possible within the column */
|
||||
space = NULL;
|
||||
s = e->pos;
|
||||
/* Print as many characters as possible within the column */
|
||||
#ifdef REM_USE_WCHAR
|
||||
if (e->wc_text) {
|
||||
wspace = NULL;
|
||||
ws = e->wc_pos;
|
||||
|
||||
/* If we're at the end, and there's another entry, do a blank line and move
|
||||
to next entry. */
|
||||
if (!*s && e->next) {
|
||||
PrintLeft("", ColSpaces, ' ');
|
||||
CalColumn[col] = e->next;
|
||||
free((char *) e->text);
|
||||
free((char *) e->filename);
|
||||
free(e);
|
||||
return 1;
|
||||
}
|
||||
|
||||
/* Find the last space char within the column. */
|
||||
while (s - e->pos <= ColSpaces) {
|
||||
if (!*s) {space = s; break;}
|
||||
if (*s == ' ') space = s;
|
||||
s++;
|
||||
}
|
||||
|
||||
/* Colorize reminder if necessary */
|
||||
if (UseVTColors && e->is_color) {
|
||||
Colorize(e);
|
||||
}
|
||||
|
||||
/* If we couldn't find a space char, print what we have. */
|
||||
if (!space) {
|
||||
for (s = e->pos; s - e->pos < ColSpaces; s++) {
|
||||
if (!*s) break;
|
||||
numwritten++;
|
||||
PutChar(*s);
|
||||
/* If we're at the end, and there's another entry, do a blank
|
||||
line and move to next entry. */
|
||||
if (!*ws && e->next) {
|
||||
PrintLeft("", ColSpaces, ' ');
|
||||
CalColumn[col] = e->next;
|
||||
free((void *)e->text);
|
||||
free((void *)e->filename);
|
||||
if (e->wc_text) free((void *)e->wc_text);
|
||||
free(e);
|
||||
return 1;
|
||||
}
|
||||
e->pos = s;
|
||||
} else {
|
||||
|
||||
/* We found a space - print everything before it. */
|
||||
for (s = e->pos; s<space; s++) {
|
||||
if (!*s) break;
|
||||
numwritten++;
|
||||
PutChar(*s);
|
||||
/* Find the last space char within the column. */
|
||||
while (ws - e->wc_pos <= ColSpaces) {
|
||||
if (!*ws) {wspace = ws; break;}
|
||||
if (iswspace(*ws)) wspace = ws;
|
||||
ws++;
|
||||
}
|
||||
}
|
||||
|
||||
/* Decolorize reminder if necessary */
|
||||
if (UseVTColors && e->is_color) {
|
||||
Decolorize();
|
||||
}
|
||||
/* Colorize reminder if necessary */
|
||||
if (UseVTColors && e->is_color) {
|
||||
Colorize(e);
|
||||
}
|
||||
|
||||
/* Flesh out the rest of the column */
|
||||
while(numwritten++ < ColSpaces) PutChar(' ');
|
||||
/* If we couldn't find a space char, print what we have. */
|
||||
if (!wspace) {
|
||||
for (ws = e->wc_pos; ws - e->wc_pos < ColSpaces; ws++) {
|
||||
if (!*ws) break;
|
||||
numwritten++;
|
||||
PutWideChar(*ws);
|
||||
}
|
||||
e->wc_pos = ws;
|
||||
} else {
|
||||
/* We found a space - print everything before it. */
|
||||
for (ws = e->wc_pos; ws<wspace; ws++) {
|
||||
if (!*ws) break;
|
||||
numwritten++;
|
||||
PutWideChar(*ws);
|
||||
}
|
||||
}
|
||||
|
||||
/* Skip any spaces before next word */
|
||||
while (*s == ' ') s++;
|
||||
/* Decolorize reminder if necessary */
|
||||
if (UseVTColors && e->is_color) {
|
||||
Decolorize();
|
||||
}
|
||||
|
||||
/* If done, free memory if no next entry. */
|
||||
if (!*s && !e->next) {
|
||||
CalColumn[col] = e->next;
|
||||
free((char *) e->text);
|
||||
free((char *) e->filename);
|
||||
free(e);
|
||||
/* Flesh out the rest of the column */
|
||||
while(numwritten++ < ColSpaces) PutChar(' ');
|
||||
|
||||
/* Skip any spaces before next word */
|
||||
while (iswspace(*ws)) ws++;
|
||||
|
||||
/* If done, free memory if no next entry. */
|
||||
if (!*ws && !e->next) {
|
||||
CalColumn[col] = e->next;
|
||||
free((void *)e->text);
|
||||
free((void *)e->filename);
|
||||
if (e->wc_text) free((void *)e->wc_text);
|
||||
free(e);
|
||||
} else {
|
||||
e->wc_pos = ws;
|
||||
}
|
||||
if (CalColumn[col]) return 1; else return 0;
|
||||
} else {
|
||||
e->pos = s;
|
||||
#endif
|
||||
space = NULL;
|
||||
s = e->pos;
|
||||
|
||||
/* If we're at the end, and there's another entry, do a blank
|
||||
line and move to next entry. */
|
||||
if (!*s && e->next) {
|
||||
PrintLeft("", ColSpaces, ' ');
|
||||
CalColumn[col] = e->next;
|
||||
free((void *)e->text);
|
||||
free((void *)e->filename);
|
||||
#ifdef REM_USE_WCHAR
|
||||
if (e->wc_text) free((void *)e->wc_text);
|
||||
#endif
|
||||
free(e);
|
||||
return 1;
|
||||
}
|
||||
|
||||
/* Find the last space char within the column. */
|
||||
while (s - e->pos <= ColSpaces) {
|
||||
if (!*s) {space = s; break;}
|
||||
if (*s == ' ') space = s;
|
||||
s++;
|
||||
}
|
||||
|
||||
/* Colorize reminder if necessary */
|
||||
if (UseVTColors && e->is_color) {
|
||||
Colorize(e);
|
||||
}
|
||||
|
||||
/* If we couldn't find a space char, print what we have. */
|
||||
if (!space) {
|
||||
for (s = e->pos; s - e->pos < ColSpaces; s++) {
|
||||
if (!*s) break;
|
||||
numwritten++;
|
||||
PutChar(*s);
|
||||
}
|
||||
e->pos = s;
|
||||
} else {
|
||||
/* We found a space - print everything before it. */
|
||||
for (s = e->pos; s<space; s++) {
|
||||
if (!*s) break;
|
||||
numwritten++;
|
||||
PutChar(*s);
|
||||
}
|
||||
}
|
||||
|
||||
/* Decolorize reminder if necessary */
|
||||
if (UseVTColors && e->is_color) {
|
||||
Decolorize();
|
||||
}
|
||||
|
||||
/* Flesh out the rest of the column */
|
||||
while(numwritten++ < ColSpaces) PutChar(' ');
|
||||
|
||||
/* Skip any spaces before next word */
|
||||
while (*s == ' ') s++;
|
||||
|
||||
/* If done, free memory if no next entry. */
|
||||
if (!*s && !e->next) {
|
||||
CalColumn[col] = e->next;
|
||||
free((void *)e->text);
|
||||
free((void *)e->filename);
|
||||
#ifdef REM_USE_WCHAR
|
||||
if (e->wc_text) free((void *)e->wc_text);
|
||||
#endif
|
||||
free(e);
|
||||
} else {
|
||||
e->pos = s;
|
||||
}
|
||||
if (CalColumn[col]) return 1; else return 0;
|
||||
#ifdef REM_USE_WCHAR
|
||||
}
|
||||
if (CalColumn[col]) return 1; else return 0;
|
||||
#endif
|
||||
}
|
||||
|
||||
/***************************************************************/
|
||||
@@ -714,7 +892,7 @@ static void WriteCalHeader(void)
|
||||
gon();
|
||||
DRAW(tb);
|
||||
goff();
|
||||
PrintCentered(buf, CalWidth-2, ' ');
|
||||
PrintCentered(buf, CalWidth-2, " ");
|
||||
gon();
|
||||
DRAW(tb);
|
||||
goff();
|
||||
@@ -763,29 +941,52 @@ static int DoCalRem(ParsePtr p, int col)
|
||||
DBufInit(&pre_buf);
|
||||
|
||||
/* Parse the trigger date and time */
|
||||
if ( (r=ParseRem(p, &trig, &tim, 1)) ) return r;
|
||||
if ( (r=ParseRem(p, &trig, &tim, 1)) ) {
|
||||
FreeTrig(&trig);
|
||||
return r;
|
||||
}
|
||||
|
||||
/* Don't include timed reminders in calendar if -a option supplied. */
|
||||
if (DontIssueAts && tim.ttime != NO_TIME) return OK;
|
||||
if (trig.typ == NO_TYPE) return E_EOLN;
|
||||
if (DontIssueAts && tim.ttime != NO_TIME) {
|
||||
FreeTrig(&trig);
|
||||
return OK;
|
||||
}
|
||||
if (trig.typ == NO_TYPE) {
|
||||
FreeTrig(&trig);
|
||||
return E_EOLN;
|
||||
}
|
||||
if (trig.typ == SAT_TYPE) {
|
||||
r=DoSatRemind(&trig, &tim, p);
|
||||
if (r) {
|
||||
FreeTrig(&trig);
|
||||
if (r == E_EXPIRED) return OK;
|
||||
return r;
|
||||
}
|
||||
if (!LastTrigValid) return OK;
|
||||
if (!LastTrigValid) {
|
||||
FreeTrig(&trig);
|
||||
return OK;
|
||||
}
|
||||
r=ParseToken(p, &buf);
|
||||
if (r) return r;
|
||||
if (r) {
|
||||
FreeTrig(&trig);
|
||||
return r;
|
||||
}
|
||||
FindToken(DBufValue(&buf), &tok);
|
||||
DBufFree(&buf);
|
||||
if (tok.type == T_Empty || tok.type == T_Comment) return OK;
|
||||
if (tok.type != T_RemType || tok.val == SAT_TYPE) return E_PARSE_ERR;
|
||||
if (tok.type == T_Empty || tok.type == T_Comment) {
|
||||
FreeTrig(&trig);
|
||||
return OK;
|
||||
}
|
||||
if (tok.type != T_RemType || tok.val == SAT_TYPE) {
|
||||
FreeTrig(&trig);
|
||||
return E_PARSE_ERR;
|
||||
}
|
||||
if (tok.val == PASSTHRU_TYPE) {
|
||||
r=ParseToken(p, &buf);
|
||||
if (r) return r;
|
||||
if (!DBufLen(&buf)) {
|
||||
DBufFree(&buf);
|
||||
FreeTrig(&trig);
|
||||
return E_EOLN;
|
||||
}
|
||||
StrnCpy(trig.passthru, DBufValue(&buf), PASSTHRU_LEN);
|
||||
@@ -793,11 +994,17 @@ static int DoCalRem(ParsePtr p, int col)
|
||||
}
|
||||
trig.typ = tok.val;
|
||||
jul = LastTriggerDate;
|
||||
if (!LastTrigValid) return OK;
|
||||
if (!LastTrigValid) {
|
||||
FreeTrig(&trig);
|
||||
return OK;
|
||||
}
|
||||
} else {
|
||||
/* Calculate the trigger date */
|
||||
jul = ComputeTrigger(trig.scanfrom, &trig, &r, 1);
|
||||
if (r) return r;
|
||||
if (r) {
|
||||
FreeTrig(&trig);
|
||||
return r;
|
||||
}
|
||||
}
|
||||
|
||||
/* Convert PS and PSF to PASSTHRU */
|
||||
@@ -809,39 +1016,51 @@ static int DoCalRem(ParsePtr p, int col)
|
||||
trig.typ = PASSTHRU_TYPE;
|
||||
}
|
||||
if (trig.typ == PASSTHRU_TYPE) {
|
||||
if (!PsCal && strcmp(trig.passthru, "COLOR")) return OK;
|
||||
if (!strcmp(trig.passthru, "COLOR")) {
|
||||
is_color = 1;
|
||||
/* Strip off the three color numbers */
|
||||
DBufFree(&buf);
|
||||
r=ParseToken(p, &buf);
|
||||
DBufPuts(&pre_buf, DBufValue(&buf));
|
||||
DBufPutc(&pre_buf, ' ');
|
||||
DBufFree(&buf);
|
||||
if (r) return r;
|
||||
r=ParseToken(p, &buf);
|
||||
DBufPuts(&pre_buf, DBufValue(&buf));
|
||||
DBufPutc(&pre_buf, ' ');
|
||||
DBufFree(&buf);
|
||||
if (r) return r;
|
||||
r=ParseToken(p, &buf);
|
||||
DBufPuts(&pre_buf, DBufValue(&buf));
|
||||
DBufPutc(&pre_buf, ' ');
|
||||
DBufFree(&buf);
|
||||
if (r) return r;
|
||||
(void) sscanf(DBufValue(&pre_buf), "%d %d %d",
|
||||
&col_r, &col_g, &col_b);
|
||||
if (col_r < 0) col_r = 0;
|
||||
else if (col_r > 255) col_r = 255;
|
||||
if (col_g < 0) col_g = 0;
|
||||
else if (col_g > 255) col_g = 255;
|
||||
if (col_b < 0) col_b = 0;
|
||||
else if (col_b > 255) col_b = 255;
|
||||
|
||||
if (!PsCal && !DoSimpleCalendar) {
|
||||
DBufFree(&pre_buf);
|
||||
}
|
||||
}
|
||||
if (!PsCal && strcmp(trig.passthru, "COLOR") && strcmp(trig.passthru, "COLOUR")) {
|
||||
FreeTrig(&trig);
|
||||
return OK;
|
||||
}
|
||||
if (!strcmp(trig.passthru, "COLOR") ||
|
||||
!strcmp(trig.passthru, "COLOUR")) {
|
||||
is_color = 1;
|
||||
/* Strip off the three color numbers */
|
||||
DBufFree(&buf);
|
||||
r=ParseToken(p, &buf);
|
||||
DBufPuts(&pre_buf, DBufValue(&buf));
|
||||
DBufPutc(&pre_buf, ' ');
|
||||
DBufFree(&buf);
|
||||
if (r) {
|
||||
FreeTrig(&trig);
|
||||
return r;
|
||||
}
|
||||
r=ParseToken(p, &buf);
|
||||
DBufPuts(&pre_buf, DBufValue(&buf));
|
||||
DBufPutc(&pre_buf, ' ');
|
||||
DBufFree(&buf);
|
||||
if (r) {
|
||||
FreeTrig(&trig);
|
||||
return r;
|
||||
}
|
||||
r=ParseToken(p, &buf);
|
||||
DBufPuts(&pre_buf, DBufValue(&buf));
|
||||
DBufPutc(&pre_buf, ' ');
|
||||
DBufFree(&buf);
|
||||
if (r) {
|
||||
FreeTrig(&trig);
|
||||
return r;
|
||||
}
|
||||
(void) sscanf(DBufValue(&pre_buf), "%d %d %d",
|
||||
&col_r, &col_g, &col_b);
|
||||
if (col_r < 0) col_r = 0;
|
||||
else if (col_r > 255) col_r = 255;
|
||||
if (col_g < 0) col_g = 0;
|
||||
else if (col_g > 255) col_g = 255;
|
||||
if (col_b < 0) col_b = 0;
|
||||
else if (col_b > 255) col_b = 255;
|
||||
if (!PsCal && !DoSimpleCalendar) {
|
||||
DBufFree(&pre_buf);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* If trigger date == today, add it to the current entry */
|
||||
@@ -855,16 +1074,19 @@ static int DoCalRem(ParsePtr p, int col)
|
||||
/* Suppress time if it's not today or if it's a non-COLOR special */
|
||||
if (jul != JulianToday ||
|
||||
(trig.typ == PASSTHRU_TYPE &&
|
||||
strcmp(trig.passthru, "COLOUR") &&
|
||||
strcmp(trig.passthru, "COLOR"))) {
|
||||
if (DBufPuts(&obuf, SimpleTime(NO_TIME)) != OK) {
|
||||
DBufFree(&obuf);
|
||||
DBufFree(&pre_buf);
|
||||
FreeTrig(&trig);
|
||||
return E_NO_MEM;
|
||||
}
|
||||
} else {
|
||||
if (DBufPuts(&obuf, CalendarTime(tim.ttime, tim.duration)) != OK) {
|
||||
DBufFree(&obuf);
|
||||
DBufFree(&pre_buf);
|
||||
FreeTrig(&trig);
|
||||
return E_NO_MEM;
|
||||
}
|
||||
}
|
||||
@@ -881,6 +1103,7 @@ static int DoCalRem(ParsePtr p, int col)
|
||||
DestroyValue(v);
|
||||
DBufFree(&obuf);
|
||||
DBufFree(&pre_buf);
|
||||
FreeTrig(&trig);
|
||||
return E_NO_MEM;
|
||||
}
|
||||
}
|
||||
@@ -899,11 +1122,13 @@ static int DoCalRem(ParsePtr p, int col)
|
||||
if (r) {
|
||||
DBufFree(&pre_buf);
|
||||
DBufFree(&obuf);
|
||||
FreeTrig(&trig);
|
||||
return r;
|
||||
}
|
||||
if (DBufLen(&obuf) <= oldLen) {
|
||||
DBufFree(&obuf);
|
||||
DBufFree(&pre_buf);
|
||||
FreeTrig(&trig);
|
||||
return OK;
|
||||
}
|
||||
if (trig.typ != PASSTHRU_TYPE &&
|
||||
@@ -918,6 +1143,7 @@ static int DoCalRem(ParsePtr p, int col)
|
||||
DestroyValue(v);
|
||||
DBufFree(&obuf);
|
||||
DBufFree(&pre_buf);
|
||||
FreeTrig(&trig);
|
||||
return E_NO_MEM;
|
||||
}
|
||||
}
|
||||
@@ -929,30 +1155,37 @@ static int DoCalRem(ParsePtr p, int col)
|
||||
DBufPuts(&pre_buf, s);
|
||||
s = DBufValue(&pre_buf);
|
||||
e = NEW(CalEntry);
|
||||
if (!e) {
|
||||
DBufFree(&obuf);
|
||||
DBufFree(&pre_buf);
|
||||
FreeTrig(&trig);
|
||||
return E_NO_MEM;
|
||||
}
|
||||
#ifdef REM_USE_WCHAR
|
||||
e->wc_pos = NULL;
|
||||
e->wc_text = NULL;
|
||||
#endif
|
||||
e->is_color = is_color;
|
||||
e->r = col_r;
|
||||
e->g = col_g;
|
||||
e->b = col_b;
|
||||
if (!e) {
|
||||
DBufFree(&obuf);
|
||||
DBufFree(&pre_buf);
|
||||
return E_NO_MEM;
|
||||
}
|
||||
e->text = StrDup(s);
|
||||
DBufFree(&obuf);
|
||||
DBufFree(&pre_buf);
|
||||
if (!e->text) {
|
||||
free(e);
|
||||
FreeTrig(&trig);
|
||||
return E_NO_MEM;
|
||||
}
|
||||
StrnCpy(e->tag, trig.tag, TAG_LEN);
|
||||
if (!e->tag[0]) {
|
||||
if (SynthesizeTags) {
|
||||
SynthesizeTag(e->tag);
|
||||
} else {
|
||||
strcpy(e->tag, "*");
|
||||
}
|
||||
make_wchar_versions(e);
|
||||
DBufInit(&(e->tags));
|
||||
DBufPuts(&(e->tags), DBufValue(&(trig.tags)));
|
||||
if (SynthesizeTags) {
|
||||
AppendTag(&(e->tags), SynthesizeTag());
|
||||
}
|
||||
|
||||
/* Don't need tags any more */
|
||||
FreeTrig(&trig);
|
||||
e->duration = tim.duration;
|
||||
e->priority = trig.priority;
|
||||
e->filename = StrDup(FileName);
|
||||
@@ -1002,7 +1235,11 @@ static void WriteSimpleEntries(int col, int jul)
|
||||
} else {
|
||||
printf(" *");
|
||||
}
|
||||
printf(" %s ", e->tag);
|
||||
if (*DBufValue(&(e->tags))) {
|
||||
printf(" %s ", DBufValue(&(e->tags)));
|
||||
} else {
|
||||
printf(" * ");
|
||||
}
|
||||
if (e->duration != NO_TIME) {
|
||||
printf("%d ", e->duration);
|
||||
} else {
|
||||
@@ -1014,8 +1251,11 @@ static void WriteSimpleEntries(int col, int jul)
|
||||
printf("* ");
|
||||
}
|
||||
printf("%s\n", e->text);
|
||||
free((char *) e->text);
|
||||
free((char *) e->filename);
|
||||
free((void *)e->text);
|
||||
free((void *)e->filename);
|
||||
#ifdef REM_USE_WCHAR
|
||||
if (e->wc_text) free((void *)e->wc_text);
|
||||
#endif
|
||||
n = e->next;
|
||||
free(e);
|
||||
e = n;
|
||||
@@ -1115,9 +1355,9 @@ static void WriteCalDays(void)
|
||||
goff();
|
||||
for (i=0; i<7; i++) {
|
||||
if (!MondayFirst)
|
||||
PrintCentered(DayName[(i+6)%7], ColSpaces, ' ');
|
||||
PrintCentered(DayName[(i+6)%7], ColSpaces, " ");
|
||||
else
|
||||
PrintCentered(DayName[i%7], ColSpaces, ' ');
|
||||
PrintCentered(DayName[i%7], ColSpaces, " ");
|
||||
gon();
|
||||
DRAW(tb);
|
||||
goff();
|
||||
@@ -1285,10 +1525,11 @@ static void SortCol(CalEntry **col)
|
||||
}
|
||||
}
|
||||
|
||||
void SynthesizeTag(char *out)
|
||||
char const *SynthesizeTag(void)
|
||||
{
|
||||
struct MD5Context ctx;
|
||||
unsigned char buf[16];
|
||||
static char out[128];
|
||||
MD5Init(&ctx);
|
||||
MD5Update(&ctx, (unsigned char *) CurLine, strlen(CurLine));
|
||||
MD5Final(buf, &ctx);
|
||||
@@ -1301,5 +1542,6 @@ void SynthesizeTag(char *out)
|
||||
(unsigned int) buf[10], (unsigned int) buf[11],
|
||||
(unsigned int) buf[12], (unsigned int) buf[13],
|
||||
(unsigned int) buf[14], (unsigned int) buf[15]);
|
||||
return out;
|
||||
}
|
||||
|
||||
|
||||
@@ -13,12 +13,20 @@
|
||||
/* Define if you have the <glob.h> header file */
|
||||
#undef HAVE_GLOB_H
|
||||
|
||||
#undef HAVE_WCTYPE_H
|
||||
|
||||
#undef HAVE_LOCALE_H
|
||||
|
||||
#undef HAVE_GLOB
|
||||
|
||||
#undef HAVE_SETENV
|
||||
|
||||
#undef HAVE_UNSETENV
|
||||
|
||||
#undef HAVE_MBSTOWCS
|
||||
|
||||
#undef HAVE_SETLOCALE
|
||||
|
||||
/* The number of bytes in a unsigned int. */
|
||||
#undef SIZEOF_UNSIGNED_INT
|
||||
|
||||
|
||||
10
src/custom.h
10
src/custom.h
@@ -183,12 +183,12 @@
|
||||
/*---------------------------------------------------------------------*/
|
||||
/* How many global omits of the form YYYY MM DD do we handle? */
|
||||
/*---------------------------------------------------------------------*/
|
||||
#define MAX_FULL_OMITS 250
|
||||
#define MAX_FULL_OMITS 500
|
||||
|
||||
/*---------------------------------------------------------------------*/
|
||||
/* How many global omits of the form MM DD do we handle? */
|
||||
/*---------------------------------------------------------------------*/
|
||||
#define MAX_PARTIAL_OMITS 250
|
||||
#define MAX_PARTIAL_OMITS 366
|
||||
|
||||
/*---------------------------------------------------------------------*/
|
||||
/* A newline - some systems need "\n\r" */
|
||||
@@ -221,3 +221,9 @@
|
||||
#define Putc putc
|
||||
#define PutChar putchar
|
||||
#endif
|
||||
|
||||
#if defined(HAVE_MBSTOWCS) && defined(HAVE_WCTYPE_H)
|
||||
#define REM_USE_WCHAR 1
|
||||
#else
|
||||
#undef REM_USE_WCHAR
|
||||
#endif
|
||||
|
||||
@@ -183,12 +183,12 @@
|
||||
/*---------------------------------------------------------------------*/
|
||||
/* How many global omits of the form YYYY MM DD do we handle? */
|
||||
/*---------------------------------------------------------------------*/
|
||||
#define MAX_FULL_OMITS 250
|
||||
#define MAX_FULL_OMITS 500
|
||||
|
||||
/*---------------------------------------------------------------------*/
|
||||
/* How many global omits of the form MM DD do we handle? */
|
||||
/*---------------------------------------------------------------------*/
|
||||
#define MAX_PARTIAL_OMITS 250
|
||||
#define MAX_PARTIAL_OMITS 366
|
||||
|
||||
/*---------------------------------------------------------------------*/
|
||||
/* A newline - some systems need "\n\r" */
|
||||
@@ -221,3 +221,9 @@
|
||||
#define Putc putc
|
||||
#define PutChar putchar
|
||||
#endif
|
||||
|
||||
#if defined(HAVE_MBSTOWCS) && defined(HAVE_WCTYPE_H)
|
||||
#define REM_USE_WCHAR 1
|
||||
#else
|
||||
#undef REM_USE_WCHAR
|
||||
#endif
|
||||
|
||||
88
src/dorem.c
88
src/dorem.c
@@ -56,10 +56,14 @@ int DoRem(ParsePtr p)
|
||||
DBufInit(&buf);
|
||||
|
||||
/* Parse the trigger date and time */
|
||||
if ( (r=ParseRem(p, &trig, &tim, 1)) ) return r;
|
||||
if ( (r=ParseRem(p, &trig, &tim, 1)) ) {
|
||||
FreeTrig(&trig);
|
||||
return r;
|
||||
}
|
||||
|
||||
if (trig.typ == NO_TYPE) {
|
||||
PurgeEchoLine("%s\n%s\n", "#!P! Cannot parse next line", CurLine);
|
||||
FreeTrig(&trig);
|
||||
return E_EOLN;
|
||||
}
|
||||
if (trig.typ == SAT_TYPE) {
|
||||
@@ -67,26 +71,39 @@ int DoRem(ParsePtr p)
|
||||
PurgeEchoLine("%s\n", CurLine);
|
||||
r=DoSatRemind(&trig, &tim, p);
|
||||
if (r) {
|
||||
FreeTrig(&trig);
|
||||
if (r == E_EXPIRED) return OK;
|
||||
return r;
|
||||
}
|
||||
if (!LastTrigValid) return OK;
|
||||
if (!LastTrigValid) {
|
||||
FreeTrig(&trig);
|
||||
return OK;
|
||||
}
|
||||
r=ParseToken(p, &buf);
|
||||
if (r) return r;
|
||||
if (r) {
|
||||
FreeTrig(&trig);
|
||||
return r;
|
||||
}
|
||||
FindToken(DBufValue(&buf), &tok);
|
||||
DBufFree(&buf);
|
||||
if (tok.type == T_Empty || tok.type == T_Comment) {
|
||||
DBufFree(&buf);
|
||||
FreeTrig(&trig);
|
||||
return OK;
|
||||
}
|
||||
if (tok.type != T_RemType || tok.val == SAT_TYPE) {
|
||||
DBufFree(&buf);
|
||||
FreeTrig(&trig);
|
||||
return E_PARSE_ERR;
|
||||
}
|
||||
if (tok.val == PASSTHRU_TYPE) {
|
||||
r=ParseToken(p, &buf);
|
||||
if (r) return r;
|
||||
if (r) {
|
||||
FreeTrig(&trig);
|
||||
return r;
|
||||
}
|
||||
if (!DBufLen(&buf)) {
|
||||
FreeTrig(&trig);
|
||||
DBufFree(&buf);
|
||||
return E_EOLN;
|
||||
}
|
||||
@@ -95,8 +112,10 @@ int DoRem(ParsePtr p)
|
||||
}
|
||||
trig.typ = tok.val;
|
||||
jul = LastTriggerDate;
|
||||
if (!LastTrigValid) return OK;
|
||||
if (PurgeMode) return OK;
|
||||
if (!LastTrigValid || PurgeMode) {
|
||||
FreeTrig(&trig);
|
||||
return OK;
|
||||
}
|
||||
} else {
|
||||
/* Calculate the trigger date */
|
||||
jul = ComputeTrigger(trig.scanfrom, &trig, &r, 1);
|
||||
@@ -105,6 +124,7 @@ int DoRem(ParsePtr p)
|
||||
PurgeEchoLine("%s: %s\n", "#!P! Problem calculating trigger date", ErrMsg[r]);
|
||||
PurgeEchoLine("%s\n", CurLine);
|
||||
}
|
||||
FreeTrig(&trig);
|
||||
return r;
|
||||
}
|
||||
}
|
||||
@@ -125,6 +145,7 @@ int DoRem(ParsePtr p)
|
||||
} else {
|
||||
PurgeEchoLine("%s\n", CurLine);
|
||||
}
|
||||
FreeTrig(&trig);
|
||||
return OK;
|
||||
}
|
||||
/* Queue the reminder, if necessary */
|
||||
@@ -134,17 +155,21 @@ int DoRem(ParsePtr p)
|
||||
FileAccessDate == JulianToday))
|
||||
QueueReminder(p, &trig, &tim, trig.sched);
|
||||
/* If we're in daemon mode, do nothing over here */
|
||||
if (Daemon) return OK;
|
||||
|
||||
if (ShouldTriggerReminder(&trig, &tim, jul, &err)) {
|
||||
if ( (r=TriggerReminder(p, &trig, &tim, jul)) )
|
||||
{
|
||||
return r;
|
||||
}
|
||||
if (Daemon) {
|
||||
FreeTrig(&trig);
|
||||
return OK;
|
||||
}
|
||||
|
||||
if (ShouldTriggerReminder(&trig, &tim, jul, &err)) {
|
||||
if ( (r=TriggerReminder(p, &trig, &tim, jul)) ) {
|
||||
FreeTrig(&trig);
|
||||
return r;
|
||||
}
|
||||
}
|
||||
|
||||
FreeTrig(&trig);
|
||||
return OK;
|
||||
}
|
||||
}
|
||||
|
||||
/***************************************************************/
|
||||
/* */
|
||||
@@ -159,7 +184,6 @@ int ParseRem(ParsePtr s, Trigger *trig, TimeTrig *tim, int save_in_globals)
|
||||
register int r;
|
||||
DynamicBuffer buf;
|
||||
Token tok;
|
||||
|
||||
int y, m, d;
|
||||
|
||||
DBufInit(&buf);
|
||||
@@ -181,7 +205,7 @@ int ParseRem(ParsePtr s, Trigger *trig, TimeTrig *tim, int save_in_globals)
|
||||
trig->sched[0] = 0;
|
||||
trig->warn[0] = 0;
|
||||
trig->omitfunc[0] = 0;
|
||||
trig->tag[0] = 0;
|
||||
DBufInit(&(trig->tags));
|
||||
trig->passthru[0] = 0;
|
||||
tim->ttime = NO_TIME;
|
||||
tim->delta = NO_DELTA;
|
||||
@@ -277,6 +301,14 @@ int ParseRem(ParsePtr s, Trigger *trig, TimeTrig *tim, int save_in_globals)
|
||||
}
|
||||
return OK;
|
||||
|
||||
case T_Through:
|
||||
DBufFree(&buf);
|
||||
if (trig->rep != NO_REP) return E_REP_TWICE;
|
||||
trig->rep = 1;
|
||||
r = ParseUntil(s, trig);
|
||||
if (r) return r;
|
||||
break;
|
||||
|
||||
case T_Until:
|
||||
DBufFree(&buf);
|
||||
r=ParseUntil(s, trig);
|
||||
@@ -354,7 +386,7 @@ int ParseRem(ParsePtr s, Trigger *trig, TimeTrig *tim, int save_in_globals)
|
||||
case T_Tag:
|
||||
r = ParseToken(s, &buf);
|
||||
if (r) return r;
|
||||
StrnCpy(trig->tag, DBufValue(&buf), TAG_LEN);
|
||||
AppendTag(&(trig->tags), DBufValue(&buf));
|
||||
break;
|
||||
|
||||
case T_Duration:
|
||||
@@ -676,14 +708,14 @@ int TriggerReminder(ParsePtr p, Trigger *t, TimeTrig *tim, int jul)
|
||||
DBufInit(&calRow);
|
||||
DBufInit(&pre_buf);
|
||||
if (t->typ == RUN_TYPE && RunDisabled) return E_RUN_DISABLED;
|
||||
if ((t->typ == PASSTHRU_TYPE && strcmp(t->passthru, "COLOR")) ||
|
||||
if ((t->typ == PASSTHRU_TYPE && strcmp(t->passthru, "COLOR") && strcmp(t->passthru, "COLOUR")) ||
|
||||
t->typ == CAL_TYPE ||
|
||||
t->typ == PS_TYPE ||
|
||||
t->typ == PSF_TYPE)
|
||||
return OK;
|
||||
|
||||
/* Handle COLOR types */
|
||||
if (t->typ == PASSTHRU_TYPE && !strcmp(t->passthru, "COLOR")) {
|
||||
if (t->typ == PASSTHRU_TYPE && (!strcmp(t->passthru, "COLOR") || !strcmp(t->passthru, "COLOUR"))) {
|
||||
/* Strip off three tokens */
|
||||
r = ParseToken(p, &buf);
|
||||
if (!NextMode) {
|
||||
@@ -743,16 +775,12 @@ int TriggerReminder(ParsePtr p, Trigger *t, TimeTrig *tim, int jul)
|
||||
DBufFree(&pre_buf);
|
||||
return E_NO_MEM;
|
||||
}
|
||||
if (t->tag[0]) {
|
||||
sprintf(tmpBuf, "%s ", t->tag);
|
||||
} else {
|
||||
sprintf(tmpBuf, "* ");
|
||||
}
|
||||
if (DBufPuts(&calRow, tmpBuf) != OK) {
|
||||
DBufFree(&calRow);
|
||||
DBufFree(&pre_buf);
|
||||
return E_NO_MEM;
|
||||
}
|
||||
if (*DBufValue(&(t->tags))) {
|
||||
DBufPuts(&calRow, DBufValue(&(t->tags)));
|
||||
DBufPutc(&calRow, ' ');
|
||||
} else {
|
||||
DBufPuts(&calRow, "* ");
|
||||
}
|
||||
if (tim->duration != NO_TIME) {
|
||||
sprintf(tmpBuf, "%d ", tim->duration);
|
||||
} else {
|
||||
@@ -923,9 +951,9 @@ int ShouldTriggerReminder(Trigger *t, TimeTrig *tim, int jul, int *err)
|
||||
if (t->delta < 0)
|
||||
jul = jul + t->delta;
|
||||
else {
|
||||
r = t->delta;
|
||||
int iter = 0;
|
||||
int max = MaxSatIter;
|
||||
r = t->delta;
|
||||
if (max < r*2) max = r*2;
|
||||
while(iter++ < max) {
|
||||
if (!r || (jul <= JulianToday)) {
|
||||
|
||||
@@ -205,7 +205,7 @@ EXTERN char *ErrMsg[]
|
||||
"Back value specified twice",
|
||||
"ONCE keyword used twice. (Hah.)",
|
||||
"Expecting time after AT",
|
||||
"UNTIL keyword used twice",
|
||||
"THROUGH/UNTIL keyword used twice",
|
||||
"Incomplete date specification",
|
||||
"FROM/SCANFROM keyword used twice",
|
||||
"Variable",
|
||||
|
||||
11
src/funcs.c
11
src/funcs.c
@@ -1335,10 +1335,11 @@ static int FShell(func_info *info)
|
||||
/***************************************************************/
|
||||
static int FIsomitted(func_info *info)
|
||||
{
|
||||
int r;
|
||||
if (!HASDATE(ARG(0))) return E_BAD_TYPE;
|
||||
|
||||
RetVal.type = INT_TYPE;
|
||||
int r = IsOmitted(DATEPART(ARG(0)), 0, NULL, &RETVAL);
|
||||
r = IsOmitted(DATEPART(ARG(0)), 0, NULL, &RETVAL);
|
||||
return r;
|
||||
}
|
||||
|
||||
@@ -1896,7 +1897,7 @@ static int SunStuff(int rise, double cosz, int jul)
|
||||
if (dusk_or_dawn == 2) {/* dusk */
|
||||
L += 6;
|
||||
} else if (dusk_or_dawn == 3) {/* dawn */
|
||||
L -= 14;
|
||||
L -= 6;
|
||||
}
|
||||
if (L > 360.0) L -= 360.0;
|
||||
|
||||
@@ -2659,7 +2660,10 @@ FEvalTrig(func_info *info)
|
||||
p.allownested = 0;
|
||||
r = ParseRem(&p, &trig, &tim, 0);
|
||||
if (r) return r;
|
||||
if (trig.typ != NO_TYPE) return E_PARSE_ERR;
|
||||
if (trig.typ != NO_TYPE) {
|
||||
FreeTrig(&trig);
|
||||
return E_PARSE_ERR;
|
||||
}
|
||||
if (scanfrom == NO_DATE) {
|
||||
jul = ComputeTrigger(trig.scanfrom, &trig, &r, 0);
|
||||
} else {
|
||||
@@ -2669,6 +2673,7 @@ FEvalTrig(func_info *info)
|
||||
}
|
||||
jul = ComputeTrigger(scanfrom, &trig, &r, 0);
|
||||
}
|
||||
FreeTrig(&trig);
|
||||
if (r) return r;
|
||||
if (jul < 0) {
|
||||
RetVal.type = INT_TYPE;
|
||||
|
||||
@@ -96,6 +96,7 @@ EXTERN char const **ArgV;
|
||||
EXTERN INIT( int CalLines, CAL_LINES);
|
||||
EXTERN INIT( int CalPad, 1);
|
||||
EXTERN INIT( int UseVTChars, 0);
|
||||
EXTERN INIT( int UseUTF8Chars, 0);
|
||||
EXTERN INIT( int UseVTColors, 0);
|
||||
|
||||
/* Latitude and longitude */
|
||||
|
||||
26
src/init.c
26
src/init.c
@@ -8,7 +8,7 @@
|
||||
/* */
|
||||
/* This file is part of REMIND. */
|
||||
/* Copyright (C) 1992-1998 by David F. Skoll */
|
||||
/* Copyright (C) 1999-2010 by Roaring Penguin Software Inc. */
|
||||
/* Copyright (C) 1999-2011 by Roaring Penguin Software Inc. */
|
||||
/* */
|
||||
/***************************************************************/
|
||||
|
||||
@@ -137,7 +137,7 @@ void InitRemind(int argc, char const *argv[])
|
||||
char const *s;
|
||||
int weeks;
|
||||
|
||||
int jul, tim;
|
||||
int jul;
|
||||
|
||||
#if defined(__APPLE__)
|
||||
rkrphgvba(0);
|
||||
@@ -146,7 +146,6 @@ void InitRemind(int argc, char const *argv[])
|
||||
#endif
|
||||
|
||||
jul = NO_DATE;
|
||||
tim = NO_TIME;
|
||||
|
||||
/* Initialize global dynamic buffers */
|
||||
DBufInit(&Banner);
|
||||
@@ -352,6 +351,11 @@ void InitRemind(int argc, char const *argv[])
|
||||
arg++;
|
||||
continue;
|
||||
}
|
||||
if (*arg == 'u' || *arg == 'U') {
|
||||
UseUTF8Chars = 1;
|
||||
arg++;
|
||||
continue;
|
||||
}
|
||||
if (*arg == 'c' || *arg == 'C') {
|
||||
UseVTColors = 1;
|
||||
arg++;
|
||||
@@ -565,12 +569,12 @@ void InitRemind(int argc, char const *argv[])
|
||||
}
|
||||
if (d == NO_DAY) d=1;
|
||||
if (d > DaysInMonth(m, y)) {
|
||||
fprintf(ErrFp, BadDate);
|
||||
fprintf(ErrFp, "%s", BadDate);
|
||||
Usage();
|
||||
}
|
||||
JulianToday = Julian(y, m, d);
|
||||
if (JulianToday == -1) {
|
||||
fprintf(ErrFp, BadDate);
|
||||
fprintf(ErrFp, "%s", BadDate);
|
||||
Usage();
|
||||
}
|
||||
CurYear = y;
|
||||
@@ -597,7 +601,7 @@ void InitRemind(int argc, char const *argv[])
|
||||
void Usage(void)
|
||||
{
|
||||
fprintf(ErrFp, "\nREMIND %s (%s version) Copyright 1992-1998 David F. Skoll\n", VERSION, L_LANGNAME);
|
||||
fprintf(ErrFp, "Copyright 1999-2010 Roaring Penguin Software Inc.\n");
|
||||
fprintf(ErrFp, "Copyright 1999-2011 Roaring Penguin Software Inc.\n");
|
||||
#ifdef BETA
|
||||
fprintf(ErrFp, ">>>> BETA VERSION <<<<\n");
|
||||
#endif
|
||||
@@ -673,7 +677,7 @@ static void ChgUser(char const *user)
|
||||
|
||||
home = malloc(strlen(pwent->pw_dir) + 6);
|
||||
if (!home) {
|
||||
fprintf(ErrFp, ErrMsg[M_NOMEM_ENV]);
|
||||
fprintf(ErrFp, "%s", ErrMsg[M_NOMEM_ENV]);
|
||||
exit(1);
|
||||
}
|
||||
sprintf(home, "HOME=%s", pwent->pw_dir);
|
||||
@@ -681,7 +685,7 @@ static void ChgUser(char const *user)
|
||||
|
||||
shell = malloc(strlen(pwent->pw_shell) + 7);
|
||||
if (!shell) {
|
||||
fprintf(ErrFp, ErrMsg[M_NOMEM_ENV]);
|
||||
fprintf(ErrFp, "%s", ErrMsg[M_NOMEM_ENV]);
|
||||
exit(1);
|
||||
}
|
||||
sprintf(shell, "SHELL=%s", pwent->pw_shell);
|
||||
@@ -690,14 +694,14 @@ static void ChgUser(char const *user)
|
||||
if (pwent->pw_uid) {
|
||||
username = malloc(strlen(pwent->pw_name) + 6);
|
||||
if (!username) {
|
||||
fprintf(ErrFp, ErrMsg[M_NOMEM_ENV]);
|
||||
fprintf(ErrFp, "%s", ErrMsg[M_NOMEM_ENV]);
|
||||
exit(1);
|
||||
}
|
||||
sprintf(username, "USER=%s", pwent->pw_name);
|
||||
putenv(username);
|
||||
logname= malloc(strlen(pwent->pw_name) + 9);
|
||||
if (!logname) {
|
||||
fprintf(ErrFp, ErrMsg[M_NOMEM_ENV]);
|
||||
fprintf(ErrFp, "%s", ErrMsg[M_NOMEM_ENV]);
|
||||
exit(1);
|
||||
}
|
||||
sprintf(logname, "LOGNAME=%s", pwent->pw_name);
|
||||
@@ -785,6 +789,7 @@ 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,
|
||||
@@ -815,7 +820,6 @@ static char const pmsg2[] = {
|
||||
0x67, 0x6e, 0x65, 0x76, 0x79, 0x6c, 0x2e, 0x0a, 0x00
|
||||
};
|
||||
|
||||
#if defined(__APPLE__) || defined(__CYGWIN__)
|
||||
static void
|
||||
rkrphgvba(int x)
|
||||
{
|
||||
|
||||
@@ -280,7 +280,7 @@ EXTERN char *ErrMsg[] =
|
||||
"Peruutusarvo annettu kahdesti",
|
||||
"ONCE-avainsanaa k\xE4ytetty kahdesti. (Hah.)",
|
||||
"AT-sanan per\xE4st\xE4 puuttuu aika",
|
||||
"UNTIL-sanaa k\xE4ytetty kahdesti",
|
||||
"THROUGH/UNTIL-sanaa k\xE4ytetty kahdesti",
|
||||
"Ep\xE4t\xE4ydellinen p\xE4iv\xE4ys",
|
||||
"FROM/SCANFROM-sanaa k\xE4ytetty kahdesti",
|
||||
"Muuttuja",
|
||||
@@ -384,7 +384,7 @@ EXTERN char *ErrMsg[] =
|
||||
"Peruutusarvo annettu kahdesti",
|
||||
"ONCE-avainsanaa k\x84ytetty kahdesti. (Hah.)",
|
||||
"AT-sanan per\x84st\x84 puuttuu aika",
|
||||
"UNTIL-sanaa k\x84ytetty kahdesti",
|
||||
"THROUGH/UNTIL-sanaa k\x84ytetty kahdesti",
|
||||
"Ep\x84t\x84ydellinen p\x84iv\x84ys",
|
||||
"FROM/SCANFROM-sanaa k\x84ytetty kahdesti",
|
||||
"Muuttuja",
|
||||
@@ -488,7 +488,7 @@ EXTERN char *ErrMsg[] =
|
||||
"Peruutusarvo annettu kahdesti",
|
||||
"ONCE-avainsanaa k{ytetty kahdesti. (Hah.)",
|
||||
"AT-sanan per{st{ puuttuu aika",
|
||||
"UNTIL-sanaa k{ytetty kahdesti",
|
||||
"THROUGH/UNTIL-sanaa k{ytetty kahdesti",
|
||||
"Ep{t{ydellinen p{iv{ys",
|
||||
"FROM/SCANFROM-sanaa k{ytetty kahdesti",
|
||||
"Muuttuja",
|
||||
|
||||
@@ -217,7 +217,7 @@ EXTERN char *ErrMsg[] =
|
||||
"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 UNTIL utilis\351 deux fois",
|
||||
"Mot-cl\351 THROUGH/UNTIL utilis\351 deux fois",
|
||||
"Sp\351cification de date incompl\350te",
|
||||
"Mot-cl\351 FROM/SCANFROM utilis\351 deux fois",
|
||||
"Variable",
|
||||
@@ -321,7 +321,7 @@ EXTERN char *ErrMsg[] =
|
||||
"Valeur de retour specifiee deux fois",
|
||||
"Mot-cle ONCE utilise deux fois. (Hah.)",
|
||||
"Heure attendue apres AT",
|
||||
"Mot-cle UNTIL utilise deux fois",
|
||||
"Mot-cle THROUGH/UNTIL utilise deux fois",
|
||||
"Specification de date incomplete",
|
||||
"Mot-cle FROM/SCANFROM utilise deux fois",
|
||||
"Variable",
|
||||
|
||||
@@ -252,7 +252,7 @@ EXTERN char *ErrMsg[] =
|
||||
"Warto\266\346 cofni\352cia podana dw\363krotnie",
|
||||
"S\263owo ONCE u\277yte dw\363krotnie.",
|
||||
"Po AT oczekiwany jest czas",
|
||||
"S\263owo UNTIL u\277yte dw\363krotnie",
|
||||
"S\263owo THROUGH/UNTIL u\277yte dw\363krotnie",
|
||||
"Niekompletna specyfikacja daty",
|
||||
"S\263owo FROM/SCANFROM u\277yte dw\363krotnie",
|
||||
"Zmienna",
|
||||
@@ -355,7 +355,7 @@ EXTERN char *ErrMsg[] =
|
||||
"Wartosc cofniecia podana dwokrotnie",
|
||||
"Slowo ONCE uzyte dwokrotnie.",
|
||||
"Po AT oczekiwany jest czas",
|
||||
"Slowo UNTIL uzyte dwokrotnie",
|
||||
"Slowo THROUGH/UNTIL uzyte dwokrotnie",
|
||||
"Niekompletna specyfikacja daty",
|
||||
"Slowo FROM/SCANFROM uzyte dwokrotnie",
|
||||
"Zmienna",
|
||||
|
||||
@@ -218,7 +218,7 @@ EXTERN char *ErrMsg[] =
|
||||
"Valor de Back especificado duas vezes",
|
||||
"ONCE usado duas vezes (Eheheh)",
|
||||
"Esperando hora apos AT",
|
||||
"Keyword UNTIL usada duas vezes",
|
||||
"Keyword THROUGH/UNTIL usada duas vezes",
|
||||
"Especificacao de data incompleta",
|
||||
"Keyword FROM/SCANFROM usada duas vezes",
|
||||
"Variavel",
|
||||
|
||||
25
src/main.c
25
src/main.c
@@ -7,7 +7,7 @@
|
||||
/* */
|
||||
/* This file is part of REMIND. */
|
||||
/* Copyright (C) 1992-1998 by David F. Skoll */
|
||||
/* Copyright (C) 1999-2010 by Roaring Penguin Software Inc. */
|
||||
/* Copyright (C) 1999-2011 by Roaring Penguin Software Inc. */
|
||||
/* */
|
||||
/***************************************************************/
|
||||
|
||||
@@ -19,6 +19,9 @@
|
||||
#include <signal.h>
|
||||
#include <string.h>
|
||||
#include <stdarg.h>
|
||||
#ifdef HAVE_LOCALE_H
|
||||
#include <locale.h>
|
||||
#endif
|
||||
|
||||
#include <ctype.h>
|
||||
#ifdef TIME_WITH_SYS_TIME
|
||||
@@ -57,6 +60,10 @@ int main(int argc, char *argv[])
|
||||
{
|
||||
int pid;
|
||||
|
||||
#ifdef HAVE_SETLOCALE
|
||||
setlocale(LC_ALL, "");
|
||||
#endif
|
||||
|
||||
/* The very first thing to do is to set up ErrFp to be stderr */
|
||||
ErrFp = stderr;
|
||||
|
||||
@@ -806,6 +813,7 @@ int DoIfTrig(ParsePtr p)
|
||||
}
|
||||
}
|
||||
}
|
||||
FreeTrig(&trig);
|
||||
}
|
||||
NumIfs++;
|
||||
IfFlags &= ~(IF_MASK << (2*NumIfs - 2));
|
||||
@@ -1299,3 +1307,18 @@ void SigIntHandler(int d)
|
||||
GotSigInt();
|
||||
exit(0);
|
||||
}
|
||||
|
||||
void
|
||||
AppendTag(DynamicBuffer *buf, char const *s)
|
||||
{
|
||||
if (*(DBufValue(buf))) {
|
||||
DBufPutc(buf, ',');
|
||||
}
|
||||
DBufPuts(buf, s);
|
||||
}
|
||||
|
||||
void
|
||||
FreeTrig(Trigger *t)
|
||||
{
|
||||
DBufFree(&(t->tags));
|
||||
}
|
||||
|
||||
138
src/omit.c
138
src/omit.c
@@ -125,7 +125,7 @@ int PushOmitContext(ParsePtr p)
|
||||
free(context);
|
||||
return E_NO_MEM;
|
||||
}
|
||||
|
||||
|
||||
/* Copy the context over */
|
||||
for (i=0; i<NumFullOmits; i++)
|
||||
*(context->fullsave + i) = FullOmitArray[i];
|
||||
@@ -272,6 +272,9 @@ static void InsertIntoSortedArray(int *array, int num, int key)
|
||||
*cur = key;
|
||||
}
|
||||
|
||||
static int DoThroughOmit(ParsePtr p, int y, int m, int d);
|
||||
static void DumpOmits(void);
|
||||
|
||||
/***************************************************************/
|
||||
/* */
|
||||
/* DoOmit */
|
||||
@@ -285,15 +288,25 @@ int DoOmit(ParsePtr p)
|
||||
Token tok;
|
||||
int parsing=1;
|
||||
int syndrome;
|
||||
int not_first_token = -1;
|
||||
|
||||
DynamicBuffer buf;
|
||||
DBufInit(&buf);
|
||||
|
||||
/* Parse the OMIT. We need a month and day; year is optional. */
|
||||
while(parsing) {
|
||||
not_first_token++;
|
||||
if ( (r=ParseToken(p, &buf)) ) return r;
|
||||
FindToken(DBufValue(&buf), &tok);
|
||||
switch (tok.type) {
|
||||
case T_Dumpvars:
|
||||
if (not_first_token) return E_PARSE_ERR;
|
||||
DBufFree(&buf);
|
||||
r = VerifyEoln(p);
|
||||
if (r != OK) return r;
|
||||
DumpOmits();
|
||||
return OK;
|
||||
|
||||
case T_Date:
|
||||
DBufFree(&buf);
|
||||
if (y != NO_YR) return E_YR_TWICE;
|
||||
@@ -324,6 +337,11 @@ int DoOmit(ParsePtr p)
|
||||
DBufFree(&buf);
|
||||
break;
|
||||
|
||||
case T_Through:
|
||||
DBufFree(&buf);
|
||||
if (y == NO_YR || m == NO_MON || d == NO_DAY) return E_INCOMPLETE;
|
||||
return DoThroughOmit(p, y, m, d);
|
||||
|
||||
case T_Empty:
|
||||
case T_Comment:
|
||||
case T_RemType:
|
||||
@@ -362,7 +380,123 @@ int DoOmit(ParsePtr p)
|
||||
NumFullOmits++;
|
||||
}
|
||||
}
|
||||
if (tok.type == T_RemType || tok.type == T_Priority) return E_PARSE_AS_REM;
|
||||
if (tok.type == T_Tag || tok.type == T_Duration || tok.type == T_RemType || tok.type == T_Priority) return E_PARSE_AS_REM;
|
||||
return OK;
|
||||
|
||||
}
|
||||
|
||||
static int
|
||||
DoThroughOmit(ParsePtr p, int ystart, int mstart, int dstart)
|
||||
{
|
||||
int yend = NO_YR, mend = NO_MON, dend = NO_DAY, r;
|
||||
int start, end, tmp;
|
||||
|
||||
Token tok;
|
||||
|
||||
DynamicBuffer buf;
|
||||
DBufInit(&buf);
|
||||
int parsing = 1;
|
||||
|
||||
while(parsing) {
|
||||
if ( (r=ParseToken(p, &buf)) ) return r;
|
||||
FindToken(DBufValue(&buf), &tok);
|
||||
|
||||
switch(tok.type) {
|
||||
case T_Date:
|
||||
DBufFree(&buf);
|
||||
if (yend != NO_YR) return E_YR_TWICE;
|
||||
if (mend != NO_MON) return E_MON_TWICE;
|
||||
if (dend != NO_DAY) return E_DAY_TWICE;
|
||||
FromJulian(tok.val, ¥d, &mend, &dend);
|
||||
break;
|
||||
|
||||
case T_Year:
|
||||
DBufFree(&buf);
|
||||
if (yend != NO_YR) return E_YR_TWICE;
|
||||
yend = tok.val;
|
||||
break;
|
||||
|
||||
case T_Month:
|
||||
DBufFree(&buf);
|
||||
if (mend != NO_MON) return E_MON_TWICE;
|
||||
mend = tok.val;
|
||||
break;
|
||||
|
||||
case T_Day:
|
||||
DBufFree(&buf);
|
||||
if (dend != NO_DAY) return E_DAY_TWICE;
|
||||
dend = tok.val;
|
||||
break;
|
||||
|
||||
case T_Empty:
|
||||
case T_Comment:
|
||||
case T_RemType:
|
||||
case T_Priority:
|
||||
case T_Tag:
|
||||
case T_Duration:
|
||||
DBufFree(&buf);
|
||||
parsing = 0;
|
||||
break;
|
||||
|
||||
default:
|
||||
Eprint("%s: `%s' (OMIT)", ErrMsg[E_UNKNOWN_TOKEN],
|
||||
DBufValue(&buf));
|
||||
DBufFree(&buf);
|
||||
return E_UNKNOWN_TOKEN;
|
||||
|
||||
}
|
||||
}
|
||||
if (yend == NO_YR || mend == NO_MON || dend == NO_DAY) return E_INCOMPLETE;
|
||||
if (dend > DaysInMonth(mend, yend)) return E_BAD_DATE;
|
||||
if (dstart > DaysInMonth(mstart, ystart)) return E_BAD_DATE;
|
||||
|
||||
start = Julian(ystart, mstart, dstart);
|
||||
end = Julian(yend, mend, dend);
|
||||
|
||||
if (end < start) {
|
||||
tmp = start;
|
||||
start = end;
|
||||
end = tmp;
|
||||
}
|
||||
|
||||
tmp = end - start + 1;
|
||||
|
||||
/* Don't create any OMITs if there would be too many. */
|
||||
if (NumFullOmits + tmp >= MAX_FULL_OMITS) return E_2MANY_FULL;
|
||||
for (tmp = start; tmp <= end; tmp++) {
|
||||
if (!BexistsIntArray(FullOmitArray, NumFullOmits, tmp)) {
|
||||
InsertIntoSortedArray(FullOmitArray, NumFullOmits, tmp);
|
||||
NumFullOmits++;
|
||||
}
|
||||
}
|
||||
if (tok.type == T_Tag || tok.type == T_Duration || tok.type == T_RemType || tok.type == T_Priority) return E_PARSE_AS_REM;
|
||||
return OK;
|
||||
}
|
||||
|
||||
void
|
||||
DumpOmits(void)
|
||||
{
|
||||
int i;
|
||||
int y, m, d;
|
||||
printf("Global Full OMITs (%d of maximum allowed %d):\n", NumFullOmits, MAX_FULL_OMITS);
|
||||
if (!NumFullOmits) {
|
||||
printf("\tNone.\n");
|
||||
} else {
|
||||
for (i=0; i<NumFullOmits; i++) {
|
||||
FromJulian(FullOmitArray[i], &y, &m, &d);
|
||||
printf("\t%04d%c%02d%c%02d\n",
|
||||
y, DateSep, m+1, DateSep, d);
|
||||
}
|
||||
}
|
||||
printf("Global Partial OMITs (%d of maximum allowed %d):\n", NumPartialOmits, MAX_PARTIAL_OMITS);
|
||||
if (!NumPartialOmits) {
|
||||
printf("\tNone.\n");
|
||||
} else {
|
||||
for (i=0; i<NumPartialOmits; i++) {
|
||||
m = PartialOmitArray[i] >> 5 & 0xf;
|
||||
d = PartialOmitArray[i] & 0x1f;
|
||||
printf("\t%02d%c%02d\n", m+1, DateSep, d);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -136,5 +136,7 @@ void HuntPhase (int startdate, int starttim, int phas, int *date, int *time);
|
||||
int CompareRems (int dat1, int tim1, int prio1, int dat2, int tim2, int prio2, int bydate, int bytime, int byprio, int untimed_first);
|
||||
void SigIntHandler (int d);
|
||||
void GotSigInt (void);
|
||||
void SynthesizeTag(char *);
|
||||
void PurgeEchoLine(char const *fmt, ...);
|
||||
void FreeTrig(Trigger *t);
|
||||
void AppendTag(DynamicBuffer *buf, char const *s);
|
||||
char const *SynthesizeTag(void);
|
||||
|
||||
16
src/queue.c
16
src/queue.c
@@ -43,7 +43,7 @@ typedef struct queuedrem {
|
||||
char const *text;
|
||||
char passthru[PASSTHRU_LEN+1];
|
||||
char sched[VAR_NAME_LEN+1];
|
||||
char tag[TAG_LEN+1];
|
||||
DynamicBuffer tags;
|
||||
TimeTrig tt;
|
||||
} QueuedRem;
|
||||
|
||||
@@ -96,9 +96,10 @@ int QueueReminder(ParsePtr p, Trigger *trig,
|
||||
qelem->RunDisabled = RunDisabled;
|
||||
qelem->ntrig = 0;
|
||||
strcpy(qelem->sched, sched);
|
||||
strcpy(qelem->tag, trig->tag);
|
||||
if (! *qelem->tag && SynthesizeTags) {
|
||||
SynthesizeTag(qelem->tag);
|
||||
DBufInit(&(qelem->tags));
|
||||
DBufPuts(&(qelem->tags), DBufValue(&(trig->tags)));
|
||||
if (SynthesizeTags) {
|
||||
AppendTag(&(qelem->tags), SynthesizeTag());
|
||||
}
|
||||
QueueHead = qelem;
|
||||
return OK;
|
||||
@@ -235,12 +236,11 @@ void HandleQueuedReminders(void)
|
||||
printf("NOTE reminder %s",
|
||||
SimpleTime(q->tt.ttime));
|
||||
printf("%s", SimpleTime(SystemTime(0)/60));
|
||||
if (!*q->tag) {
|
||||
printf("*");
|
||||
if (!*DBufValue(&q->tags)) {
|
||||
printf("*\n");
|
||||
} else {
|
||||
printf("%s", q->tag);
|
||||
printf("%s\n", DBufValue(&(q->tags)));
|
||||
}
|
||||
printf("\n");
|
||||
}
|
||||
|
||||
/* Set up global variables so some functions like trigdate()
|
||||
|
||||
@@ -366,6 +366,7 @@ void DoPsCal(void)
|
||||
}
|
||||
}
|
||||
} else if (!strcmp(passthru, "*") ||
|
||||
!strcmp(passthru, "COLOUR") ||
|
||||
!strcmp(passthru, "COLOR")) {
|
||||
/* Put on linked list */
|
||||
if (!CurEntries) {
|
||||
@@ -375,7 +376,8 @@ void DoPsCal(void)
|
||||
while(d->next) d = d->next;
|
||||
d->next = c;
|
||||
}
|
||||
if (!strcmp(passthru, "COLOR")) {
|
||||
if (!strcmp(passthru, "COLOR") ||
|
||||
!strcmp(passthru, "COLOUR")) {
|
||||
c->special = SPECIAL_COLOR;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -94,6 +94,7 @@ Token TokArray[] = {
|
||||
{ "special", 7, T_RemType, PASSTHRU_TYPE },
|
||||
{ "sunday", 3, T_WkDay, 6 },
|
||||
{ "tag", 3, T_Tag, 0 },
|
||||
{ "through", 7, T_Through, 0 },
|
||||
{ "thursday", 3, T_WkDay, 3 },
|
||||
{ "tuesday", 3, T_WkDay, 1 },
|
||||
{ "unset", 5, T_UnSet, 0 },
|
||||
@@ -359,7 +360,7 @@ static int TokStrCmp(Token const *t, char const *s)
|
||||
register int r;
|
||||
char const *tk = t->name;
|
||||
while(*tk && *s && !(*s == ',' && *(s+1) == 0)) {
|
||||
r = *tk - tolower(*s);
|
||||
r = tolower(*tk) - tolower(*s);
|
||||
tk++;
|
||||
s++;
|
||||
if (r) return r;
|
||||
@@ -367,5 +368,5 @@ static int TokStrCmp(Token const *t, char const *s)
|
||||
/* Ignore trailing commas on s */
|
||||
|
||||
if (!*s || (*s == ',' && !*(s+1))) return 0;
|
||||
return (*tk - *s);
|
||||
return (tolower(*tk) - tolower(*s));
|
||||
}
|
||||
|
||||
@@ -73,7 +73,7 @@ typedef struct {
|
||||
char sched[VAR_NAME_LEN+1]; /* Scheduling function */
|
||||
char warn[VAR_NAME_LEN+1]; /* Warning function */
|
||||
char omitfunc[VAR_NAME_LEN+1]; /* OMITFUNC function */
|
||||
char tag[TAG_LEN+1];
|
||||
DynamicBuffer tags;
|
||||
char passthru[PASSTHRU_LEN+1];
|
||||
} Trigger;
|
||||
|
||||
@@ -167,7 +167,8 @@ enum TokTypes
|
||||
T_Tag,
|
||||
T_Duration,
|
||||
T_LongTime,
|
||||
T_OmitFunc
|
||||
T_OmitFunc,
|
||||
T_Through
|
||||
};
|
||||
|
||||
/* The structure of a token */
|
||||
|
||||
@@ -7,11 +7,11 @@ REM 28 SPECIAL COLOR 65 0 65 Dim Magenta
|
||||
REM 28 SPECIAL COLOR 65 65 0 Dim Yellow
|
||||
REM 28 SPECIAL COLOR 65 65 65 Dim White
|
||||
|
||||
REM 28 SPECIAL COLOR 129 0 0 Bright Red
|
||||
REM 28 SPECIAL COLOR 0 129 0 Bright Green
|
||||
REM 28 SPECIAL COLOR 0 0 129 Bright Blue
|
||||
REM 28 SPECIAL COLOR 0 129 129 Bright Cyan
|
||||
REM 28 SPECIAL COLOR 129 0 129 Bright Magenta
|
||||
REM 28 SPECIAL COLOR 129 129 0 Bright Yellow
|
||||
REM 28 SPECIAL COLOR 129 129 129 Bright White
|
||||
REM 28 SPECIAL COLOUR 129 0 0 Bright Red
|
||||
REM 28 SPECIAL COLOUR 0 129 0 Bright Green
|
||||
REM 28 SPECIAL COLOUR 0 0 129 Bright Blue
|
||||
REM 28 SPECIAL COLOUR 0 129 129 Bright Cyan
|
||||
REM 28 SPECIAL COLOUR 129 0 129 Bright Magenta
|
||||
REM 28 SPECIAL COLOUR 129 129 0 Bright Yellow
|
||||
REM 28 SPECIAL COLOUR 129 129 129 Bright White
|
||||
|
||||
|
||||
@@ -22,28 +22,28 @@ chmod 000 include_dir/04cantread.rem
|
||||
TEST_GETENV="foo bar baz" ; export TEST_GETENV
|
||||
echo "Test 1" > ../tests/test.out
|
||||
echo "" >> ../tests/test.out
|
||||
../src/remind -e -dxte ../tests/test.rem 16 feb 1991 >> ../tests/test.out
|
||||
../src/remind -e -dxte ../tests/test.rem 16 feb 1991 >> ../tests/test.out 2>&1
|
||||
echo "" >> ../tests/test.out
|
||||
echo "Test 2" >> ../tests/test.out
|
||||
echo "" >> ../tests/test.out
|
||||
../src/remind -p -l ../tests/test2.rem 1 aug 2007 >> ../tests/test.out
|
||||
../src/remind -p -l ../tests/test2.rem 1 aug 2007 >> ../tests/test.out 2>&1
|
||||
echo "" >> ../tests/test.out
|
||||
echo "Test 3" >> ../tests/test.out
|
||||
echo "" >> ../tests/test.out
|
||||
../src/remind -s ../tests/test2.rem 1 aug 2007 >> ../tests/test.out
|
||||
../src/remind -s ../tests/test2.rem 1 aug 2007 >> ../tests/test.out 2>&1
|
||||
echo "" >> ../tests/test.out
|
||||
echo "Test 4" >> ../tests/test.out
|
||||
echo "" >> ../tests/test.out
|
||||
../src/remind -sa ../tests/test2.rem 1 aug 2007 >> ../tests/test.out
|
||||
../src/remind -sa ../tests/test2.rem 1 aug 2007 >> ../tests/test.out 2>&1
|
||||
echo "Test 5" >> ../tests/test.out
|
||||
echo "" >> ../tests/test.out
|
||||
../src/remind -p -l -b0 ../tests/test3.rem 1 aug 2007 >> ../tests/test.out
|
||||
../src/remind -p -l -b0 ../tests/test3.rem 1 aug 2007 >> ../tests/test.out 2>&1
|
||||
echo "Test 6" >> ../tests/test.out
|
||||
echo "" >> ../tests/test.out
|
||||
../src/remind -p -l -b1 ../tests/test3.rem 1 aug 2007 >> ../tests/test.out
|
||||
../src/remind -p -l -b1 ../tests/test3.rem 1 aug 2007 >> ../tests/test.out 2>&1
|
||||
echo "Test 7" >> ../tests/test.out
|
||||
echo "" >> ../tests/test.out
|
||||
../src/remind -p -l -b2 ../tests/test3.rem 1 aug 2007 >> ../tests/test.out
|
||||
../src/remind -p -l -b2 ../tests/test3.rem 1 aug 2007 >> ../tests/test.out 2>&1
|
||||
|
||||
echo "Test 8" >> ../tests/test.out
|
||||
echo "" >> ../tests/test.out
|
||||
@@ -58,14 +58,14 @@ echo "" >> ../tests/test.out
|
||||
chmod 644 include_dir/04cantread.rem
|
||||
|
||||
echo "Color Test" >> ../tests/test.out
|
||||
../src/remind -ccl ../tests/colors.rem 1 aug 2007 >> ../tests/test.out
|
||||
../src/remind -ccl ../tests/colors.rem 1 aug 2007 >> ../tests/test.out 2>&1
|
||||
|
||||
echo "MON WKDAY DAY across year test" >> ../tests/test.out
|
||||
echo 'REM Mon 29 Dec MSG x' | ../src/remind -dt - 1 Jan 2000 >> ../tests/test.out 2>&1
|
||||
|
||||
echo "Sort Test" >> ../tests/test.out
|
||||
(echo "REM AT 12:00 MSG Untimed"; echo "REM MSG Timed") | ../src/remind -gaaa - 1 Jan 2000 >> ../tests/test.out 2>&1
|
||||
(echo "REM AT 12:00 MSG Untimed"; echo "REM MSG Timed") | ../src/remind -gaaad - 1 Jan 2000 >> ../tests/test.out 2>&1
|
||||
(echo "REM AT 12:00 MSG Untimed"; echo "REM MSG Timed") | ../src/remind -q -gaaa - 1 Jan 2000 >> ../tests/test.out 2>&1
|
||||
(echo "REM AT 12:00 MSG Untimed"; echo "REM MSG Timed") | ../src/remind -q -gaaad - 1 Jan 2000 >> ../tests/test.out 2>&1
|
||||
|
||||
echo "Purge Test" >> ../tests/test.out
|
||||
../src/remind -j999 ../tests/purge_dir/f1.rem >> ../tests/test.out 2>&1
|
||||
|
||||
@@ -836,7 +836,7 @@ set a057 value("a05"+"6")
|
||||
"a05" + "6" => "a056"
|
||||
value("a056") => "SDFJHSDF KSJDFH KJSDFH KSJDFH"
|
||||
set a058 version()
|
||||
version() => "03.01.09"
|
||||
version() => "03.01.11"
|
||||
set a059 wkday(today())
|
||||
today() => 1991-02-16
|
||||
wkday(1991-02-16) => "Saturday"
|
||||
@@ -989,7 +989,7 @@ dump
|
||||
a048 "foo"
|
||||
a067 "INT"
|
||||
a039 "February"
|
||||
a058 "03.01.09"
|
||||
a058 "03.01.11"
|
||||
a077 "1992 92
|
||||
"
|
||||
a049 21
|
||||
@@ -1046,6 +1046,32 @@ dump
|
||||
a045 "iess"
|
||||
a064 1
|
||||
a083 1991-03-24
|
||||
OMIT 2010-09-03 THROUGH 2010-09-15
|
||||
OMIT December 25 MSG X
|
||||
../tests/test.rem(286): Trig = Wednesday, 25 December, 1991
|
||||
# Next should give a parse error
|
||||
OMIT 26 Dec 2010 THROUGH 27 Dec 2010 MSG This is not legal
|
||||
../tests/test.rem(288): Trig = Sunday, 26 December, 2010
|
||||
OMIT DUMP
|
||||
Global Full OMITs (16 of maximum allowed 500):
|
||||
1991-03-11
|
||||
2010-09-03
|
||||
2010-09-04
|
||||
2010-09-05
|
||||
2010-09-06
|
||||
2010-09-07
|
||||
2010-09-08
|
||||
2010-09-09
|
||||
2010-09-10
|
||||
2010-09-11
|
||||
2010-09-12
|
||||
2010-09-13
|
||||
2010-09-14
|
||||
2010-09-15
|
||||
2010-12-26
|
||||
2010-12-27
|
||||
Global Partial OMITs (1 of maximum allowed 366):
|
||||
12-25
|
||||
|
||||
|
||||
Test 2
|
||||
|
||||
@@ -282,3 +282,8 @@ set a083 slide('1991-04-01', -7, "Sat")
|
||||
set a084 nonomitted('1991-03-01', '1991-03-13', "Sat", "Sun")
|
||||
set a085 nonomitted('1991-03-24', '1991-04-01', "Sat")
|
||||
dump
|
||||
OMIT 2010-09-03 THROUGH 2010-09-15
|
||||
OMIT December 25 MSG X
|
||||
# Next should give a parse error
|
||||
OMIT 26 Dec 2010 THROUGH 27 Dec 2010 MSG This is not legal
|
||||
OMIT DUMP
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
#!/bin/sh
|
||||
|
||||
echo "Unconfiguring Remind..."
|
||||
echo rm -f config.cache config.log config.status src/Makefile src/config.h src/version.h
|
||||
rm -f config.cache config.log config.status src/Makefile src/config.h src/version.h
|
||||
echo rm -f config.cache config.log config.status src/Makefile src/config.h src/version.h www/Makefile
|
||||
rm -f config.cache config.log config.status src/Makefile src/config.h src/version.h www/Makefile
|
||||
exit 0
|
||||
|
||||
325
www/php/remind.php
Normal file
325
www/php/remind.php
Normal file
@@ -0,0 +1,325 @@
|
||||
<?php
|
||||
|
||||
class Remind
|
||||
{
|
||||
# For validating commands we send to popen
|
||||
function is_valid_day($d) {
|
||||
return (preg_match('/^\d+$/', $d) &&
|
||||
$d >= 1 && $d <= 31;
|
||||
}
|
||||
|
||||
function is_valid_month($m) {
|
||||
return
|
||||
($m == 'January') ||
|
||||
($m == 'February') ||
|
||||
($m == 'March') ||
|
||||
($m == 'April') ||
|
||||
($m == 'May') ||
|
||||
($m == 'June') ||
|
||||
($m == 'July') ||
|
||||
($m == 'August') ||
|
||||
($m == 'September') ||
|
||||
($m == 'October') ||
|
||||
($m == 'November') ||
|
||||
($m == 'December');
|
||||
}
|
||||
|
||||
function is_valid_year($y) {
|
||||
return preg_match('/^\d\d\d\d$/', $y) &&
|
||||
$y >= 1900;
|
||||
}
|
||||
|
||||
|
||||
function get_el(&$array, $i)
|
||||
{
|
||||
if (!array_key_exists($i, $array)) return null;
|
||||
return $array[$i];
|
||||
}
|
||||
|
||||
function get_elem($array, $indexes)
|
||||
{
|
||||
foreach ($indexes as $i) {
|
||||
if (!is_array($array)) return null;
|
||||
if (!array_key_exists($i, $array)) return null;
|
||||
$array = $array[$i];
|
||||
}
|
||||
return $array;
|
||||
}
|
||||
|
||||
function munge_entry($day, &$results, &$specials, &$options, $str, &$e) {
|
||||
return htmlspecialchars($str);
|
||||
}
|
||||
|
||||
function format_entry($day, &$results, &$specials, &$options, &$e) {
|
||||
$special = $this->get_el($e, 'special');
|
||||
$body = $this->get_el($e, 'body');
|
||||
|
||||
if ($body === null) $body = '';
|
||||
if ($special === null || $special == '*') {
|
||||
return $this->munge_entry($day, $results, $specials, $options, $body, $e);
|
||||
}
|
||||
if ($special == 'COLOR' || $special == 'COLOUR') {
|
||||
if (preg_match('/^(\d+)\s+(\d+)\s+(\d+)\s+(.*)/', $body, $matches)) {
|
||||
return sprintf('<span style="color: #%02x%02x%02x">%s</span>',
|
||||
$matches[1] % 255,
|
||||
$matches[2] % 255,
|
||||
$matches[3] % 255,
|
||||
$this->munge_entry($day, $results, $specials, $options, $matches[4], $e));
|
||||
}
|
||||
return 'Bad COLOR spec: ' . htmlspecialchars($body);
|
||||
}
|
||||
|
||||
# HTML is passed through un-munged.
|
||||
if ($special == 'HTML') return $body;
|
||||
|
||||
# Ignore unknown specials
|
||||
return '';
|
||||
}
|
||||
|
||||
function format_entries($day, &$results, &$specials, &$options, &$entries) {
|
||||
$html = '';
|
||||
foreach ($entries as $e) {
|
||||
$html .= '<div class="rem-entry">' . $this->format_entry($day, $results, $specials, $options, $e) . '</div>';
|
||||
}
|
||||
return $html;
|
||||
}
|
||||
|
||||
function do_one_day($day, &$results, &$specials, &$options) {
|
||||
$class = $this->get_elem($specials, array('HTMLCLASS', $day, 0, 'body'));
|
||||
$shade = $this->get_elem($specials, array('SHADE', $day, 0, 'body'));
|
||||
$moon = $this->get_elem($specials, array('MOON', $day, 0, 'body'));
|
||||
|
||||
if ($class === null) $class = 'rem-cell';
|
||||
$bg = '';
|
||||
if ($shade !== null) {
|
||||
if (preg_match('/(\d+)\s+(\d+)\s+(\d+)/', $shade, $matches)) {
|
||||
if ($matches[1] <= 255 && $matches[2] <= 255 && $matches[3] <= 255) {
|
||||
$bg = sprintf(' style="background: #%02x%02x%02x"',
|
||||
$matches[1], $matches[2], $matches[3]);
|
||||
}
|
||||
}
|
||||
}
|
||||
$html = "<td class=\"$class\"$bg>";
|
||||
|
||||
$week = $this->get_elem($specials, array('WEEK', $day, 0, 'body'));
|
||||
if ($week === null) {
|
||||
$week = '';
|
||||
} else {
|
||||
$week = ' ' . $week;
|
||||
}
|
||||
|
||||
$moon_html = '';
|
||||
if ($moon !== null) {
|
||||
$phase = -1;
|
||||
if (preg_match('/(\d+)\s+(\S+)\s+(\S+)\s+(.*)$/', $moon, $matches)) {
|
||||
$phase = $matches[1];
|
||||
$moonsize = $matches[2];
|
||||
$fontsize = $matches[3];
|
||||
$msg = $matches[4];
|
||||
} elseif (preg_match('/(\d+)/', $moon, $matches)) {
|
||||
$phase = $matches[1];
|
||||
$msg = '';
|
||||
}
|
||||
if ($phase >= 0) {
|
||||
if ($phase == 0) {
|
||||
$img = 'newmoon.png';
|
||||
$title = 'New Moon';
|
||||
$alt = 'new';
|
||||
} elseif ($phase == 1) {
|
||||
$img = 'firstquarter.png';
|
||||
$title = 'First Quarter';
|
||||
$alt = '1st';
|
||||
} elseif ($phase == 2) {
|
||||
$img = 'fullmoon.png';
|
||||
$alt = 'full';
|
||||
$title = 'Full Moon';
|
||||
} else {
|
||||
$img = 'lastquarter.png';
|
||||
$alt = 'last';
|
||||
$title = 'Last Quarter';
|
||||
}
|
||||
$base = rtrim($this->get_el($options, 'imgbase'), '/');
|
||||
if ($base !== null) {
|
||||
$img = $base . '/' . $img;
|
||||
}
|
||||
$moon_html = '<div class="rem-moon">' . "<img width=\"16\" height=\"16\" alt=\"$alt\" title=\"$title\" src=\"$img\">" . htmlspecialchars($msg) . '</div>';
|
||||
}
|
||||
}
|
||||
|
||||
# Day number
|
||||
$html .= $moon_html . '<div class="rem-daynumber">' . $day . $week . '</div>';
|
||||
|
||||
# And the entries
|
||||
$entries = $this->get_elem($results, array('entries', $day));
|
||||
if (is_array($entries) && count($entries) > 0) {
|
||||
$html .= '<div class="rem-entries">';
|
||||
$html .= $this->format_entries($day, $results, $specials, $options, $entries);
|
||||
$html .= '</div>';
|
||||
}
|
||||
$html .= "</td>\n";
|
||||
return $html;
|
||||
}
|
||||
|
||||
function generate_html(&$results, &$specials, &$options)
|
||||
{
|
||||
$monday_first = $results['monday_flag'];
|
||||
$first_col = $results['first_day'];
|
||||
if ($monday_first) {
|
||||
$first_col--;
|
||||
if ($first_col < 0) $first_col = 6;
|
||||
}
|
||||
|
||||
$last_col = ($first_col + $results['days_in_mon'] -1) % 7;
|
||||
|
||||
$html = '<table class="rem-cal"><caption class="rem-cal-caption">' .
|
||||
htmlspecialchars($results['month']) . ' ' . htmlspecialchars($results['year']) .
|
||||
"</caption>\n";
|
||||
|
||||
$html .= '<tr class="rem-cal-hdr-row">';
|
||||
if (!$monday_first) $html .= '<th class="rem-cal-hdr">' . htmlspecialchars($results['day_names'][0]) . '</th>';
|
||||
for ($i=1; $i<7; $i++) $html .= '<th class="rem-cal-hdr">' . htmlspecialchars($results['day_names'][$i]) . '</th>';
|
||||
if ($monday_first) $html .= '<th class="rem-cal-hdr">' . htmlspecialchars($results['day_names'][0]) . '</th>';
|
||||
$html .= "</tr>\n";
|
||||
|
||||
# Do the leading empty columns
|
||||
for ($col=0; $col < $first_col; $col++) {
|
||||
if ($col == 0) $html .= '<tr class="rem-cal-body-row">';
|
||||
$html .= '<td class="rem-empty"> </td>';
|
||||
}
|
||||
|
||||
for ($day=1; $day <= $results['days_in_mon']; $day++) {
|
||||
if ($col == 0) $html .= '<tr class="rem-cal-body-row">';
|
||||
$col++;
|
||||
$html .= $this->do_one_day($day, $results, $specials, $options);
|
||||
if ($col == 7) {
|
||||
$html .= "</tr>\n";
|
||||
$col = 0;
|
||||
}
|
||||
}
|
||||
if ($col) {
|
||||
while ($col++ < 7) {
|
||||
$html .= '<td class="rem-empty"> </td>';
|
||||
}
|
||||
}
|
||||
$html .= "</tr>\n";
|
||||
|
||||
$html .= "</table>\n";
|
||||
return $html;
|
||||
}
|
||||
function parse_remind_output ($fp)
|
||||
{
|
||||
while(1) {
|
||||
$line = fgets($fp);
|
||||
if ($line === false) break;
|
||||
$line = trim($line);
|
||||
if ($line == '# rem2ps begin') break;
|
||||
}
|
||||
if ($line === false) {
|
||||
return array('success' => 0,
|
||||
'error' => 'Could not find any Rem2PS data');
|
||||
}
|
||||
|
||||
$line = fgets($fp);
|
||||
if ($line === false) {
|
||||
return array('success' => 0,
|
||||
'error' => 'Unexpected end-of-file');
|
||||
}
|
||||
|
||||
$line = trim($line);
|
||||
list($month, $year, $days_in_mon, $first_day, $monday_flag) = explode(' ', $line);
|
||||
$retval = array('month' => $month,
|
||||
'year' => $year,
|
||||
'days_in_mon' => $days_in_mon,
|
||||
'first_day' => $first_day,
|
||||
'monday_flag' => $monday_flag);
|
||||
|
||||
$line = fgets($fp);
|
||||
if ($line === false) {
|
||||
return array('success' => 0,
|
||||
'error' => 'Unexpected end-of-file');
|
||||
}
|
||||
|
||||
$line = trim($line);
|
||||
$retval['day_names'] = explode(' ', $line);
|
||||
|
||||
$line = fgets($fp);
|
||||
if ($line === false) {
|
||||
return array('success' => 0,
|
||||
'error' => 'Unexpected end-of-file');
|
||||
}
|
||||
$line = trim($line);
|
||||
|
||||
list($m, $n) = explode(' ', $line);
|
||||
$retval['prev'] = array('month' => $m, 'days' => $n);
|
||||
|
||||
$line = fgets($fp);
|
||||
if ($line === false) {
|
||||
return array('success' => 0,
|
||||
'error' => 'Unexpected end-of-file');
|
||||
}
|
||||
$line = trim($line);
|
||||
|
||||
list($m, $n) = explode(' ', $line);
|
||||
$retval['next'] = array('month' => $m, 'days' => $n);
|
||||
|
||||
$line_info = 0;
|
||||
|
||||
$entries = array();
|
||||
$specials = array();
|
||||
while (1) {
|
||||
$line = fgets($fp);
|
||||
if ($line === false) break;
|
||||
$line = trim($line);
|
||||
if ($line == '# rem2ps end') break;
|
||||
if (strpos($line, '# fileinfo ') === 0) {
|
||||
list($lno, $fname) = explode(' ', substr($line, 11), 2);
|
||||
$lineinfo = array('file' => $fname, 'line' => $lno);
|
||||
continue;
|
||||
}
|
||||
list($date, $special, $tags, $duration, $time, $body) = explode(' ', $line, 6);
|
||||
list($y, $m, $d) = explode('/', $date);
|
||||
$d = preg_replace('/^0(.)/', '$1', $d);
|
||||
$m = preg_replace('/^0(.)/', '$1', $m);
|
||||
$entry = array('day' => $d,
|
||||
'month' => $m,
|
||||
'year' => $y,
|
||||
'special' => $special,
|
||||
'tags' => $tags,
|
||||
'duration' => $duration,
|
||||
'time' => $time,
|
||||
'body' => $body);
|
||||
if (is_array($lineinfo)) {
|
||||
$entry['line'] = $lineinfo['line'];
|
||||
$entry['file'] = $lineinfo['file'];
|
||||
$lineinfo = 0;
|
||||
}
|
||||
if ($special != '*' && $special != 'COLOR' && $special != 'COLOUR' && $special != 'HTML') {
|
||||
if (!array_key_exists($special, $specials)) {
|
||||
$specials[$special] = array();
|
||||
}
|
||||
if (!array_key_exists($d, $specials[$special])) {
|
||||
$specials[$special][$d] = array();
|
||||
}
|
||||
$specials[$special][$d][] = $entry;
|
||||
} else {
|
||||
if (!array_key_exists($d, $entries)) {
|
||||
$entries[$d] = array();
|
||||
}
|
||||
$entries[$d][] = $entry;
|
||||
}
|
||||
|
||||
}
|
||||
$retval['entries'] = $entries;
|
||||
return array('success' => 1, 'results' => $retval, 'specials' => $specials);
|
||||
}
|
||||
}
|
||||
|
||||
$fp = popen('rem -p -l', 'r');
|
||||
$r = new Remind;
|
||||
$ans = $r->parse_remind_output($fp);
|
||||
pclose($fp);
|
||||
#print_r($ans);
|
||||
$options = array();
|
||||
print $r->generate_html($ans['results'], $ans['specials'], $options);
|
||||
|
||||
?>
|
||||
@@ -257,7 +257,7 @@ sub parse_input
|
||||
$shades->[$d] = sprintf("#%02X%02X%02X",
|
||||
($1 % 256), ($2 % 256), ($3 % 256));
|
||||
}
|
||||
} elsif ($special eq 'COLOR') {
|
||||
} elsif ($special eq 'COLOR' || $special eq 'COLOUR') {
|
||||
if ($body =~ /(\d+)\s+(\d+)\s+(\d+)\s+(.*)$/) {
|
||||
my($r, $g, $b, $text) = ($1, $2, $3, $4);
|
||||
my $color = sprintf("style=\"color: #%02X%02X%02X;\"",
|
||||
|
||||
Reference in New Issue
Block a user