mirror of
https://salsa.debian.org/dskoll/remind.git
synced 2026-04-16 06:18:47 +02:00
Add PUSH-SYSVARS and POP-SYSVARS commands.
This commit is contained in:
@@ -110,15 +110,17 @@
|
||||
(defconst remind-keywords
|
||||
(sort
|
||||
(list "ADDOMIT" "AFTER" "AT" "BAN" "BANNER" "BEFORE" "CAL" "CLEAR"
|
||||
"CLEAR-OMIT-CONTEXT" "DEBUG" "DO" "DUMP" "DUMPVARS" "DURATION" "ELSE"
|
||||
"ENDIF" "ERRMSG" "EXIT" "EXPR" "FIRST" "FLUSH" "FOURTH" "FRENAME" "FROM" "FSET"
|
||||
"FUNSET" "IF" "IFTRIG" "IN" "INC" "INCLUDE" "INCLUDECMD" "INFO" "LAST"
|
||||
"LASTDAY" "LASTWORKDAY" "MAYBE" "MAYBE-UNCOMPUTABLE" "MSF" "MSG"
|
||||
"NOQUEUE" "OMIT" "OMITFUNC" "ONCE" "POP" "POP-OMIT-CONTEXT" "PRESERVE"
|
||||
"PRIORITY" "PS" "PSFILE" "PUSH" "PUSH-OMIT-CONTEXT" "REM" "RUN"
|
||||
"SATISFY" "SCAN" "SCANFROM" "SCHED" "SECOND" "SET" "SKIP" "SPECIAL"
|
||||
"SYSINCLUDE" "TAG" "THIRD" "THROUGH" "TRANSLATE" "TRANS" "UNSET"
|
||||
"UNTIL" "WARN")
|
||||
"CLEAR-OMIT-CONTEXT" "DEBUG" "DO" "DUMP" "DUMPVARS"
|
||||
"DURATION" "ELSE" "ENDIF" "ERRMSG" "EXIT" "EXPR" "FIRST"
|
||||
"FLUSH" "FOURTH" "FRENAME" "FROM" "FSET" "FUNSET" "IF"
|
||||
"IFTRIG" "IN" "INC" "INCLUDE" "INCLUDECMD" "INFO" "LAST"
|
||||
"LASTDAY" "LASTWORKDAY" "MAYBE" "MAYBE-UNCOMPUTABLE" "MSF"
|
||||
"MSG" "NOQUEUE" "OMIT" "OMITFUNC" "ONCE" "POP"
|
||||
"POP-OMIT-CONTEXT" "POP-SYSVARS" "PRESERVE" "PRIORITY" "PS"
|
||||
"PSFILE" "PUSH" "PUSH-SYSVARS" "PUSH-OMIT-CONTEXT" "REM"
|
||||
"RUN" "SATISFY" "SCAN" "SCANFROM" "SCHED" "SECOND" "SET"
|
||||
"SKIP" "SPECIAL" "SYSINCLUDE" "TAG" "THIRD" "THROUGH"
|
||||
"TRANSLATE" "TRANS" "UNSET" "UNTIL" "WARN")
|
||||
#'(lambda (a b) (> (length a) (length b)))))
|
||||
|
||||
|
||||
|
||||
@@ -2579,7 +2579,7 @@ For example, to delete all the variables declared above, use:
|
||||
UNSET a b mydir time date
|
||||
.fi
|
||||
.PP
|
||||
.B SYSTEM VARIABLES
|
||||
.SH SYSTEM VARIABLES
|
||||
.PP
|
||||
In addition to the regular user variables, \fBRemind\fR has several
|
||||
"system variables" that are used to query or control the operating
|
||||
@@ -3125,7 +3125,31 @@ Note: If any of the calendar modes are in effect, then the
|
||||
values of $Daemon, $DontFork, $DontTrigAts, $DontQueue, $HushMode,
|
||||
$IgnoreOnce, $InfDelta, and $NextMode are not meaningful.
|
||||
.PP
|
||||
.B BUILT-IN FUNCTIONS
|
||||
.SH SAVING AND RESTORING SYSTEM VARIABLES
|
||||
.PP
|
||||
Just as with the OMIT context, you can save and restore the values of
|
||||
all (modifiable) system variables. For example:
|
||||
.PP
|
||||
.nf
|
||||
# Save all system variables
|
||||
PUSH-SYSVARS
|
||||
|
||||
SET $DefaultColor "255 0 0"
|
||||
SET $AddBlankLines 0
|
||||
REM MSG Hello
|
||||
|
||||
# Restore all system variables
|
||||
POP-SYSVARS
|
||||
|
||||
# Now the changes to $DefaultColor and $AddBlankLines
|
||||
# have been undone
|
||||
.fi
|
||||
.PP
|
||||
As you see from the example, PUSH-SYSVARS saves the values of all system
|
||||
variables, and POP-SYSVARS restores them to the values they had at the
|
||||
time of the matching PUSH-SYSVARS call.
|
||||
.PP
|
||||
.SH BUILT-IN FUNCTIONS
|
||||
.PP
|
||||
\fBRemind\fR has a plethora of built-in functions. The syntax for a function
|
||||
call is the same as in C - the function name, followed a comma-separated list
|
||||
|
||||
@@ -1806,6 +1806,18 @@ static void GenerateCalEntries(int col)
|
||||
break;
|
||||
case T_Pop: r=PopOmitContext(&p); break;
|
||||
case T_Push: r=PushOmitContext(&p); break;
|
||||
case T_PushSysvars:
|
||||
r=PushSysvars();
|
||||
if (r == OK) {
|
||||
r = VerifyEoln(&p);
|
||||
}
|
||||
break;
|
||||
case T_PopSysvars:
|
||||
r=PopSysvars();
|
||||
if (r == OK) {
|
||||
r = VerifyEoln(&p);
|
||||
}
|
||||
break;
|
||||
case T_Preserve: r=DoPreserve(&p); break;
|
||||
case T_Expr: r = DoExpr(&p); break;
|
||||
case T_Translate: r = DoTranslate(&p); break;
|
||||
|
||||
@@ -30,8 +30,8 @@
|
||||
#define E_CANT_PARSE_WKDAY 8
|
||||
#define E_NO_MEM 9
|
||||
#define E_BAD_NUMBER 10
|
||||
/* #define E_OP_STK_UNDER 11 */
|
||||
/* #define E_VA_STK_UNDER 12 */
|
||||
#define E_PUSHSV_NO_POP 11
|
||||
#define E_POPSV_NO_PUSH 12
|
||||
#define E_CANT_COERCE 13
|
||||
#define E_BAD_TYPE 14
|
||||
#define E_DATE_OVER 15
|
||||
@@ -158,8 +158,8 @@ EXTERN char *ErrMsg[]
|
||||
/* E_CANT_PARSE_WKDAY*/ "Invalid weekday name",
|
||||
/* E_NO_MEM */ "Out of memory",
|
||||
/* E_BAD_NUMBER */ "Ill-formed number",
|
||||
/* E_OP_STK_UNDER */ "",
|
||||
/* E_VA_STK_UNDER */ "",
|
||||
/* E_PUSHSV_NO_POP */ "Warning: PUSH-SYSVARS without matching POP-SYSVARS",
|
||||
/* E_POPSV_NO_PUSH */ "POP-SYSVARS without matching PUSH-SYSVARS",
|
||||
/* E_CANT_COERCE */ "Can't coerce",
|
||||
/* E_BAD_TYPE */ "Type mismatch",
|
||||
/* E_DATE_OVER */ "Date overflow",
|
||||
|
||||
21
src/main.c
21
src/main.c
@@ -181,8 +181,14 @@ int main(int argc, char *argv[])
|
||||
}
|
||||
|
||||
if (!Hush) {
|
||||
if (DestroyOmitContexts(1))
|
||||
if (DestroyOmitContexts(1)) {
|
||||
FreshLine = 1;
|
||||
Eprint("%s", GetErr(E_PUSH_NOPOP));
|
||||
}
|
||||
if (EmptySysvarStack()) {
|
||||
FreshLine = 1;
|
||||
Eprint("%s", GetErr(E_PUSHSV_NO_POP));
|
||||
}
|
||||
if (!Daemon && !NextMode && !NumTriggered && !NumQueued) {
|
||||
printf("%s\n", GetErr(E_NOREMINDERS));
|
||||
} else if (!Daemon && !NextMode && !NumTriggered) {
|
||||
@@ -235,6 +241,7 @@ PerIterationInit(void)
|
||||
{
|
||||
ClearGlobalOmits();
|
||||
DestroyOmitContexts(1);
|
||||
EmptySysvarStack();
|
||||
DestroyVars(0);
|
||||
DefaultColorR = -1;
|
||||
DefaultColorG = -1;
|
||||
@@ -366,6 +373,18 @@ static void DoReminders(void)
|
||||
case T_Pop: r=PopOmitContext(&p); break;
|
||||
case T_Preserve: r=DoPreserve(&p); break;
|
||||
case T_Push: r=PushOmitContext(&p); break;
|
||||
case T_PushSysvars:
|
||||
r=PushSysvars();
|
||||
if (r == OK) {
|
||||
r = VerifyEoln(&p);
|
||||
}
|
||||
break;
|
||||
case T_PopSysvars:
|
||||
r=PopSysvars();
|
||||
if (r == OK) {
|
||||
r = VerifyEoln(&p);
|
||||
}
|
||||
break;
|
||||
case T_Expr: r = DoExpr(&p); break;
|
||||
case T_Translate: r = DoTranslate(&p); break;
|
||||
case T_RemType: if (tok.val == RUN_TYPE) {
|
||||
|
||||
@@ -121,12 +121,9 @@ int PushOmitContext(ParsePtr p)
|
||||
context = NEW(OmitContext);
|
||||
if (!context) return E_NO_MEM;
|
||||
|
||||
if (GetCurrentFilename()) {
|
||||
context->filename = GetCurrentFilename();
|
||||
} else {
|
||||
context->filename = "";
|
||||
}
|
||||
context->filename = GetCurrentFilename();
|
||||
context->lineno = LineNo;
|
||||
|
||||
context->numfull = NumFullOmits;
|
||||
context->numpart = NumPartialOmits;
|
||||
context->weekdaysave = WeekdayOmits;
|
||||
|
||||
@@ -147,6 +147,9 @@ int SetVar (char const *str, Value const *val, int nonconst_expr);
|
||||
int DoSet (Parser *p);
|
||||
int DoUnset (Parser *p);
|
||||
int DoDump (ParsePtr p);
|
||||
int PushSysvars(void);
|
||||
int EmptySysvarStack(void);
|
||||
int PopSysvars(void);
|
||||
void DumpVarTable (int dump_constness);
|
||||
void DumpUnusedVars(void);
|
||||
void DestroyVars (int all);
|
||||
|
||||
@@ -91,11 +91,13 @@ Token TokArray[] = {
|
||||
{ "omitfunc", 8, T_OmitFunc, 0 },
|
||||
{ "once", 4, T_Once, 0 },
|
||||
{ "pop-omit-context", 3, T_Pop, 0 },
|
||||
{ "pop-sysvars", 11, T_PopSysvars, 0 },
|
||||
{ "preserve", 8, T_Preserve, 0 },
|
||||
{ "priority", 8, T_Priority, 0 },
|
||||
{ "ps", 2, T_RemType, PS_TYPE },
|
||||
{ "psfile", 6, T_RemType, PSF_TYPE },
|
||||
{ "push-omit-context", 4, T_Push, 0 },
|
||||
{ "push-sysvars", 12, T_PushSysvars, 0 },
|
||||
{ "rem", 3, T_Rem, 0 },
|
||||
{ "run", 3, T_RemType, RUN_TYPE },
|
||||
{ "satisfy", 7, T_RemType, SAT_TYPE },
|
||||
|
||||
21
src/types.h
21
src/types.h
@@ -228,13 +228,14 @@ enum TokTypes
|
||||
{ T_Illegal,
|
||||
T_AddOmit, T_At, T_Back, T_BackAdj, T_Banner, T_Clr, T_Comment,
|
||||
T_Date, T_DateTime, T_Day, T_Debug, T_Delta, T_Dumpvars, T_Duration,
|
||||
T_Else, T_Empty, T_EndIf, T_ErrMsg, T_Exit, T_Expr,
|
||||
T_Flush, T_Frename, T_Fset, T_Funset, T_If, T_IfTrig, T_In,
|
||||
T_Include, T_IncludeCmd, T_IncludeR, T_IncludeSys, T_Info, T_LastBack,
|
||||
T_LongTime, T_MaybeUncomputable, T_Month, T_NoQueue, T_Number, T_Omit,
|
||||
T_OmitFunc, T_Once, T_Ordinal, T_Pop, T_Preserve, T_Priority, T_Push,T_Rem,
|
||||
T_RemType, T_Rep, T_Scanfrom, T_Sched, T_Set, T_Skip, T_Tag, T_Through,
|
||||
T_Time, T_Translate, T_UnSet, T_Until, T_Warn, T_WkDay, T_Year
|
||||
T_Else, T_Empty, T_EndIf, T_ErrMsg, T_Exit, T_Expr, T_Flush,
|
||||
T_Frename, T_Fset, T_Funset, T_If, T_IfTrig, T_In, T_Include,
|
||||
T_IncludeCmd, T_IncludeR, T_IncludeSys, T_Info, T_LastBack,
|
||||
T_LongTime, T_MaybeUncomputable, T_Month, T_NoQueue, T_Number,
|
||||
T_Omit, T_OmitFunc, T_Once, T_Ordinal, T_Pop, T_PopSysvars,
|
||||
T_Preserve, T_Priority, T_Push, T_PushSysvars, T_Rem, T_RemType,
|
||||
T_Rep, T_Scanfrom, T_Sched, T_Set, T_Skip, T_Tag, T_Through, T_Time,
|
||||
T_Translate, T_UnSet, T_Until, T_Warn, T_WkDay, T_Year
|
||||
};
|
||||
|
||||
/* The structure of a token */
|
||||
@@ -311,3 +312,9 @@ typedef struct udf_struct {
|
||||
int lineno_start;
|
||||
int recurse_flag;
|
||||
} UserFunc;
|
||||
|
||||
/* A pushed systtem variable */
|
||||
typedef struct {
|
||||
char const *name;
|
||||
Value v;
|
||||
} PushedSysvar;
|
||||
|
||||
85
src/var.c
85
src/var.c
@@ -1079,6 +1079,91 @@ static SysVar SysVarArr[] = {
|
||||
};
|
||||
|
||||
#define NUMSYSVARS ( sizeof(SysVarArr) / sizeof(SysVar) )
|
||||
static size_t NumPushableSysvars = 0;
|
||||
|
||||
struct pushed_sysvars {
|
||||
struct pushed_sysvars *next;
|
||||
char const *filename;
|
||||
int lineno;
|
||||
PushedSysvar *vars;
|
||||
};
|
||||
|
||||
static struct pushed_sysvars *SysvarStack = NULL;
|
||||
|
||||
static size_t CountPushableSysvars(void)
|
||||
{
|
||||
if (NumPushableSysvars != 0) return NumPushableSysvars;
|
||||
size_t i;
|
||||
for (i=0; i<NUMSYSVARS; i++) {
|
||||
if (SysVarArr[i].modifiable) {
|
||||
NumPushableSysvars++;
|
||||
}
|
||||
}
|
||||
return NumPushableSysvars;
|
||||
}
|
||||
|
||||
int PushSysvars(void)
|
||||
{
|
||||
size_t i, j;
|
||||
struct pushed_sysvars *ps = NEW(struct pushed_sysvars);
|
||||
if (!ps) return E_NO_MEM;
|
||||
|
||||
ps->filename = GetCurrentFilename();
|
||||
ps->lineno = LineNo;
|
||||
|
||||
ps->next = SysvarStack;
|
||||
ps->vars = calloc(CountPushableSysvars(), sizeof(PushedSysvar));
|
||||
if (!ps->vars) {
|
||||
free(ps);
|
||||
return E_NO_MEM;
|
||||
}
|
||||
|
||||
j = 0;
|
||||
for (i=0; i<NUMSYSVARS; i++) {
|
||||
if (SysVarArr[i].modifiable) {
|
||||
ps->vars[j].name = SysVarArr[i].name;
|
||||
(void) GetSysVar(ps->vars[j].name, &(ps->vars[j].v));
|
||||
/* fprintf(ErrFp, "push($%s) => %s\n", ps->vars[j].name, PrintValue(&(ps->vars[j].v), NULL)); */
|
||||
j++;
|
||||
}
|
||||
}
|
||||
SysvarStack = ps;
|
||||
return OK;
|
||||
}
|
||||
|
||||
int PopSysvars(void)
|
||||
{
|
||||
if (!SysvarStack) {
|
||||
return E_POPSV_NO_PUSH;
|
||||
}
|
||||
size_t n = CountPushableSysvars();
|
||||
size_t i;
|
||||
struct pushed_sysvars *ps = SysvarStack;
|
||||
|
||||
if (strcmp(ps->filename, GetCurrentFilename())) {
|
||||
Wprint(tr("POP-SYSVARS at %s:%d matches PUSH-SYSVARS in different file: %s:%d"), GetCurrentFilename(), LineNo, ps->filename, ps->lineno);
|
||||
}
|
||||
SysvarStack = ps->next;
|
||||
for (i=0; i<n; i++) {
|
||||
/* fprintf(ErrFp, "pop($%s) => %s\n", ps->vars[i].name, PrintValue(&(ps->vars[i].v), NULL)); */
|
||||
(void) SetSysVar(ps->vars[i].name, &(ps->vars[i].v));
|
||||
DestroyValue(ps->vars[i].v);
|
||||
}
|
||||
free(ps->vars);
|
||||
free(ps);
|
||||
return OK;
|
||||
}
|
||||
|
||||
int EmptySysvarStack(void)
|
||||
{
|
||||
int j=0;
|
||||
while(SysvarStack) {
|
||||
j++;
|
||||
PopSysvars();
|
||||
}
|
||||
return j;
|
||||
}
|
||||
|
||||
static void DumpSysVar (char const *name, const SysVar *v);
|
||||
|
||||
static int SetTranslatableVariable(SysVar const *v, Value const *value)
|
||||
|
||||
1679
tests/test.cmp
1679
tests/test.cmp
File diff suppressed because one or more lines are too long
@@ -272,7 +272,7 @@ set $LatDeg 30
|
||||
set $LatMin 30
|
||||
set $LatSec 0
|
||||
set $LongDeg -25
|
||||
set $LongMin 15
|
||||
set $LongMin -15
|
||||
set $LongSec 0
|
||||
|
||||
set a000 abs(1)
|
||||
@@ -478,6 +478,12 @@ REM MAYBE-UNCOMPUTABLE Mon OMIT Mon SKIP MSG Never ever ever...
|
||||
REM MAYBE-UNCOMPUTABLE Mon SATISFY [wkdaynum($T) == 3] MSG Nope nope...
|
||||
|
||||
dump
|
||||
PUSH-SYSVARS
|
||||
set $Tomorrow "HAHA, tomorrow"
|
||||
set $Latitude "0"
|
||||
set $DefaultColor "42 42 42"
|
||||
dump $
|
||||
POP-SYSVARS
|
||||
dump $
|
||||
msg [$April]%
|
||||
msg [$August]%
|
||||
|
||||
Reference in New Issue
Block a user