mirror of
https://salsa.debian.org/dskoll/remind.git
synced 2026-04-17 23:08:40 +02:00
Convert "isany" to short-circuit evaluation.
This commit is contained in:
94
src/funcs.c
94
src/funcs.c
@@ -60,6 +60,9 @@
|
|||||||
#define RetVal (info->retval)
|
#define RetVal (info->retval)
|
||||||
|
|
||||||
#define DBG(x) do { if (DebugFlag & DB_PRTEXPR) { x; } } while(0)
|
#define DBG(x) do { if (DebugFlag & DB_PRTEXPR) { x; } } while(0)
|
||||||
|
/* Debugging helpers for "choose()", "iif(), etc. */
|
||||||
|
#define PUT(x) DBufPuts(&DebugBuf, x)
|
||||||
|
#define OUT() do { fprintf(ErrFp, "%s\n", DBufValue(&DebugBuf)); DBufFree(&DebugBuf); } while(0)
|
||||||
|
|
||||||
static int
|
static int
|
||||||
solstice_equinox_for_year(int y, int which);
|
solstice_equinox_for_year(int y, int which);
|
||||||
@@ -104,7 +107,7 @@ static int FHtmlEscape (func_info *);
|
|||||||
static int FHtmlStriptags (func_info *);
|
static int FHtmlStriptags (func_info *);
|
||||||
static int FIif (expr_node *, Value *, Value *, int *);
|
static int FIif (expr_node *, Value *, Value *, int *);
|
||||||
static int FIndex (func_info *);
|
static int FIndex (func_info *);
|
||||||
static int FIsAny (func_info *);
|
static int FIsAny (expr_node *, Value *, Value *, int *);
|
||||||
static int FIsdst (func_info *);
|
static int FIsdst (func_info *);
|
||||||
static int FIsleap (func_info *);
|
static int FIsleap (func_info *);
|
||||||
static int FIsomitted (func_info *);
|
static int FIsomitted (func_info *);
|
||||||
@@ -263,7 +266,7 @@ BuiltinFunc Func[] = {
|
|||||||
{ "htmlstriptags",1, 1, 1, FHtmlStriptags, NULL },
|
{ "htmlstriptags",1, 1, 1, FHtmlStriptags, NULL },
|
||||||
{ "iif", 1, NO_MAX, 1, NULL, FIif }, /*NEW-STYLE*/
|
{ "iif", 1, NO_MAX, 1, NULL, FIif }, /*NEW-STYLE*/
|
||||||
{ "index", 2, 3, 1, FIndex, NULL },
|
{ "index", 2, 3, 1, FIndex, NULL },
|
||||||
{ "isany", 1, NO_MAX, 1, FIsAny, NULL },
|
{ "isany", 1, NO_MAX, 1, NULL, FIsAny }, /*NEW-STYLE*/
|
||||||
{ "isdst", 0, 2, 0, FIsdst, NULL },
|
{ "isdst", 0, 2, 0, FIsdst, NULL },
|
||||||
{ "isleap", 1, 1, 1, FIsleap, NULL },
|
{ "isleap", 1, 1, 1, FIsleap, NULL },
|
||||||
{ "isomitted", 1, 1, 0, FIsomitted, NULL },
|
{ "isomitted", 1, 1, 0, FIsomitted, NULL },
|
||||||
@@ -376,10 +379,9 @@ static int RetStrVal(char const *s, func_info *info)
|
|||||||
/***************************************************************/
|
/***************************************************************/
|
||||||
static int FStrlen(func_info *info)
|
static int FStrlen(func_info *info)
|
||||||
{
|
{
|
||||||
Value *v = &ARG(0);
|
ASSERT_TYPE(0, STR_TYPE);
|
||||||
if (v->type != STR_TYPE) return E_BAD_TYPE;
|
|
||||||
RetVal.type = INT_TYPE;
|
RetVal.type = INT_TYPE;
|
||||||
size_t l = strlen(v->v.str);
|
size_t l = strlen(ARGSTR(0));
|
||||||
if (l > INT_MAX) return E_2HIGH;
|
if (l > INT_MAX) return E_2HIGH;
|
||||||
RETVAL = (int) l;
|
RETVAL = (int) l;
|
||||||
return OK;
|
return OK;
|
||||||
@@ -1034,8 +1036,8 @@ static int FOrd(func_info *info)
|
|||||||
/* */
|
/* */
|
||||||
/* FPad - Pad a string to min length */
|
/* FPad - Pad a string to min length */
|
||||||
/* */
|
/* */
|
||||||
/* pad("1", "0", 4) --> "0004" */
|
/* pad("1", "0", 4) --> "0001" */
|
||||||
/* pad("1", "0", 4, 1) --> "4000" */
|
/* pad("1", "0", 4, 1) --> "1000" */
|
||||||
/* pad("foo", "bar", 7) -> "barbfoo" */
|
/* pad("foo", "bar", 7) -> "barbfoo" */
|
||||||
/* */
|
/* */
|
||||||
/***************************************************************/
|
/***************************************************************/
|
||||||
@@ -1159,32 +1161,70 @@ static int FPlural(func_info *info)
|
|||||||
/* otherwise. */
|
/* otherwise. */
|
||||||
/* */
|
/* */
|
||||||
/***************************************************************/
|
/***************************************************************/
|
||||||
static int FIsAny(func_info *info)
|
static int FIsAny(expr_node *node, Value *locals, Value *ans, int *nonconst)
|
||||||
{
|
{
|
||||||
int i;
|
DynamicBuffer DebugBuf;
|
||||||
RetVal.type = INT_TYPE;
|
expr_node *cur;
|
||||||
RETVAL = 0;
|
int r;
|
||||||
for (i=1; i<Nargs; i++) {
|
|
||||||
if (ARG(0).type == ARG(i).type) {
|
Value v;
|
||||||
if (ARG(0).type == STR_TYPE) {
|
Value candidate;
|
||||||
if (!strcmp(ARGSTR(0), ARGSTR(i))) {
|
|
||||||
RETVAL = 1;
|
ans->type = INT_TYPE;
|
||||||
return OK;
|
ans->v.val = 0;
|
||||||
}
|
|
||||||
} else {
|
DBG(DBufInit(&DebugBuf));
|
||||||
if (ARGV(0) == ARGV(i)) {
|
DBG(PUT("isany("));
|
||||||
RETVAL = 1;
|
|
||||||
return OK;
|
cur = node->child;
|
||||||
}
|
r = evaluate_expr_node(cur, locals, &v, nonconst);
|
||||||
|
if (r != OK) {
|
||||||
|
DBG(DBufFree(&DebugBuf));
|
||||||
|
return r;
|
||||||
|
}
|
||||||
|
DBG(PUT(PrintValue(&v, NULL)));
|
||||||
|
while(cur->sibling) {
|
||||||
|
cur = cur->sibling;
|
||||||
|
r = evaluate_expr_node(cur, locals, &candidate, nonconst);
|
||||||
|
if (r != OK) {
|
||||||
|
DestroyValue(v);
|
||||||
|
DBG(DBufFree(&DebugBuf));
|
||||||
|
return r;
|
||||||
|
}
|
||||||
|
DBG(PUT(", "));
|
||||||
|
DBG(PUT(PrintValue(&candidate, NULL)));
|
||||||
|
if (candidate.type != v.type) {
|
||||||
|
DestroyValue(candidate);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
if (v.type == STR_TYPE) {
|
||||||
|
if (strcmp(v.v.str, candidate.v.str)) {
|
||||||
|
DestroyValue(candidate);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
if (v.v.val != candidate.v.val) {
|
||||||
|
DestroyValue(candidate);
|
||||||
|
continue;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
DestroyValue(candidate);
|
||||||
|
ans->v.val = 1;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
DestroyValue(v);
|
||||||
|
if (DebugFlag & DB_PRTEXPR) {
|
||||||
|
while(cur->sibling) {
|
||||||
|
cur = cur->sibling;
|
||||||
|
PUT(", ?");
|
||||||
|
}
|
||||||
|
PUT(") => ");
|
||||||
|
PUT(PrintValue(ans, NULL));
|
||||||
|
OUT();
|
||||||
}
|
}
|
||||||
return OK;
|
return OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Debugging helpers for "choose()" and "iif() */
|
|
||||||
#define PUT(x) DBufPuts(&DebugBuf, x)
|
|
||||||
#define OUT() do { fprintf(ErrFp, "%s\n", DBufValue(&DebugBuf)); DBufFree(&DebugBuf); } while(0)
|
|
||||||
/***************************************************************/
|
/***************************************************************/
|
||||||
/* */
|
/* */
|
||||||
/* FChoose */
|
/* FChoose */
|
||||||
@@ -1200,7 +1240,7 @@ static int FChoose(expr_node *node, Value *locals, Value *ans, int *nonconst)
|
|||||||
int r;
|
int r;
|
||||||
int n;
|
int n;
|
||||||
int nargs = node->num_kids;
|
int nargs = node->num_kids;
|
||||||
Value(v);
|
Value v;
|
||||||
DBG(DBufInit(&DebugBuf));
|
DBG(DBufInit(&DebugBuf));
|
||||||
DBG(PUT("choose("));
|
DBG(PUT("choose("));
|
||||||
|
|
||||||
|
|||||||
@@ -3779,11 +3779,11 @@ isany("foo", 2) => 0
|
|||||||
set a isany(1:00, 2)
|
set a isany(1:00, 2)
|
||||||
isany(01:00, 2) => 0
|
isany(01:00, 2) => 0
|
||||||
set a isany(1, 2, 1, 3)
|
set a isany(1, 2, 1, 3)
|
||||||
isany(1, 2, 1, 3) => 1
|
isany(1, 2, 1, ?) => 1
|
||||||
set a isany("foo", 2, 3, "foo")
|
set a isany("foo", 2, 3, "foo")
|
||||||
isany("foo", 2, 3, "foo") => 1
|
isany("foo", 2, 3, "foo") => 1
|
||||||
set a isany(1:00, 2, "foo", 2:00, 1:00, 9:00)
|
set a isany(1:00, 2, "foo", 2:00, 1:00, 9:00)
|
||||||
isany(01:00, 2, "foo", 02:00, 01:00, 09:00) => 1
|
isany(01:00, 2, "foo", 02:00, 01:00, ?) => 1
|
||||||
|
|
||||||
# Shellescape
|
# Shellescape
|
||||||
set a shellescape(" !\"#$%%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\\]^_`abcdefghijklmnopqrstuvwxyz{|}~")
|
set a shellescape(" !\"#$%%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\\]^_`abcdefghijklmnopqrstuvwxyz{|}~")
|
||||||
|
|||||||
Reference in New Issue
Block a user