mirror of
https://salsa.debian.org/dskoll/remind.git
synced 2026-04-17 14:59:20 +02:00
Make CallFunc and built-in functions re-entrant.
This commit is contained in:
44
src/expr.c
44
src/expr.c
@@ -72,9 +72,7 @@ Operator UnOp[] = {
|
||||
};
|
||||
#define NUM_UN_OPS (sizeof(UnOp) / sizeof(Operator))
|
||||
|
||||
/* Functions have the same definitions as operators, except the prec field
|
||||
is used to indicate how many arguments are needed. */
|
||||
extern Operator Func[];
|
||||
extern BuiltinFunc Func[];
|
||||
|
||||
Operator OpStack[OP_STACK_SIZE];
|
||||
Value ValStack[VAL_STACK_SIZE];
|
||||
@@ -332,7 +330,8 @@ int Evaluate(char const **s, Var *locals)
|
||||
{
|
||||
int OpBase, ValBase;
|
||||
int r;
|
||||
Operator *f;
|
||||
Operator *o;
|
||||
BuiltinFunc *f;
|
||||
int args; /* Number of function arguments */
|
||||
Operator op, op2;
|
||||
Value va;
|
||||
@@ -409,10 +408,10 @@ int Evaluate(char const **s, Var *locals)
|
||||
if (r) return r;
|
||||
}
|
||||
} else { /* Unary operator */
|
||||
f = FindFunc(DBufValue(&ExprBuf), UnOp, NUM_UN_OPS);
|
||||
if (f) {
|
||||
o = FindOperator(DBufValue(&ExprBuf), UnOp, NUM_UN_OPS);
|
||||
if (o) {
|
||||
DBufFree(&ExprBuf);
|
||||
PushOpStack(*f);
|
||||
PushOpStack(*o);
|
||||
continue; /* Still looking for an atomic vlue */
|
||||
} else if (!ISID(*DBufValue(&ExprBuf)) &&
|
||||
*DBufValue(&ExprBuf) != '$' &&
|
||||
@@ -458,13 +457,13 @@ int Evaluate(char const **s, Var *locals)
|
||||
return OK;
|
||||
}
|
||||
/* Must be a binary operator */
|
||||
f = FindFunc(DBufValue(&ExprBuf), BinOp, NUM_BIN_OPS);
|
||||
o = FindOperator(DBufValue(&ExprBuf), BinOp, NUM_BIN_OPS);
|
||||
DBufFree(&ExprBuf);
|
||||
if (!f) return E_EXPECTING_BINOP;
|
||||
if (!o) return E_EXPECTING_BINOP;
|
||||
|
||||
/* While operators of higher or equal precedence are on the stack,
|
||||
pop them off and evaluate */
|
||||
while (OpStackPtr > OpBase && OpStack[OpStackPtr-1].prec >= f->prec) {
|
||||
while (OpStackPtr > OpBase && OpStack[OpStackPtr-1].prec >= o->prec) {
|
||||
PopOpStack(op2);
|
||||
if (r) return r;
|
||||
if (DebugFlag & DB_PRTEXPR)
|
||||
@@ -476,7 +475,7 @@ int Evaluate(char const **s, Var *locals)
|
||||
return r;
|
||||
}
|
||||
}
|
||||
PushOpStack(*f);
|
||||
PushOpStack(*o);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1125,7 +1124,28 @@ static int LogNot(void)
|
||||
/* Find a function. */
|
||||
/* */
|
||||
/***************************************************************/
|
||||
Operator *FindFunc(char const *name, Operator where[], int num)
|
||||
Operator *FindOperator(char const *name, Operator where[], int num)
|
||||
{
|
||||
int top=num-1, bot=0;
|
||||
int mid, r;
|
||||
while (top >= bot) {
|
||||
mid = (top + bot) / 2;
|
||||
r = StrCmpi(name, where[mid].name);
|
||||
if (!r) return &where[mid];
|
||||
else if (r > 0) bot = mid+1;
|
||||
else top = mid-1;
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/***************************************************************/
|
||||
/* */
|
||||
/* FindFunc */
|
||||
/* */
|
||||
/* Find a function. */
|
||||
/* */
|
||||
/***************************************************************/
|
||||
BuiltinFunc *FindFunc(char const *name, BuiltinFunc where[], int num)
|
||||
{
|
||||
int top=num-1, bot=0;
|
||||
int mid, r;
|
||||
|
||||
455
src/funcs.c
455
src/funcs.c
File diff suppressed because it is too large
Load Diff
@@ -43,7 +43,7 @@ int IncludeFile (char const *fname);
|
||||
int GetAccessDate (char const *file);
|
||||
int SetAccessDate (char const *fname, int jul);
|
||||
int TopLevel (void);
|
||||
int CallFunc (Operator *f, int nargs);
|
||||
int CallFunc (BuiltinFunc *f, int nargs);
|
||||
void InitRemind (int argc, char const *argv[]);
|
||||
void Usage (void);
|
||||
int Julian (int year, int month, int day);
|
||||
@@ -105,7 +105,8 @@ int DoMsgCommand (char const *cmd, char const *msg);
|
||||
int ParseNonSpaceChar (ParsePtr p, int *err, int peek);
|
||||
unsigned int HashVal (char const *str);
|
||||
int DateOK (int y, int m, int d);
|
||||
Operator *FindFunc (char const *name, Operator where[], int num);
|
||||
Operator *FindOperator (char const *name, Operator where[], int num);
|
||||
BuiltinFunc *FindFunc (char const *name, BuiltinFunc where[], int num);
|
||||
int InsertIntoSortBuffer (int jul, int tim, char const *body, int typ, int prio);
|
||||
void IssueSortedReminders (void);
|
||||
int UserFuncExists (char const *fn);
|
||||
|
||||
14
src/types.h
14
src/types.h
@@ -30,6 +30,20 @@ typedef struct {
|
||||
int (*func)(void);
|
||||
} Operator;
|
||||
|
||||
/* Structure for passing in Nargs and out RetVal from functions */
|
||||
typedef struct {
|
||||
int nargs;
|
||||
Value retval;
|
||||
} func_info;
|
||||
|
||||
/* Define the type of user-functions */
|
||||
typedef struct {
|
||||
char const *name;
|
||||
char minargs;
|
||||
char maxargs;
|
||||
int (*func)(func_info *);
|
||||
} BuiltinFunc;
|
||||
|
||||
/* Define the structure of a variable */
|
||||
typedef struct var {
|
||||
struct var *next;
|
||||
|
||||
@@ -40,7 +40,7 @@ static UserFunc *FuncHash[FUNC_HASH_SIZE];
|
||||
|
||||
/* Access to built-in functions */
|
||||
extern int NumFuncs;
|
||||
extern Operator Func[];
|
||||
extern BuiltinFunc Func[];
|
||||
|
||||
/* We need access to the expression evaluation stack */
|
||||
extern Value ValStack[];
|
||||
|
||||
Reference in New Issue
Block a user