static int charConvert(ej_t* ep, int base, int maxDig)
{
    int		i, c, lval, convChar;

    lval = 0;
    for (i = 0; i < maxDig; i++) {
        if ((c = inputGetc(ep)) < 0) {
            break;
        }
        /*
         *		Initialize to out of range value
         */
        convChar = base;
        if (gisdigit(c)) {
            convChar = c - '0';
        } else if (c >= 'a' && c <= 'f') {
            convChar = c - 'a' + 10;
        } else if (c >= 'A' && c <= 'F') {
            convChar = c - 'A' + 10;
        }
        /*
         *		if unexpected character then return it to buffer.
         */
        if (convChar >= base) {
            inputPutback(ep, c);
            break;
        }
        lval = (lval * base) + convChar;
    }
    return lval;
}
Exemple #2
0
static int evalCond(ej_t *ep, char_t *lhs, int rel, char_t *rhs)
{
	char_t	buf[16];
	int		l, r, lval;

	a_assert(lhs);
	a_assert(rhs);
	a_assert(rel > 0);

	lval = 0;
	if (gisdigit((int)*lhs) && gisdigit((int)*rhs)) {
		l = gatoi(lhs);
		r = gatoi(rhs);
		switch (rel) {
		case COND_AND:
			lval = l && r;
			break;
		case COND_OR:
			lval = l || r;
			break;
		default:
			ejError(ep, T("Bad operator %d"), rel);
			return -1;
		}
	} else {
		if (!gisdigit((int)*lhs)) {
			ejError(ep, T("Conditional must be numeric"), lhs);
		} else {
			ejError(ep, T("Conditional must be numeric"), rhs);
		}
	}

	stritoa(lval, buf, sizeof(buf));
	setString(B_L, &ep->result, buf);
	return 0;
}
Exemple #3
0
//----------------------------------------------------------------------------
// convert decimal/hexadecimal number to tUint32
//----------------------------------------------------------------------------
tUint32 xstrToUint32(tCChar* pIn)
{
  register tUint32 dwOut = 0;
 
  // handle hexadecimal format 0x.....
  if ((*pIn == '0') && ((*(pIn + 1) == 'x') || (*(pIn + 1) == 'X'))) {
    for (pIn += 2; gisxdigit(*pIn); pIn++) 
      dwOut = (dwOut * 16) + ((*pIn > '9') ? ((*pIn & 0x07) + 9) : (*pIn - '0'));
    } // if

  else {
    for ( ; gisdigit(*pIn); pIn++) 
      dwOut = (dwOut * 10) + (*pIn - '0');
    } // else

  return dwOut;
  } // xstrToUint32
Exemple #4
0
tUint32 xstrToUint32(tUint32& dwOut, tCChar* pIn)
{
  dwOut = 0;

  // handle hexadecimal format 0x.....
  if ((*pIn == '0') && ((*(pIn + 1) == 'x') || (*(pIn + 1) == 'X'))) {
    for (pIn += 2; gisxdigit(*pIn); pIn++) 
      dwOut = (dwOut * 16) + ((*pIn > '9') ? ((*pIn & 0x07) + 9) : (*pIn - '0'));
    } // if

  else {
    for ( ; gisdigit(*pIn); pIn++) 
      dwOut = (dwOut * 10) + (*pIn - '0');
    } // else

//  for (dwOut = 0; gisdigit(*pIn); pIn++) 
//    dwOut = (dwOut * 10) + (*pIn - '0');

  return (*pIn) ? XERROR_SYNTAX : XERROR_SUCCESS;
  } // xstrToUint32
