?? ejparse.c
字號:
}
}
if (numeric) {
l = gatoi(lhs);
r = gatoi(rhs);
switch (rel) {
case EXPR_PLUS:
lval = l + r;
break;
case EXPR_INC:
lval = l + 1;
break;
case EXPR_MINUS:
lval = l - r;
break;
case EXPR_DEC:
lval = l - 1;
break;
case EXPR_MUL:
lval = l * r;
break;
case EXPR_DIV:
if (r != 0) {
lval = l / r;
} else {
lval = 0;
}
break;
case EXPR_MOD:
if (r != 0) {
lval = l % r;
} else {
lval = 0;
}
break;
case EXPR_LSHIFT:
lval = l << r;
break;
case EXPR_RSHIFT:
lval = l >> r;
break;
case EXPR_EQ:
lval = l == r;
break;
case EXPR_NOTEQ:
lval = l != r;
break;
case EXPR_LESS:
lval = (l < r) ? 1 : 0;
break;
case EXPR_LESSEQ:
lval = (l <= r) ? 1 : 0;
break;
case EXPR_GREATER:
lval = (l > r) ? 1 : 0;
break;
case EXPR_GREATEREQ:
lval = (l >= r) ? 1 : 0;
break;
case EXPR_BOOL_COMP:
lval = (r == 0) ? 1 : 0;
break;
default:
ejError(ep, T("Bad operator %d"), rel);
return -1;
}
} else {
switch (rel) {
case EXPR_PLUS:
clearString(&ep->result);
appendString(&ep->result, lhs);
appendString(&ep->result, rhs);
return 0;
case EXPR_LESS:
lval = gstrcmp(lhs, rhs) < 0;
break;
case EXPR_LESSEQ:
lval = gstrcmp(lhs, rhs) <= 0;
break;
case EXPR_GREATER:
lval = gstrcmp(lhs, rhs) > 0;
break;
case EXPR_GREATEREQ:
lval = gstrcmp(lhs, rhs) >= 0;
break;
case EXPR_EQ:
lval = gstrcmp(lhs, rhs) == 0;
break;
case EXPR_NOTEQ:
lval = gstrcmp(lhs, rhs) != 0;
break;
case EXPR_INC:
case EXPR_DEC:
case EXPR_MINUS:
case EXPR_DIV:
case EXPR_MOD:
case EXPR_LSHIFT:
case EXPR_RSHIFT:
default:
ejError(ep, T("Bad operator"));
return -1;
}
}
stritoa(lval, buf, sizeof(buf));
setString(B_L, &ep->result, buf);
return 0;
}
/******************************************************************************/
/*
* Evaluate a function
*/
static int evalFunction(ej_t *ep)
{
sym_t *sp;
int (*fn)(int eid, void *handle, int argc, char_t **argv);
if ((sp = symLookup(ep->functions, ep->func->fname)) == NULL) {
ejError(ep, T("Undefined procedure %s"), ep->func->fname);
return -1;
}
fn = (int (*)(int, void*, int, char_t**)) sp->content.value.integer;
if (fn == NULL) {
ejError(ep, T("Undefined procedure %s"), ep->func->fname);
return -1;
}
return (*fn)(ep->eid, (void*) ep->userHandle, ep->func->nArgs,
ep->func->args);
}
/******************************************************************************/
/*
* Output a parse ej_error message
*/
void ejError(ej_t* ep, char_t* fmt, ...)
{
va_list args;
ejinput_t *ip;
char_t *errbuf, *msgbuf;
a_assert(ep);
a_assert(fmt);
ip = ep->input;
va_start(args, fmt);
msgbuf = NULL;
fmtValloc(&msgbuf, E_MAX_ERROR, fmt, args);
va_end(args);
if (ep && ip) {
fmtAlloc(&errbuf, E_MAX_ERROR, T("%s\n At line %d, line => \n\n%s\n"),
msgbuf, ip->lineNumber, ip->line);
bfreeSafe(B_L, ep->error);
ep->error = errbuf;
}
bfreeSafe(B_L, msgbuf);
}
/******************************************************************************/
/*
* Clear a string value
*/
static void clearString(char_t **ptr)
{
a_assert(ptr);
if (*ptr) {
bfree(B_L, *ptr);
}
*ptr = NULL;
}
/******************************************************************************/
/*
* Set a string value
*/
static void setString(B_ARGS_DEC, char_t **ptr, char_t *s)
{
a_assert(ptr);
if (*ptr) {
bfree(B_ARGS, *ptr);
}
*ptr = bstrdup(B_ARGS, s);
}
/******************************************************************************/
/*
* Append to the pointer value
*/
static void appendString(char_t **ptr, char_t *s)
{
int len, oldlen;
a_assert(ptr);
if (*ptr) {
len = gstrlen(s);
oldlen = gstrlen(*ptr);
*ptr = brealloc(B_L, *ptr, (len + oldlen + 1) * sizeof(char_t));
gstrcpy(&(*ptr)[oldlen], s);
} else {
*ptr = bstrdup(B_L, s);
}
}
/******************************************************************************/
/*
* Define a function
*/
int ejSetGlobalFunction(int eid, char_t *name,
int (*fn)(int eid, void *handle, int argc, char_t **argv))
{
ej_t *ep;
if ((ep = ejPtr(eid)) == NULL) {
return -1;
}
return ejSetGlobalFunctionDirect(ep->functions, name, fn);
}
/******************************************************************************/
/*
* Define a function directly into the function symbol table.
*/
int ejSetGlobalFunctionDirect(sym_fd_t functions, char_t *name,
int (*fn)(int eid, void *handle, int argc, char_t **argv))
{
if (symEnter(functions, name, valueInteger((long) fn), 0) == NULL) {
return -1;
}
return 0;
}
/******************************************************************************/
/*
* Remove ("undefine") a function
*/
int ejRemoveGlobalFunction(int eid, char_t *name)
{
ej_t *ep;
if ((ep = ejPtr(eid)) == NULL) {
return -1;
}
return symDelete(ep->functions, name);
}
/******************************************************************************/
/*
* Get a function definition
*/
void *ejGetGlobalFunction(int eid, char_t *name)
{
ej_t *ep;
sym_t *sp;
int (*fn)(int eid, void *handle, int argc, char_t **argv);
if ((ep = ejPtr(eid)) == NULL) {
return NULL;
}
if ((sp = symLookup(ep->functions, name)) != NULL) {
fn = (int (*)(int, void*, int, char_t**)) sp->content.value.integer;
return (void*) fn;
}
return NULL;
}
/******************************************************************************/
/*
* Utility routine to crack Ejscript arguments. Return the number of args
* seen. This routine only supports %s and %d type args.
*
* Typical usage:
*
* if (ejArgs(argc, argv, "%s %d", &name, &age) < 2) {
* error("Insufficient args\n");
* return -1;
* }
*/
int ejArgs(int argc, char_t **argv, char_t *fmt, ...)
{
va_list vargs;
char_t *cp, **sp;
int *ip;
int argn;
va_start(vargs, fmt);
if (argv == NULL) {
return 0;
}
for (argn = 0, cp = fmt; cp && *cp && argv[argn]; ) {
if (*cp++ != '%') {
continue;
}
switch (*cp) {
case 'd':
ip = va_arg(vargs, int*);
*ip = gatoi(argv[argn]);
break;
case 's':
sp = va_arg(vargs, char_t**);
*sp = argv[argn];
break;
default:
/*
* Unsupported
*/
a_assert(0);
}
argn++;
}
va_end(vargs);
return argn;
}
/******************************************************************************/
/*
* Define the user handle
*/
void ejSetUserHandle(int eid, int handle)
{
ej_t *ep;
if ((ep = ejPtr(eid)) == NULL) {
return;
}
ep->userHandle = handle;
}
/******************************************************************************/
/*
* Get the user handle
*/
int ejGetUserHandle(int eid)
{
ej_t *ep;
if ((ep = ejPtr(eid)) == NULL) {
return -1;
}
return ep->userHandle;
}
/******************************************************************************/
/*
* Get the current line number
*/
int ejGetLineNumber(int eid)
{
ej_t *ep;
if ((ep = ejPtr(eid)) == NULL) {
return -1;
}
return ep->input->lineNumber;
}
/******************************************************************************/
/*
* Set the result
*/
void ejSetResult(int eid, char_t *s)
{
ej_t *ep;
if ((ep = ejPtr(eid)) == NULL) {
return;
}
setString(B_L, &ep->result, s);
}
/******************************************************************************/
/*
* Get the result
*/
char_t *ejGetResult(int eid)
{
ej_t *ep;
if ((ep = ejPtr(eid)) == NULL) {
return NULL;
}
return ep->result;
}
/******************************************************************************/
/*
* Set a variable. Note: a variable with a value of NULL means declared but
* undefined. The value is defined in the top-most variable frame.
*/
void ejSetVar(int eid, char_t *var, char_t *value)
{
ej_t *ep;
value_t v;
a_assert(var && *var);
if ((ep = ejPtr(eid)) == NULL) {
return;
}
if (value == NULL) {
v = valueString(value, 0);
} else {
v = valueString(value, VALUE_ALLOCATE);
}
symEnter(ep->variables[ep->variableMax - 1] - EJ_OFFSET, var, v, 0);
}
/******************************************************************************/
/*
* Set a local variable. Note: a variable with a value of NULL means
* declared but undefined. The value is defined in the top-most variable frame.
*/
void ejSetLocalVar(int eid, char_t *var, char_t *value)
{
ej_t *ep;
value_t v;
a_assert(var && *var);
if ((ep = ejPtr(eid)) == NULL) {
return;
}
if (value == NULL) {
v = valueString(value, 0);
} else {
v = valueString(value, VALUE_ALLOCATE);
}
symEnter(ep->variables[ep->variableMax - 1] - EJ_OFFSET, var, v, 0);
}
/******************************************************************************/
/*
* Set a global variable. Note: a variable with a value of NULL means
* declared but undefined. The value is defined in the global variable frame.
*/
void ejSetGlobalVar(int eid, char_t *var, char_t *value)
{
ej_t *ep;
value_t v;
a_assert(var && *var);
if ((ep = ejPtr(eid)) == NULL) {
return;
}
if (value == NULL) {
v = valueString(value, 0);
} else {
v = valueString(value, VALUE_ALLOCATE);
}
symEnter(ep->variables[0] - EJ_OFFSET, var, v, 0);
}
/******************************************************************************/
/*
* Get a variable
*/
int ejGetVar(int eid, char_t *var, char_t **value)
{
ej_t *ep;
sym_t *sp;
int i;
a_assert(var && *var);
a_assert(value);
if ((ep = ejPtr(eid)) == NULL) {
return -1;
}
i = ep->variableMax - 1;
if ((sp = symLookup(ep->variables[i] - EJ_OFFSET, var)) == NULL) {
i = 0;
if ((sp = symLookup(ep->variables[0] - EJ_OFFSET, var)) == NULL) {
return -1;
}
}
a_assert(sp->content.type == string);
*value = sp->content.value.string;
return i;
}
/******************************************************************************/
/*
* Get the variable symbol table
*/
sym_fd_t ejGetVariableTable(int eid)
{
ej_t *ep;
if ((ep = ejPtr(eid)) == NULL) {
return -1;
}
return *ep->variables;
}
/******************************************************************************/
/*
* Get the functions symbol table
*/
sym_fd_t ejGetFunctionTable(int eid)
{
ej_t *ep;
if ((ep = ejPtr(eid)) == NULL) {
return -1;
}
return ep->functions;
}
/******************************************************************************/
/*
* Free an argument list
*/
static void freeFunc(ejfunc_t *func)
{
int i;
for (i = func->nArgs - 1; i >= 0; i--) {
bfree(B_L, func->args[i]);
func->nArgs = hFree((void***) &func->args, i);
}
if (func->fname) {
bfree(B_L, func->fname);
func->fname = NULL;
}
}
/******************************************************************************/
/*
* Get Ejscript pointer
*/
static ej_t *ejPtr(int eid)
{
a_assert(0 <= eid && eid < ejMax);
if (eid < 0 || eid >= ejMax || ejHandles[eid] == NULL) {
ejError(NULL, T("Bad handle %d"), eid);
return NULL;
}
return ejHandles[eid];
}
/******************************************************************************/
/*
* This function removes any new lines. Used for else cases, etc.
*/
static void ejRemoveNewlines(ej_t *ep, int state)
{
int tid;
do {
tid = ejLexGetToken(ep, state);
} while (tid == TOK_NEWLINE);
ejLexPutbackToken(ep, tid, ep->token);
}
/******************************************************************************/
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -