mirror of
https://salsa.debian.org/dskoll/remind.git
synced 2026-04-17 23:08:40 +02:00
Add catcherr() built-in function.
This commit is contained in:
@@ -164,7 +164,7 @@
|
|||||||
(defconst remind-builtin-functions
|
(defconst remind-builtin-functions
|
||||||
(sort
|
(sort
|
||||||
(list "_" "abs" "access" "adawn" "adusk" "ampm" "ansicolor" "args" "asc"
|
(list "_" "abs" "access" "adawn" "adusk" "ampm" "ansicolor" "args" "asc"
|
||||||
"baseyr" "catch" "char" "choose" "coerce" "columns" "current" "date"
|
"baseyr" "catch" "catcherr" "char" "choose" "coerce" "columns" "current" "date"
|
||||||
"datepart" "datetime" "dawn" "day" "daysinmon" "defined" "dosubst"
|
"datepart" "datetime" "dawn" "day" "daysinmon" "defined" "dosubst"
|
||||||
"dusk" "easterdate" "escape" "evaltrig" "filedate" "filedatetime"
|
"dusk" "easterdate" "escape" "evaltrig" "filedate" "filedatetime"
|
||||||
"filedir" "filename" "getenv" "hebdate" "hebday" "hebmon" "hebyear"
|
"filedir" "filename" "getenv" "hebdate" "hebday" "hebmon" "hebyear"
|
||||||
|
|||||||
@@ -3288,6 +3288,29 @@ Note in the last example that catch does \fInot\fR protect you from errors
|
|||||||
in the evaluation of \fBarg2\fR.
|
in the evaluation of \fBarg2\fR.
|
||||||
.RE
|
.RE
|
||||||
.TP
|
.TP
|
||||||
|
.B catcherr()
|
||||||
|
Returns a string representing the error message from the most
|
||||||
|
recently-evaluated \fBcatch()\fR function whose first argument yielded
|
||||||
|
an error. Note that the error message is always in English even if
|
||||||
|
\fBRemind\fR has been localized; this lets you reliably test the return
|
||||||
|
value. Here are some examples:
|
||||||
|
.RS
|
||||||
|
.PP
|
||||||
|
.nf
|
||||||
|
# No "catch" invocations yet: sets a to "Ok"
|
||||||
|
set a catcherr()
|
||||||
|
|
||||||
|
# Sets b to "oops" and a to "Division by zero"
|
||||||
|
set b catch(1/0, "oops")
|
||||||
|
set a catcherr()
|
||||||
|
|
||||||
|
# Sets b to 1 and a to "Division by zero". The catch error
|
||||||
|
# is never cleared by a non-error catch()
|
||||||
|
set b catch(4-3, "not-evaluated")
|
||||||
|
set a catcherr()
|
||||||
|
.fi
|
||||||
|
.RE
|
||||||
|
.TP
|
||||||
.B char(i_i1 [,i_i2...])
|
.B char(i_i1 [,i_i2...])
|
||||||
This function can take any number of \fBINT\fR arguments. It returns
|
This function can take any number of \fBINT\fR arguments. It returns
|
||||||
a \fBSTRING\fR consisting of the bytes specified by the arguments.
|
a \fBSTRING\fR consisting of the bytes specified by the arguments.
|
||||||
|
|||||||
21
src/funcs.c
21
src/funcs.c
@@ -64,6 +64,9 @@
|
|||||||
#define PUT(x) DBufPuts(&DebugBuf, x)
|
#define PUT(x) DBufPuts(&DebugBuf, x)
|
||||||
#define OUT() do { fprintf(ErrFp, "%s\n", DBufValue(&DebugBuf)); DBufFree(&DebugBuf); } while(0)
|
#define OUT() do { fprintf(ErrFp, "%s\n", DBufValue(&DebugBuf)); DBufFree(&DebugBuf); } while(0)
|
||||||
|
|
||||||
|
/* Last error from catch() */
|
||||||
|
static int LastCatchError = OK;
|
||||||
|
|
||||||
static int
|
static int
|
||||||
solstice_equinox_for_year(int y, int which);
|
solstice_equinox_for_year(int y, int which);
|
||||||
|
|
||||||
@@ -79,6 +82,7 @@ static int FArgs (func_info *);
|
|||||||
static int FAsc (func_info *);
|
static int FAsc (func_info *);
|
||||||
static int FBaseyr (func_info *);
|
static int FBaseyr (func_info *);
|
||||||
static int FCatch (expr_node *, Value *, Value *, int *);
|
static int FCatch (expr_node *, Value *, Value *, int *);
|
||||||
|
static int FCatchErr (func_info *);
|
||||||
static int FChar (func_info *);
|
static int FChar (func_info *);
|
||||||
static int FChoose (expr_node *, Value *, Value *, int *);
|
static int FChoose (expr_node *, Value *, Value *, int *);
|
||||||
static int FCoerce (func_info *);
|
static int FCoerce (func_info *);
|
||||||
@@ -245,6 +249,7 @@ BuiltinFunc Func[] = {
|
|||||||
{ "asc", 1, 1, 1, FAsc, NULL },
|
{ "asc", 1, 1, 1, FAsc, NULL },
|
||||||
{ "baseyr", 0, 0, 1, FBaseyr, NULL },
|
{ "baseyr", 0, 0, 1, FBaseyr, NULL },
|
||||||
{ "catch", 2, 2, 1, NULL, FCatch }, /* NEW-STYLE */
|
{ "catch", 2, 2, 1, NULL, FCatch }, /* NEW-STYLE */
|
||||||
|
{ "catcherr", 0, 0, 0, FCatchErr, NULL },
|
||||||
{ "char", 1, NO_MAX, 1, FChar, NULL },
|
{ "char", 1, NO_MAX, 1, FChar, NULL },
|
||||||
{ "choose", 2, NO_MAX, 1, NULL, FChoose }, /*NEW-STYLE*/
|
{ "choose", 2, NO_MAX, 1, NULL, FChoose }, /*NEW-STYLE*/
|
||||||
{ "coerce", 2, 2, 1, FCoerce, NULL },
|
{ "coerce", 2, 2, 1, FCoerce, NULL },
|
||||||
@@ -1320,6 +1325,9 @@ static int FCatch(expr_node *node, Value *locals, Value *ans, int *nonconst)
|
|||||||
}
|
}
|
||||||
return r;
|
return r;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Save the catch error */
|
||||||
|
LastCatchError = r;
|
||||||
if (DebugFlag & DB_PRTEXPR) {
|
if (DebugFlag & DB_PRTEXPR) {
|
||||||
PUT("*");
|
PUT("*");
|
||||||
PUT(GetErr(r));
|
PUT(GetErr(r));
|
||||||
@@ -1344,6 +1352,19 @@ static int FCatch(expr_node *node, Value *locals, Value *ans, int *nonconst)
|
|||||||
}
|
}
|
||||||
return r;
|
return r;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/***************************************************************/
|
||||||
|
/* */
|
||||||
|
/* FCatchErr */
|
||||||
|
/* Return (as a string) the English error thrown by the last */
|
||||||
|
/* catch() expression that errored out. */
|
||||||
|
/* */
|
||||||
|
/***************************************************************/
|
||||||
|
static int FCatchErr(func_info *info)
|
||||||
|
{
|
||||||
|
return RetStrVal(GetEnglishErr(LastCatchError), info);
|
||||||
|
}
|
||||||
|
|
||||||
/***************************************************************/
|
/***************************************************************/
|
||||||
/* */
|
/* */
|
||||||
/* FChoose */
|
/* FChoose */
|
||||||
|
|||||||
@@ -2138,6 +2138,14 @@ int GetOnceDate(void)
|
|||||||
return OnceDate;
|
return OnceDate;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
char const *GetEnglishErr(int r)
|
||||||
|
{
|
||||||
|
if (r < 0 || r >= NumErrs) {
|
||||||
|
r = E_SWERR;
|
||||||
|
}
|
||||||
|
return ErrMsg[r];
|
||||||
|
}
|
||||||
|
|
||||||
char const *GetErr(int r)
|
char const *GetErr(int r)
|
||||||
{
|
{
|
||||||
char const *msg;
|
char const *msg;
|
||||||
|
|||||||
@@ -271,6 +271,7 @@ void InitTranslationTable(void);
|
|||||||
char const *GetTranslatedString(char const *orig);
|
char const *GetTranslatedString(char const *orig);
|
||||||
int GetTranslatedStringTryingVariants(char const *orig, DynamicBuffer *out);
|
int GetTranslatedStringTryingVariants(char const *orig, DynamicBuffer *out);
|
||||||
char const *GetErr(int r);
|
char const *GetErr(int r);
|
||||||
|
char const *GetEnglishErr(int r);
|
||||||
char const *tr(char const *s);
|
char const *tr(char const *s);
|
||||||
void print_escaped_string(FILE *fp, char const *s);
|
void print_escaped_string(FILE *fp, char const *s);
|
||||||
void print_escaped_string_helper(FILE *fp, char const *s, int esc_for_remind, int json);
|
void print_escaped_string_helper(FILE *fp, char const *s, int esc_for_remind, int json);
|
||||||
|
|||||||
@@ -16256,27 +16256,39 @@ D'oh, a file whose name has spaces! ../tests/with space.rem
|
|||||||
|
|
||||||
DEBUG +x
|
DEBUG +x
|
||||||
# Test catch() built-in function
|
# Test catch() built-in function
|
||||||
|
set m catcherr()
|
||||||
|
catcherr() => "Ok"
|
||||||
set a catch(4/2, 33)
|
set a catch(4/2, 33)
|
||||||
4 / 2 => 2
|
4 / 2 => 2
|
||||||
catch(2, ?) => 2
|
catch(2, ?) => 2
|
||||||
|
set m catcherr()
|
||||||
|
catcherr() => "Ok"
|
||||||
set a catch(4/0, 33)
|
set a catch(4/0, 33)
|
||||||
4 / 0 => Division by zero
|
4 / 0 => Division by zero
|
||||||
catch(*Division by zero*, 33) => 33
|
catch(*Division by zero*, 33) => 33
|
||||||
|
set m catcherr()
|
||||||
|
catcherr() => "Division by zero"
|
||||||
set a catch(4/0, 1/0)
|
set a catch(4/0, 1/0)
|
||||||
4 / 0 => Division by zero
|
4 / 0 => Division by zero
|
||||||
1 / 0 => Division by zero
|
1 / 0 => Division by zero
|
||||||
../tests/test.rem(1444): `/': Division by zero
|
../tests/test.rem(1447): `/': Division by zero
|
||||||
catch(*Division by zero*, *Division by zero*) => Division by zero
|
catch(*Division by zero*, *Division by zero*) => Division by zero
|
||||||
|
set m catcherr()
|
||||||
|
catcherr() => "Division by zero"
|
||||||
set a catch(catch(4/0, 1/0), 39)
|
set a catch(catch(4/0, 1/0), 39)
|
||||||
4 / 0 => Division by zero
|
4 / 0 => Division by zero
|
||||||
1 / 0 => Division by zero
|
1 / 0 => Division by zero
|
||||||
catch(*Division by zero*, *Division by zero*) => Division by zero
|
catch(*Division by zero*, *Division by zero*) => Division by zero
|
||||||
catch(*Division by zero*, 39) => 39
|
catch(*Division by zero*, 39) => 39
|
||||||
|
set m catcherr()
|
||||||
|
catcherr() => "Division by zero"
|
||||||
set a catch(4/0, catch(4/0, 39))
|
set a catch(4/0, catch(4/0, 39))
|
||||||
4 / 0 => Division by zero
|
4 / 0 => Division by zero
|
||||||
4 / 0 => Division by zero
|
4 / 0 => Division by zero
|
||||||
catch(*Division by zero*, 39) => 39
|
catch(*Division by zero*, 39) => 39
|
||||||
catch(*Division by zero*, 39) => 39
|
catch(*Division by zero*, 39) => 39
|
||||||
|
set m catcherr()
|
||||||
|
catcherr() => "Division by zero"
|
||||||
set a catch(1/0, catch("f" * "g", catch($IntMin*88, 42)))
|
set a catch(1/0, catch("f" * "g", catch($IntMin*88, 42)))
|
||||||
1 / 0 => Division by zero
|
1 / 0 => Division by zero
|
||||||
"f" * "g" => Type mismatch
|
"f" * "g" => Type mismatch
|
||||||
@@ -16285,10 +16297,12 @@ $IntMin => -2147483648
|
|||||||
catch(*Number too high*, 42) => 42
|
catch(*Number too high*, 42) => 42
|
||||||
catch(*Type mismatch*, 42) => 42
|
catch(*Type mismatch*, 42) => 42
|
||||||
catch(*Division by zero*, 42) => 42
|
catch(*Division by zero*, 42) => 42
|
||||||
|
set m catcherr()
|
||||||
|
catcherr() => "Number too high"
|
||||||
DEBUG -x
|
DEBUG -x
|
||||||
DEBUG -e
|
DEBUG -e
|
||||||
Variable hash table statistics:
|
Variable hash table statistics:
|
||||||
Entries: 100141; Buckets: 87719; Non-empty Buckets: 66299
|
Entries: 100142; Buckets: 87719; Non-empty Buckets: 66300
|
||||||
Maxlen: 5; Minlen: 0; Avglen: 1.142; Stddev: 0.878; Avg nonempty len: 1.510
|
Maxlen: 5; Minlen: 0; Avglen: 1.142; Stddev: 0.878; Avg nonempty len: 1.510
|
||||||
Growths: 13; Shrinks: 0
|
Growths: 13; Shrinks: 0
|
||||||
Function hash table statistics:
|
Function hash table statistics:
|
||||||
@@ -24110,6 +24124,7 @@ args
|
|||||||
asc
|
asc
|
||||||
baseyr
|
baseyr
|
||||||
catch
|
catch
|
||||||
|
catcherr
|
||||||
char
|
char
|
||||||
choose
|
choose
|
||||||
coerce
|
coerce
|
||||||
|
|||||||
@@ -1439,12 +1439,19 @@ do "with space.rem"
|
|||||||
|
|
||||||
DEBUG +x
|
DEBUG +x
|
||||||
# Test catch() built-in function
|
# Test catch() built-in function
|
||||||
|
set m catcherr()
|
||||||
set a catch(4/2, 33)
|
set a catch(4/2, 33)
|
||||||
|
set m catcherr()
|
||||||
set a catch(4/0, 33)
|
set a catch(4/0, 33)
|
||||||
|
set m catcherr()
|
||||||
set a catch(4/0, 1/0)
|
set a catch(4/0, 1/0)
|
||||||
|
set m catcherr()
|
||||||
set a catch(catch(4/0, 1/0), 39)
|
set a catch(catch(4/0, 1/0), 39)
|
||||||
|
set m catcherr()
|
||||||
set a catch(4/0, catch(4/0, 39))
|
set a catch(4/0, catch(4/0, 39))
|
||||||
|
set m catcherr()
|
||||||
set a catch(1/0, catch("f" * "g", catch($IntMin*88, 42)))
|
set a catch(1/0, catch("f" * "g", catch($IntMin*88, 42)))
|
||||||
|
set m catcherr()
|
||||||
DEBUG -x
|
DEBUG -x
|
||||||
DEBUG -e
|
DEBUG -e
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user