Exemple #5
0
static int evalExpr(ej_t *ep, char_t *lhs, int rel, char_t *rhs)
{
	char_t	*cp, buf[16];
	int		numeric, l, r, lval;

	a_assert(lhs);
	a_assert(rhs);
	a_assert(rel > 0);

/*
 *	All of the characters in the lhs and rhs must be numeric
 */
	numeric = 1;
	for (cp = lhs; *cp; cp++) {
		if (!gisdigit((int)*cp)) {
			numeric = 0;
			break;
		}
	}

	if (numeric) {
		for (cp = rhs; *cp; cp++) {
			if (!gisdigit((int)*cp)) {
				numeric = 0;
				break;
			}
		}
	}

	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) {
static int getLexicalToken(ej_t* ep, int state)
{
    ringq_t		*inq, *tokq;
    ejinput_t*	ip;
    int			done, tid, c, quote, style;

    a_assert(ep);
    ip = ep->input;
    a_assert(ip);

    inq = &ip->script;
    tokq = &ip->tokbuf;

    ep->tid = -1;
    tid = -1;
    ep->token = T("");

    ringqFlush(tokq);

    if (ip->putBackTokenId > 0) {
        ringqPutStr(tokq, ip->putBackToken);
        tid = ip->putBackTokenId;
        ip->putBackTokenId = 0;
        ep->token = (char_t*) tokq->servp;
        return tid;
    }

    if ((c = inputGetc(ep)) < 0) {
        return TOK_EOF;
    }

    for (done = 0; !done; ) {
        switch (c) {
        case -1:
            return TOK_EOF;

        case ' ':
        case '\t':
        case '\r':
            do {
                if ((c = inputGetc(ep)) < 0)
                    break;
            } while (c == ' ' || c == '\t' || c == '\r');
            break;

        case '\n':
            return TOK_NEWLINE;

        case '(':
            tokenAddChar(ep, c);
            return TOK_LPAREN;

        case ')':
            tokenAddChar(ep, c);
            return TOK_RPAREN;

        case '{':
            tokenAddChar(ep, c);
            return TOK_LBRACE;

        case '}':
            tokenAddChar(ep, c);
            return TOK_RBRACE;

        case '+':
            if ((c = inputGetc(ep)) < 0) {
                ejError(ep, T("Syntax Error"));
                return TOK_ERR;
            }
            if (c != '+' ) {
                inputPutback(ep, c);
                tokenAddChar(ep, EXPR_PLUS);
                return TOK_EXPR;
            }
            tokenAddChar(ep, EXPR_INC);
            return TOK_INC_DEC;

        case '-':
            if ((c = inputGetc(ep)) < 0) {
                ejError(ep, T("Syntax Error"));
                return TOK_ERR;
            }
            if (c != '-' ) {
                inputPutback(ep, c);
                tokenAddChar(ep, EXPR_MINUS);
                return TOK_EXPR;
            }
            tokenAddChar(ep, EXPR_DEC);
            return TOK_INC_DEC;

        case '*':
            tokenAddChar(ep, EXPR_MUL);
            return TOK_EXPR;

        case '%':
            tokenAddChar(ep, EXPR_MOD);
            return TOK_EXPR;

        case '/':
            /*
             *			Handle the division operator and comments
             */
            if ((c = inputGetc(ep)) < 0) {
                ejError(ep, T("Syntax Error"));
                return TOK_ERR;
            }
            if (c != '*' && c != '/') {
                inputPutback(ep, c);
                tokenAddChar(ep, EXPR_DIV);
                return TOK_EXPR;
            }
            style = c;
            /*
             *			Eat comments. Both C and C++ comment styles are supported.
             */
            while (1) {
                if ((c = inputGetc(ep)) < 0) {
                    ejError(ep, T("Syntax Error"));
                    return TOK_ERR;
                }
                if (c == '\n' && style == '/') {
                    break;
                } else if (c == '*') {
                    c = inputGetc(ep);
                    if (style == '/') {
                        if (c == '\n') {
                            break;
                        }
                    } else {
                        if (c == '/') {
                            break;
                        }
                    }
                }
            }
            /*
             *			Continue looking for a token, so get the next character
             */
            if ((c = inputGetc(ep)) < 0) {
                return TOK_EOF;
            }
            break;

        case '<':									/* < and <= */
            if ((c = inputGetc(ep)) < 0) {
                ejError(ep, T("Syntax Error"));
                return TOK_ERR;
            }
            if (c == '<') {
                tokenAddChar(ep, EXPR_LSHIFT);
                return TOK_EXPR;
            } else if (c == '=') {
                tokenAddChar(ep, EXPR_LESSEQ);
                return TOK_EXPR;
            }
            tokenAddChar(ep, EXPR_LESS);
            inputPutback(ep, c);
            return TOK_EXPR;

        case '>':									/* > and >= */
            if ((c = inputGetc(ep)) < 0) {
                ejError(ep, T("Syntax Error"));
                return TOK_ERR;
            }
            if (c == '>') {
                tokenAddChar(ep, EXPR_RSHIFT);
                return TOK_EXPR;
            } else if (c == '=') {
                tokenAddChar(ep, EXPR_GREATEREQ);
                return TOK_EXPR;
            }
            tokenAddChar(ep, EXPR_GREATER);
            inputPutback(ep, c);
            return TOK_EXPR;

        case '=':									/* "==" */
            if ((c = inputGetc(ep)) < 0) {
                ejError(ep, T("Syntax Error"));
                return TOK_ERR;
            }
            if (c == '=') {
                tokenAddChar(ep, EXPR_EQ);
                return TOK_EXPR;
            }
            inputPutback(ep, c);
            return TOK_ASSIGNMENT;

        case '!':									/* "!=" or "!"*/
            if ((c = inputGetc(ep)) < 0) {
                ejError(ep, T("Syntax Error"));
                return TOK_ERR;
            }
            if (c == '=') {
                tokenAddChar(ep, EXPR_NOTEQ);
                return TOK_EXPR;
            }
            inputPutback(ep, c);
            tokenAddChar(ep, EXPR_BOOL_COMP);
            return TOK_EXPR;

        case ';':
            tokenAddChar(ep, c);
            return TOK_SEMI;

        case ',':
            tokenAddChar(ep, c);
            return TOK_COMMA;

        case '|':									/* "||" */
            if ((c = inputGetc(ep)) < 0 || c != '|') {
                ejError(ep, T("Syntax Error"));
                return TOK_ERR;
            }
            tokenAddChar(ep, COND_OR);
            return TOK_LOGICAL;

        case '&':									/* "&&" */
            if ((c = inputGetc(ep)) < 0 || c != '&') {
                ejError(ep, T("Syntax Error"));
                return TOK_ERR;
            }
            tokenAddChar(ep, COND_AND);
            return TOK_LOGICAL;

        case '\"':									/* String quote */
        case '\'':
            quote = c;
            if ((c = inputGetc(ep)) < 0) {
                ejError(ep, T("Syntax Error"));
                return TOK_ERR;
            }

            while (c != quote) {
                /*
                 *				check for escape sequence characters
                 */
                if (c == '\\') {
                    c = inputGetc(ep);

                    if (gisdigit(c)) {
                        /*
                         *						octal support, \101 maps to 65 = 'A'. put first char
                         *						back so converter will work properly.
                         */
                        inputPutback(ep, c);
                        c = charConvert(ep, OCTAL, 3);

                    } else {
                        switch (c) {
                        case 'n':
                            c = '\n';
                            break;
                        case 'b':
                            c = '\b';
                            break;
                        case 'f':
                            c = '\f';
                            break;
                        case 'r':
                            c = '\r';
                            break;
                        case 't':
                            c = '\t';
                            break;
                        case 'x':
                            /*
                             *							hex support, \x41 maps to 65 = 'A'
                             */
                            c = charConvert(ep, HEX, 2);
                            break;
                        case 'u':
                            /*
                             *							unicode support, \x0401 maps to 65 = 'A'
                             */
                            c = charConvert(ep, HEX, 2);
                            c = c*16 + charConvert(ep, HEX, 2);

                            break;
                        case '\'':
                        case '\"':
                        case '\\':
                            break;
                        default:
                            ejError(ep, T("Invalid Escape Sequence"));
                            return TOK_ERR;
                        }
                    }
                    if (tokenAddChar(ep, c) < 0) {
                        return TOK_ERR;
                    }
                } else {
                    if (tokenAddChar(ep, c) < 0) {
                        return TOK_ERR;
                    }
                }
                if ((c = inputGetc(ep)) < 0) {
                    ejError(ep, T("Unmatched Quote"));
                    return TOK_ERR;
                }
            }
            return TOK_LITERAL;

        case '0':
        case '1':
        case '2':
        case '3':
        case '4':
        case '5':
        case '6':
        case '7':
        case '8':
        case '9':
            do {
                if (tokenAddChar(ep, c) < 0) {
                    return TOK_ERR;
                }
                if ((c = inputGetc(ep)) < 0)
                    break;
            } while (gisdigit(c));
            inputPutback(ep, c);
            return TOK_LITERAL;

        default:
            /*
             *			Identifiers or a function names
             */
            while (1) {
                if (c == '\\') {
                    /*
                     *					just ignore any \ characters.
                     */
                } else if (tokenAddChar(ep, c) < 0) {
                    break;
                }
                if ((c = inputGetc(ep)) < 0) {
                    break;
                }
                if (!gisalnum(c) && c != '$' && c != '_' &&
                    c != '\\') {
                    break;
                }
            }
            if (! gisalpha(*tokq->servp) && *tokq->servp != '$' &&
                *tokq->servp != '_') {
                ejError(ep, T("Invalid identifier %s"), tokq->servp);
                return TOK_ERR;
            }
            /*
             *			Check for reserved words (only "if", "else", "var", "for"
             *			and "return" at the moment)
             */
            if (state == STATE_STMT) {
                if (gstrcmp(ep->token, T("if")) == 0) {
                    return TOK_IF;
                } else if (gstrcmp(ep->token, T("else")) == 0) {
                    return TOK_ELSE;
                } else if (gstrcmp(ep->token, T("var")) == 0) {
                    return TOK_VAR;
                } else if (gstrcmp(ep->token, T("for")) == 0) {
                    return TOK_FOR;
                } else if (gstrcmp(ep->token, T("return")) == 0) {
                    if ((c == ';') || (c == '(')) {
                        inputPutback(ep, c);
                    }
                    return TOK_RETURN;
                }
            }

            /*
             * 			Skip white space after token to find out whether this is
             * 			a function or not.
             */
            while (c == ' ' || c == '\t' || c == '\r' || c == '\n') {
                if ((c = inputGetc(ep)) < 0)
                    break;
            }

            tid = (c == '(') ? TOK_FUNCTION : TOK_ID;
            done++;
        }
    }

    /*
     *	Putback the last extra character for next time
     */
    inputPutback(ep, c);
    return tid;
}