Esempio n. 1
0
static int parse_numeric_literal(parser_ctx_t *ctx, literal_t **literal)
{
    LONG l, d;

    l = *ctx->ptr++ - '0';
    if(!l) {
        if(*ctx->ptr == 'x' || *ctx->ptr == 'X') {
            if(++ctx->ptr == ctx->end) {
                ERR("unexpected end of file\n");
                return 0;
            }

            while(ctx->ptr < ctx->end && (d = hex_to_int(*ctx->ptr)) != -1) {
                l = l*16 + d;
                ctx->ptr++;
            }

            if(ctx->ptr < ctx->end && is_identifier_char(*ctx->ptr)) {
                WARN("unexpected identifier char\n");
                return lex_error(ctx, JS_E_MISSING_SEMICOLON);
            }

            *literal = new_double_literal(ctx, l);
            return tNumericLiteral;
        }

        if(isdigitW(*ctx->ptr)) {
            unsigned base = 8;
            const WCHAR *ptr;
            double val = 0;

            for(ptr = ctx->ptr; ptr < ctx->end && isdigitW(*ptr); ptr++) {
                if(*ptr > '7') {
                    base = 10;
                    break;
                }
            }

            do {
                val = val*base + *ctx->ptr-'0';
            }while(++ctx->ptr < ctx->end && isdigitW(*ctx->ptr));

            /* FIXME: Do we need it here? */
            if(ctx->ptr < ctx->end && (is_identifier_char(*ctx->ptr) || *ctx->ptr == '.')) {
                WARN("wrong char after octal literal: '%c'\n", *ctx->ptr);
                return lex_error(ctx, JS_E_MISSING_SEMICOLON);
            }

            *literal = new_double_literal(ctx, val);
            return tNumericLiteral;
        }

        if(is_identifier_char(*ctx->ptr)) {
            WARN("wrong char after zero\n");
            return lex_error(ctx, JS_E_MISSING_SEMICOLON);
        }
    }

    return parse_double_literal(ctx, l, literal);
}
Esempio n. 2
0
File: lex.c Progetto: mikekap/wine
static int cc_token(parser_ctx_t *ctx, void *lval)
{
    unsigned id_len = 0;
    cc_var_t *var;

    static const WCHAR cc_onW[] = {'c','c','_','o','n',0};
    static const WCHAR setW[] = {'s','e','t',0};
    static const WCHAR elifW[] = {'e','l','i','f',0};
    static const WCHAR endW[] = {'e','n','d',0};

    ctx->ptr++;

    if(!check_keyword(ctx, cc_onW, NULL))
        return init_cc(ctx);

    if(!check_keyword(ctx, setW, NULL)) {
        FIXME("@set not implemented\n");
        return lex_error(ctx, E_NOTIMPL);
    }

    if(!check_keyword(ctx, ifW, NULL)) {
        FIXME("@if not implemented\n");
        return lex_error(ctx, E_NOTIMPL);
    }

    if(!check_keyword(ctx, elifW, NULL)) {
        FIXME("@elif not implemented\n");
        return lex_error(ctx, E_NOTIMPL);
    }

    if(!check_keyword(ctx, elseW, NULL)) {
        FIXME("@else not implemented\n");
        return lex_error(ctx, E_NOTIMPL);
    }

    if(!check_keyword(ctx, endW, NULL)) {
        FIXME("@end not implemented\n");
        return lex_error(ctx, E_NOTIMPL);
    }

    if(!ctx->script->cc)
        return lex_error(ctx, JS_E_DISABLED_CC);

    while(ctx->ptr+id_len < ctx->end && is_identifier_char(ctx->ptr[id_len]))
        id_len++;
    if(!id_len)
        return '@';

    TRACE("var %s\n", debugstr_wn(ctx->ptr, id_len));

    var = find_cc_var(ctx->script->cc, ctx->ptr, id_len);
    ctx->ptr += id_len;
    if(!var || var->is_num) {
        *(literal_t**)lval = new_double_literal(ctx, var ? var->u.n : ret_nan());
        return tNumericLiteral;
    }

    *(literal_t**)lval = new_boolean_literal(ctx, var->u.b);
    return tBooleanLiteral;
}
Esempio n. 3
0
File: lex.c Progetto: mikekap/wine
static BOOL skip_comment(parser_ctx_t *ctx)
{
    if(ctx->ptr+1 >= ctx->end)
        return FALSE;

    if(*ctx->ptr != '/') {
        if(*ctx->ptr == '@' && ctx->ptr+2 < ctx->end && ctx->ptr[1] == '*' && ctx->ptr[2] == '/') {
            ctx->ptr += 3;
            return TRUE;
        }

        return FALSE;
    }

    switch(ctx->ptr[1]) {
    case '*':
        ctx->ptr += 2;
        if(ctx->ptr+2 < ctx->end && *ctx->ptr == '@' && is_identifier_char(ctx->ptr[1]))
            return FALSE;
        while(ctx->ptr+1 < ctx->end && (ctx->ptr[0] != '*' || ctx->ptr[1] != '/'))
            ctx->ptr++;

        if(ctx->ptr[0] == '*' && ctx->ptr[1] == '/') {
            ctx->ptr += 2;
        }else {
            WARN("unexpected end of file (missing end of comment)\n");
            ctx->ptr = ctx->end;
        }
        break;
    case '/':
        ctx->ptr += 2;
        if(ctx->ptr+2 < ctx->end && *ctx->ptr == '@' && is_identifier_char(ctx->ptr[1]))
            return FALSE;
        while(ctx->ptr < ctx->end && !is_endline(*ctx->ptr))
            ctx->ptr++;
        break;
    default:
        return FALSE;
    }

    return TRUE;
}
Esempio n. 4
0
File: ext.c Progetto: infoburp/gawk
awk_bool_t
make_builtin(const awk_ext_func_t *funcinfo)
{
	NODE *symbol, *f;
	INSTRUCTION *b;
	const char *sp;
	char c;
	const char *name = funcinfo->name;
	int count = funcinfo->num_expected_args;

	sp = name;
	if (sp == NULL || *sp == '\0')
		fatal(_("make_builtin: missing function name"));

	if (! is_letter(*sp))
		return awk_false;

	for (sp++; (c = *sp++) != '\0';) {
		if (! is_identifier_char(c))
			return awk_false;
	}

	f = lookup(name);

	if (f != NULL) {
		if (f->type == Node_func) {
			/* user-defined function */
			fatal(_("make_builtin: can't redefine function `%s'"), name);
		} else if (f->type == Node_ext_func) {
			/* multiple extension() calls etc. */ 
			if (do_lint)
				lintwarn(_("make_builtin: function `%s' already defined"), name);
			return awk_false;
		} else
			/* variable name etc. */ 
			fatal(_("make_builtin: function name `%s' previously defined"), name);
	} else if (check_special(name) >= 0)
		fatal(_("make_builtin: can't use gawk built-in `%s' as function name"), name); 

	if (count < 0)
		fatal(_("make_builtin: negative argument count for function `%s'"),
				name);

	b = bcalloc(Op_symbol, 1, 0);
	b->extfunc = funcinfo->function;
	b->expr_count = count;

	/* NB: extension sub must return something */

       	symbol = install_symbol(estrdup(name, strlen(name)), Node_ext_func);
	symbol->code_ptr = b;
	track_ext_func(name);
	return awk_true;
}
Esempio n. 5
0
File: json.c Progetto: AmesianX/wine
static BOOL is_keyword(json_parse_ctx_t *ctx, const WCHAR *keyword)
{
    unsigned i;
    for(i=0; keyword[i]; i++) {
        if(!ctx->ptr[i] || keyword[i] != ctx->ptr[i])
            return FALSE;
    }
    if(is_identifier_char(ctx->ptr[i]))
        return FALSE;
    ctx->ptr += i;
    return TRUE;
}
Esempio n. 6
0
void DataTypeClassNameParser::Parser::read_next_identifier(std::string* name) {
  size_t i = index_;
  while (!is_eos() && is_identifier_char(str_[index_]))
    ++index_;
  if (name != NULL) {
    if (index_ > i) {
      *name = str_.substr(i, index_ - i);
    } else{
      name->clear();
    }
  }
}
Esempio n. 7
0
field *get_fields(char *def) {
  int num_fields = get_num_fields(def);
  field *fields = malloc(sizeof(field) * num_fields);

  char *curr = def;
  int idx = 0;
  while((curr = strstr(curr, "FIELD"))) {
    curr += 5; // strlen("FIELD")

    // advance past field type
    while (curr[0] != ',') curr++;

    while (!is_identifier_char(curr[0])) curr++;
    char *end = curr;
    while (is_identifier_char(end[0])) end++;
    size_t field_length = end - curr;

    fields[idx++].name = substr(curr, field_length);
  }
  return fields;
}
Esempio n. 8
0
File: ext.c Progetto: infoburp/gawk
void
make_old_builtin(const char *name, NODE *(*func)(int), int count)	/* temporary */
{
	NODE *symbol, *f;
	INSTRUCTION *b;
	const char *sp;
	char c;

	sp = name;
	if (sp == NULL || *sp == '\0')
		fatal(_("extension: missing function name"));

	if (! is_letter(*sp))
		fatal(_("extension: illegal character `%c' in function name `%s'"), *sp, name);

	for (sp++; (c = *sp++) != '\0';) {
		if (! is_identifier_char(c))
			fatal(_("extension: illegal character `%c' in function name `%s'"), c, name);
	}

	f = lookup(name);

	if (f != NULL) {
		if (f->type == Node_func) {
			/* user-defined function */
			fatal(_("extension: can't redefine function `%s'"), name);
		} else if (f->type == Node_ext_func) {
			/* multiple extension() calls etc. */ 
			if (do_lint)
				lintwarn(_("extension: function `%s' already defined"), name);
			return;
		} else
			/* variable name etc. */ 
			fatal(_("extension: function name `%s' previously defined"), name);
	} else if (check_special(name) >= 0)
		fatal(_("extension: can't use gawk built-in `%s' as function name"), name); 

	if (count < 0)
		fatal(_("make_builtin: negative argument count for function `%s'"),
				name);

	b = bcalloc(Op_symbol, 1, 0);
	b->builtin = func;
	b->expr_count = count;

	/* NB: extension sub must return something */

       	symbol = install_symbol(estrdup(name, strlen(name)), Node_old_ext_func);
	symbol->code_ptr = b;
	track_ext_func(name);
}
Esempio n. 9
0
static char *
eat_show_line(int test_for_endshow)
{
    int c;
    int saw_escape_code = 0;
    int starting_line = yylineno;
    char buffer[200];      /* This must be large enough to hold "endshow" */
    char *ptr = buffer;

    while (yylineno == starting_line) {
	c = input();
	if (!c) {
	    unput(c);
	    *ptr = '\0';
	    return(string_Copy(buffer));
	} else if (c == '\\') {
	    saw_escape_code = 1;
	    c = eat_escape_code();
	    if (!c)
	      continue;
	}

	*ptr = c;
	ptr++;

	if ((ptr==buffer+strlen("endshow")) && test_for_endshow)
	  if (!strncmp(buffer, "endshow", strlen("endshow"))
	      && !saw_escape_code) {
	      c = input();
	      unput(c);
	      if (!is_identifier_char(c))
		return(0);
	  }

	if (ptr>buffer+sizeof(buffer)-2) {
	    string the_line;
	    string rest_of_line = eat_show_line(0);

	    *ptr = '\0';
	    the_line = string_Concat(buffer, rest_of_line);
	    free(rest_of_line);
	    return(the_line);
	}
    }

    *ptr = '\0';
    return(string_Copy(buffer));
}
Esempio n. 10
0
static BOOL parse_cc_identifier(parser_ctx_t *ctx, const WCHAR **ret, unsigned *ret_len)
{
    if(*ctx->ptr != '@') {
        lex_error(ctx, JS_E_EXPECTED_AT);
        return FALSE;
    }

    if(!is_identifier_first_char(*++ctx->ptr)) {
        lex_error(ctx, JS_E_EXPECTED_IDENTIFIER);
        return FALSE;
    }

    *ret = ctx->ptr;
    while(++ctx->ptr < ctx->end && is_identifier_char(*ctx->ptr));
    *ret_len = ctx->ptr - *ret;
    return TRUE;
}
Esempio n. 11
0
File: lex.c Progetto: mikekap/wine
static int parse_identifier(parser_ctx_t *ctx, const WCHAR **ret)
{
    const WCHAR *ptr = ctx->ptr++;
    WCHAR *wstr;
    int len;

    while(ctx->ptr < ctx->end && is_identifier_char(*ctx->ptr))
        ctx->ptr++;

    len = ctx->ptr-ptr;

    *ret = wstr = parser_alloc(ctx, (len+1)*sizeof(WCHAR));
    memcpy(wstr, ptr, (len+1)*sizeof(WCHAR));
    wstr[len] = 0;

    /* FIXME: unescape */
    return tIdentifier;
}
Esempio n. 12
0
static int parse_identifier(parser_ctx_t *ctx, const WCHAR **ret)
{
    const WCHAR *ptr = ctx->ptr++;
    WCHAR *str;
    int len;

    while(ctx->ptr < ctx->end && is_identifier_char(*ctx->ptr))
        ctx->ptr++;
    len = ctx->ptr-ptr;

    str = parser_alloc(ctx, (len+1)*sizeof(WCHAR));
    if(!str)
        return 0;

    memcpy(str, ptr, (len+1)*sizeof(WCHAR));
    str[len] = 0;
    *ret = str;
    return tIdentifier;
}
Esempio n. 13
0
static int parse_hex_literal(parser_ctx_t *ctx, LONG *ret)
{
    const WCHAR *begin = ctx->ptr;
    LONG l = 0, d;

    while((d = hex_to_int(*++ctx->ptr)) != -1)
        l = l*16 + d;

    if(begin + 9 /* max digits+1 */ < ctx->ptr || (*ctx->ptr != '&' && is_identifier_char(*ctx->ptr))) {
        FIXME("invalid literal\n");
        return 0;
    }

    if(*ctx->ptr == '&')
        ctx->ptr++;

    *ret = l;
    return (short)l == l ? tShort : tLong;
}
Esempio n. 14
0
static int check_keyword(parser_ctx_t *ctx, const WCHAR *word)
{
    const WCHAR *p1 = ctx->ptr;
    const WCHAR *p2 = word;
    WCHAR c;

    while(p1 < ctx->end && *p2) {
        c = tolowerW(*p1);
        if(c != *p2)
            return c - *p2;
        p1++;
        p2++;
    }

    if(*p2 || (p1 < ctx->end && is_identifier_char(*p1)))
        return 1;

    ctx->ptr = p1;
    return 0;
}
Esempio n. 15
0
File: lex.c Progetto: mikekap/wine
static int check_keyword(parser_ctx_t *ctx, const WCHAR *word, const WCHAR **lval)
{
    const WCHAR *p1 = ctx->ptr;
    const WCHAR *p2 = word;

    while(p1 < ctx->end && *p2) {
        if(*p1 != *p2)
            return *p1 - *p2;
        p1++;
        p2++;
    }

    if(*p2 || (p1 < ctx->end && is_identifier_char(*p1)))
        return 1;

    if(lval)
        *lval = ctx->ptr;
    ctx->ptr = p1;
    return 0;
}
Esempio n. 16
0
// Check if the character before the search string is a valid character that will
// make the character + search string a valid token. Used to find out if the char
// before the occurrence of strings 'class' and 'function' is a non-identifier char
// and non-$ char
// Eg: xfunction should return false so should $class
static gboolean non_letter_before(gchar *original, gchar *current, gchar *search)
{
  gint search_len;

  search_len = strlen(search);

  // First, make sure we're not going to go out of bounds.
  if (current-original < (search_len+1)) {
    return FALSE;
  }

  // Second, go back from current search_len positions
  current = current - (search_len);

  // Then check to see if we match
  if (!is_identifier_char(*current) && *current != '$') {
    return TRUE;
  }

  return FALSE;
}
Esempio n. 17
0
void DataTypeCqlNameParser::Parser::read_next_identifier(std::string* name) {
  size_t start_index = index_;
  if (str_[start_index] == '"') {
    ++index_;
    while (!is_eos()) {
      bool is_quote = str_[index_] == '"';
      ++index_;
      if (is_quote) {
        if  (!is_eos() && str_[index_] == '"') {
          ++index_;
        } else {
          break;
        }
      }
    }
  } else {
    while (!is_eos() && (is_identifier_char(str_[index_]) || str_[index_] == '"')) {
      ++index_;
    }
  }
  name->assign(str_.begin() + start_index, str_.begin() + index_);
}
Esempio n. 18
0
File: lex.c Progetto: jkdewar/rook
/*----------------------------------------------------------------------*/
static void read_identifier(lex_state_t *l, token_t *token) {
    const char *start;
    const char *end;
    size_t len;

    /* find the end of the identifier */
    start = l->ptr;
    end = l->ptr;
    for (;;) {
        if (!is_identifier_char(*end))
            break;
        end += 1;
    }

    /* copy identifier string to the token */
    len = end - start;
    token->type = TK_IDENTIFIER;
    token->u.s = (char *)ALLOC(len + 1);
    memcpy(token->u.s, start, len);
    token->u.s[len] = '\0';
    l->ptr += len;
}
Esempio n. 19
0
static char *
read_identifier (struct parsebuf *p)
{
  /* Index of the first character of the identifier in p->buf.  */
  int start;
  /* Next index after the last character of the identifer in p->buf.  */
  int end;

  skip_whitespace (p);

  /* Capture the start of the identifier.  */
  start = p->pos;

  /* Scan for the end.  */
  while (is_identifier_char (peek_char (p)))
    read_char (p);
  end = p->pos;

  if (end - start < 1)
    return 0;

  return grub_new_substring (p->buf, start, end);
}
Esempio n. 20
0
int yylex(void)
{
    register int c, last_char;
    register char *ptr;
    int start_line_no;
    int_dictionary_binding *binding;
    char varname[MAX_IDENTIFIER_LENGTH+1];

    for (;;) {
	switch (c = input()) {

	    /*
	     * Skip whitespace:
	     */
	  case ' ':   case '\t':   case '\n':
	    continue;

	    /*
	     * '#' comments out everything up to the and including
	     * the next <cr>:
	     */
	  case '#':
	    while ( (c=input()) && (c!='\n') ) ;
	    if (!c)
	      unput(c);
	    continue;

	    /*
	     * Handle c-style comments.  Note that "/[^*]" is not the start
	     * of any valid token.
	     */
	  case '/':
	    start_line_no = yylineno;

	    /* verify that next character is a '*': */
	    if ((c=input()) != '*')
	      return(ERROR);

	    /* Scan until "*\/" or <EOF>: */
	    for (last_char=0; ; last_char=c) {
		c = input();
		if (c == '/' && (last_char=='*'))
		  break;
		if (!c) {
		    unput(c);
		    report_parse_error("unterminated c style comment found beginning", start_line_no);
		    return(ERROR);
		}
	    }
	    continue;

	    /*
	     * The following characters lex as themselves:
	     *   '+', '|', '&', '(', ')', '.', ',' and <EOF>:
	     */
	  case   0:   case '+':   case '|':   case '&':   case '(':
	  case ')':   case '.':	  case ',':
	    return(c);

	    /*
	     * Handle "=[^~=]", "=~", and "==":
	     */
	  case '=':
	    switch (c = input()) {
	      case '~':
		return(REGEQ);
	      case '=':
		return(EQ);
	      default:
		unput(c);
		return('=');
	    }

	    /*
	     * Handle "![^~=]", "!~", and "!=":
	     */
	  case '!':
	    switch (c = input()) {
	      case '~':
		return(REGNEQ);
	      case '=':
		return(NEQ);
	      default:
		unput(c);
		return('!');
	    }

	    /*
	     * Handle identifiers and keywords:
	     *
	     * Note that the below set of characters is hard coded from
	     * is_identifier_char from parser.h.
	     */
	  case 'a':   case 'b':   case 'c':   case 'd':   case 'e':
	  case 'f':   case 'g':   case 'h':   case 'i':   case 'j':
	  case 'k':   case 'l':   case 'm':   case 'n':   case 'o':
	  case 'p':   case 'q':   case 'r':   case 's':   case 't':
	  case 'u':   case 'v':   case 'w':   case 'x':   case 'y':
	  case 'z':
	  case 'A':   case 'B':   case 'C':   case 'D':   case 'E':
	  case 'F':   case 'G':   case 'H':   case 'I':   case 'J':
	  case 'K':   case 'L':   case 'M':   case 'N':   case 'O':
	  case 'P':   case 'Q':   case 'R':   case 'S':   case 'T':
	  case 'U':   case 'V':   case 'W':   case 'X':   case 'Y':
	  case 'Z':
	  case '0':   case '1':   case '2':   case '3':   case '4':
	  case '5':   case '6':   case '7':   case '8':   case '9':
	  case '_':
	    /*
	     * Read in the first MAX_IDENTIFIER_LENGTH characters of the
	     * identifier into varname null terminated.  Eat
	     * the rest of the characters of the identifier:
	     */
	    for (ptr = varname;;) {
		if (ptr<varname+MAX_IDENTIFIER_LENGTH)
		  *(ptr++) = c;
		c = input();
		if (!is_identifier_char(c))
		  break;
	    }
	    unput(c);
	    *ptr = '\0';

	    /*
	     * Look up the identifier in the keyword dictionary.
	     * If its a match, return the keyword's #.  In the case
	     * of show, call handle_show to do more processing.
	     * If not a match, treat as a variable name.
	     */
	    binding = int_dictionary_Lookup(keyword_dict, varname);
	    if (!binding) {
		yylval.text = string_Copy(varname);
		return(VARNAME);
	    }
	    if (binding->value == SHOW)
	      return(handle_show());
	    else
	      return(binding->value);

	    /*
	     * Handle "${identifier}".  Note that $ followed by a
	     * non-identifier character is not the start of any valid token.
	     */
	  case '$':
	    c = input();
	    if (!is_identifier_char(c))
	      return(ERROR);
    
	    /*
	     * Read in the first MAX_IDENTIFIER_LENGTH characters of the
	     * identifier into varname null terminated.  Eat
	     * the rest of the characters of the identifier:
	     */
	    for (ptr = varname;;) {
		if (ptr<varname+MAX_IDENTIFIER_LENGTH)
		  *(ptr++) = c;
		c = input();
		if (!is_identifier_char(c))
		  break;
	    }
	    unput(c);
	    *ptr = '\0';

	    yylval.text = string_Copy(varname);
	    return(VARREF);

	    /*
	     * Handle constant strings:
	     */
	  case '"':
	    yylval.text = eat_string(yylineno);
	    if (yylval.text)
	      return(STRING);
	    else
	      return(ERROR);

	    /*
	     * All other characters do not start valid tokens:
	     */
	  default:
	    return(ERROR);
	}
    }
}
Esempio n. 21
0
File: lex.c Progetto: jkdewar/rook
/*----------------------------------------------------------------------*/
static int next_token(lex_state_t *l) {
    token_t *token;
    char c;
    char cn;
    token = &l->out->tokens[l->out->token_count];
    skip_comments_and_whitespace(l);
    token->source_pos = l->ptr - l->in->source;
    c  = *(l->ptr + 0);
    cn = *(l->ptr + 1);
    if (c == '\0') {
        return 0;
    } else if (c == '\"') {
        read_string(l, token);
    } else if (is_decimal_digit(c)) {
        read_number(l, token);
    } else if (is_identifier_char(c)) {
        read_identifier(l, token);
        match_keyword(token);
    } else if (c == '<' && cn == '=') {
        token->type = TK_LESS_EQUAL;
        l->ptr += 2;
    } else if (c == '=' && cn == '=') {
        token->type = TK_EQUALS_EQUALS;
        l->ptr += 2;
    } else if (c == '>' && cn == '=') {
        token->type = TK_GREATER_EQUAL;
        l->ptr += 2;
    } else if (c == '+') {
        token->type = TK_PLUS;
        ++l->ptr;
    } else if (c == '-') {
        token->type = TK_MINUS;
        ++l->ptr;
    } else if (c == '*') {
        token->type = TK_STAR;
        ++l->ptr;
    } else if (c == '/') {
        token->type = TK_SLASH;
        ++l->ptr;
    } else if (c == '=') {
        token->type = TK_EQUALS;
        ++l->ptr;
    } else if (c == '<') {
        token->type = TK_LESS;
        ++l->ptr;
    } else if (c == '>') {
        token->type = TK_GREATER;
        ++l->ptr;
    } else if (c == '(') {
        token->type = TK_LBRACKET;
        ++l->ptr;
    } else if (c == ')') {
        token->type = TK_RBRACKET;
        ++l->ptr;
    } else if (c == ',') {
        token->type = TK_COMMA;
        ++l->ptr;
    } else if (c == ':') {
        token->type = TK_COLON;
        ++l->ptr;
    } else if (c == ';') {
        token->type = TK_SEMICOLON;
        ++l->ptr;
    } else {
        error(l);
    }
    return 1;
}
Esempio n. 22
0
File: json.c Progetto: AmesianX/wine
/* ECMA-262 5.1 Edition    15.12.1.2 */
static HRESULT parse_json_value(json_parse_ctx_t *ctx, jsval_t *r)
{
    HRESULT hres;

    switch(skip_spaces(ctx)) {

    /* JSONNullLiteral */
    case 'n':
        if(!is_keyword(ctx, nullW))
            break;
        *r = jsval_null();
        return S_OK;

    /* JSONBooleanLiteral */
    case 't':
        if(!is_keyword(ctx, trueW))
            break;
        *r = jsval_bool(TRUE);
        return S_OK;
    case 'f':
        if(!is_keyword(ctx, falseW))
            break;
        *r = jsval_bool(FALSE);
        return S_OK;

    /* JSONObject */
    case '{': {
        WCHAR *prop_name;
        jsdisp_t *obj;
        jsval_t val;

        hres = create_object(ctx->ctx, NULL, &obj);
        if(FAILED(hres))
            return hres;

        ctx->ptr++;
        if(skip_spaces(ctx) == '}') {
            ctx->ptr++;
            *r = jsval_obj(obj);
            return S_OK;
        }

        while(1) {
            if(*ctx->ptr != '"')
                break;
            hres = parse_json_string(ctx, &prop_name);
            if(FAILED(hres))
                break;

            if(skip_spaces(ctx) != ':') {
                FIXME("missing ':'\n");
                heap_free(prop_name);
                break;
            }

            ctx->ptr++;
            hres = parse_json_value(ctx, &val);
            if(SUCCEEDED(hres)) {
                hres = jsdisp_propput_name(obj, prop_name, val);
                jsval_release(val);
            }
            heap_free(prop_name);
            if(FAILED(hres))
                break;

            if(skip_spaces(ctx) == '}') {
                ctx->ptr++;
                *r = jsval_obj(obj);
                return S_OK;
            }

            if(*ctx->ptr++ != ',') {
                FIXME("expected ','\n");
                break;
            }
            skip_spaces(ctx);
        }

        jsdisp_release(obj);
        break;
    }

    /* JSONString */
    case '"': {
        WCHAR *string;
        jsstr_t *str;

        hres = parse_json_string(ctx, &string);
        if(FAILED(hres))
            return hres;

        /* FIXME: avoid reallocation */
        str = jsstr_alloc(string);
        heap_free(string);
        if(!str)
            return E_OUTOFMEMORY;

        *r = jsval_string(str);
        return S_OK;
    }

    /* JSONArray */
    case '[': {
        jsdisp_t *array;
        unsigned i = 0;
        jsval_t val;

        hres = create_array(ctx->ctx, 0, &array);
        if(FAILED(hres))
            return hres;

        ctx->ptr++;
        if(skip_spaces(ctx) == ']') {
            ctx->ptr++;
            *r = jsval_obj(array);
            return S_OK;
        }

        while(1) {
            hres = parse_json_value(ctx, &val);
            if(FAILED(hres))
                break;

            hres = jsdisp_propput_idx(array, i, val);
            jsval_release(val);
            if(FAILED(hres))
                break;

            if(skip_spaces(ctx) == ']') {
                ctx->ptr++;
                *r = jsval_obj(array);
                return S_OK;
            }

            if(*ctx->ptr != ',') {
                FIXME("expected ','\n");
                break;
            }

            ctx->ptr++;
            i++;
        }

        jsdisp_release(array);
        break;
    }

    /* JSONNumber */
    default: {
        int sign = 1;
        double n;

        if(*ctx->ptr == '-') {
            sign = -1;
            ctx->ptr++;
            skip_spaces(ctx);
        }

        if(!isdigitW(*ctx->ptr))
            break;

        if(*ctx->ptr == '0') {
            ctx->ptr++;
            n = 0;
            if(is_identifier_char(*ctx->ptr))
                break;
        }else {
            hres = parse_decimal(&ctx->ptr, ctx->end, &n);
            if(FAILED(hres))
                return hres;
        }

        *r = jsval_number(sign*n);
        return S_OK;
    }
    }

    FIXME("Syntax error at %s\n", debugstr_w(ctx->ptr));
    return E_FAIL;
}
static int
i386_intel_operand (char *operand_string, int got_a_float)
{
  char *saved_input_line_pointer, *buf;
  segT exp_seg;
  expressionS exp, *expP;
  char suffix = 0;
  int ret;

  /* Initialize state structure.  */
  intel_state.op_modifier = O_absent;
  intel_state.is_mem = 0;
  intel_state.base = NULL;
  intel_state.index = NULL;
  intel_state.seg = NULL;
  operand_type_set (&intel_state.reloc_types, ~0);
  gas_assert (!intel_state.in_offset);
  gas_assert (!intel_state.in_bracket);
  gas_assert (!intel_state.in_scale);

  saved_input_line_pointer = input_line_pointer;
  input_line_pointer = buf = xstrdup (operand_string);

  /* A '$' followed by an identifier char is an identifier.  Otherwise,
     it's operator '.' followed by an expression.  */
  if (*buf == '$' && !is_identifier_char (buf[1]))
    *buf = '.';

  intel_syntax = -1;
  memset (&exp, 0, sizeof(exp));
  exp_seg = expression (&exp);
  ret = i386_intel_simplify (&exp);
  intel_syntax = 1;

  SKIP_WHITESPACE ();
  if (!is_end_of_line[(unsigned char) *input_line_pointer])
    {
      as_bad (_("junk `%s' after expression"), input_line_pointer);
      ret = 0;
    }
  else if (exp.X_op == O_illegal || exp.X_op == O_absent)
    {
      as_bad (_("invalid expression"));
      ret = 0;
    }

  input_line_pointer = saved_input_line_pointer;
  free (buf);

  gas_assert (!intel_state.in_offset);
  gas_assert (!intel_state.in_bracket);
  gas_assert (!intel_state.in_scale);

  if (!ret)
    return 0;

  if (intel_state.op_modifier != O_absent
      && current_templates->start->base_opcode != 0x8d /* lea */)
    {
      i.types[this_operand].bitfield.unspecified = 0;

      switch (intel_state.op_modifier)
	{
	case O_byte_ptr:
	  i.types[this_operand].bitfield.byte = 1;
	  suffix = BYTE_MNEM_SUFFIX;
	  break;

	case O_word_ptr:
	  i.types[this_operand].bitfield.word = 1;
	  if ((current_templates->start->name[0] == 'l'
	       && current_templates->start->name[2] == 's'
	       && current_templates->start->name[3] == 0)
	      || current_templates->start->base_opcode == 0x62 /* bound */)
	    suffix = BYTE_MNEM_SUFFIX; /* so it will cause an error */
	  else if (got_a_float == 2)	/* "fi..." */
	    suffix = SHORT_MNEM_SUFFIX;
	  else
	    suffix = WORD_MNEM_SUFFIX;
	  break;

	case O_dword_ptr:
	  i.types[this_operand].bitfield.dword = 1;
	  if ((current_templates->start->name[0] == 'l'
	       && current_templates->start->name[2] == 's'
	       && current_templates->start->name[3] == 0)
	      || current_templates->start->base_opcode == 0x62 /* bound */)
	    suffix = WORD_MNEM_SUFFIX;
	  else if (flag_code == CODE_16BIT
		   && (current_templates->start->opcode_modifier.jump
		       || current_templates->start->opcode_modifier.jumpdword))
	    suffix = LONG_DOUBLE_MNEM_SUFFIX;
	  else if (got_a_float == 1)	/* "f..." */
	    suffix = SHORT_MNEM_SUFFIX;
	  else
	    suffix = LONG_MNEM_SUFFIX;
	  break;

	case O_fword_ptr:
	  i.types[this_operand].bitfield.fword = 1;
	  if (current_templates->start->name[0] == 'l'
	      && current_templates->start->name[2] == 's'
	      && current_templates->start->name[3] == 0)
	    suffix = LONG_MNEM_SUFFIX;
	  else if (!got_a_float)
	    {
	      if (flag_code == CODE_16BIT)
		add_prefix (DATA_PREFIX_OPCODE);
	      suffix = LONG_DOUBLE_MNEM_SUFFIX;
	    }
	  else
	    suffix = BYTE_MNEM_SUFFIX; /* so it will cause an error */
	  break;

	case O_qword_ptr:
	  i.types[this_operand].bitfield.qword = 1;
	  if (current_templates->start->base_opcode == 0x62 /* bound */
	      || got_a_float == 1)	/* "f..." */
	    suffix = LONG_MNEM_SUFFIX;
	  else
	    suffix = QWORD_MNEM_SUFFIX;
	  break;

	case O_tbyte_ptr:
	  i.types[this_operand].bitfield.tbyte = 1;
	  if (got_a_float == 1)
	    suffix = LONG_DOUBLE_MNEM_SUFFIX;
	  else
	    suffix = BYTE_MNEM_SUFFIX; /* so it will cause an error */
	  break;

	case O_oword_ptr:
	case O_xmmword_ptr:
	  i.types[this_operand].bitfield.xmmword = 1;
	  suffix = XMMWORD_MNEM_SUFFIX;
	  break;

	case O_ymmword_ptr:
	  i.types[this_operand].bitfield.ymmword = 1;
	  suffix = YMMWORD_MNEM_SUFFIX;
	  break;

	case O_far_ptr:
	  suffix = LONG_DOUBLE_MNEM_SUFFIX;
	  /* FALLTHROUGH */
	case O_near_ptr:
	  if (!current_templates->start->opcode_modifier.jump
	      && !current_templates->start->opcode_modifier.jumpdword)
	    suffix = got_a_float /* so it will cause an error */
		     ? BYTE_MNEM_SUFFIX
		     : LONG_DOUBLE_MNEM_SUFFIX;
	  break;

	default:
	  BAD_CASE (intel_state.op_modifier);
	  break;
	}

      if (!i.suffix)
	i.suffix = suffix;
      else if (i.suffix != suffix)
	{
	  as_bad (_("conflicting operand size modifiers"));
	  return 0;
	}
    }

  /* Operands for jump/call need special consideration.  */
  if (current_templates->start->opcode_modifier.jump
      || current_templates->start->opcode_modifier.jumpdword
      || current_templates->start->opcode_modifier.jumpintersegment)
    {
      if (i.op[this_operand].regs || intel_state.base || intel_state.index
	  || intel_state.is_mem > 1)
	i.types[this_operand].bitfield.jumpabsolute = 1;
      else
	switch (intel_state.op_modifier)
	  {
	  case O_near_ptr:
	    if (intel_state.seg)
	      i.types[this_operand].bitfield.jumpabsolute = 1;
	    else
	      intel_state.is_mem = 1;
	    break;
	  case O_far_ptr:
	  case O_absent:
	    if (!intel_state.seg)
	      {
		intel_state.is_mem = 1;
		if (intel_state.op_modifier == O_absent)
		  break;
		as_bad (_("cannot infer the segment part of the operand"));
		return 0;
	      }
	    else if (S_GET_SEGMENT (intel_state.seg) == reg_section)
	      i.types[this_operand].bitfield.jumpabsolute = 1;
	    else
	      {
		i386_operand_type types;

		if (i.imm_operands >= MAX_IMMEDIATE_OPERANDS)
		  {
		    as_bad (_("at most %d immediate operands are allowed"),
			    MAX_IMMEDIATE_OPERANDS);
		    return 0;
		  }
		expP = &im_expressions[i.imm_operands++];
		memset (expP, 0, sizeof(*expP));
		expP->X_op = O_symbol;
		expP->X_add_symbol = intel_state.seg;
		i.op[this_operand].imms = expP;

		resolve_expression (expP);
		operand_type_set (&types, ~0);
		if (!i386_finalize_immediate (S_GET_SEGMENT (intel_state.seg),
					      expP, types, operand_string))
		  return 0;
		if (i.operands < MAX_OPERANDS)
		  {
		    this_operand = i.operands++;
		    i.types[this_operand].bitfield.unspecified = 1;
		  }
		if (suffix == LONG_DOUBLE_MNEM_SUFFIX)
		  i.suffix = 0;
		intel_state.seg = NULL;
		intel_state.is_mem = 0;
	      }
	    break;
	  default:
	    i.types[this_operand].bitfield.jumpabsolute = 1;
	    break;
	  }
      if (i.types[this_operand].bitfield.jumpabsolute)
	intel_state.is_mem |= 1;
    }
  else if (intel_state.seg)
    intel_state.is_mem |= 1;

  if (i.op[this_operand].regs)
    {
      i386_operand_type temp;

      /* Register operand.  */
      if (intel_state.base || intel_state.index || intel_state.seg)
	{
	  as_bad (_("invalid operand"));
	  return 0;
	}

      temp = i.op[this_operand].regs->reg_type;
      temp.bitfield.baseindex = 0;
      i.types[this_operand] = operand_type_or (i.types[this_operand], temp);
      i.types[this_operand].bitfield.unspecified = 0;
      ++i.reg_operands;
    }
  else if (intel_state.base || intel_state.index || intel_state.seg
	   || intel_state.is_mem)
    {
      /* Memory operand.  */
      if (i.mem_operands
	  >= 2 - !current_templates->start->opcode_modifier.isstring)
	{
	  as_bad (_("too many memory references for `%s'"),
		  current_templates->start->name);
	  return 0;
	}

      expP = &disp_expressions[i.disp_operands];
      memcpy (expP, &exp, sizeof(exp));
      resolve_expression (expP);

      if (expP->X_op != O_constant || expP->X_add_number
	  || (!intel_state.base && !intel_state.index))
	{
	  i.op[this_operand].disps = expP;
	  i.disp_operands++;

	  if (flag_code == CODE_64BIT)
	    {
	      i.types[this_operand].bitfield.disp32 = 1;
	      if (!i.prefix[ADDR_PREFIX])
		{
		  i.types[this_operand].bitfield.disp64 = 1;
		  i.types[this_operand].bitfield.disp32s = 1;
		}
	    }
	  else if (!i.prefix[ADDR_PREFIX] ^ (flag_code == CODE_16BIT))
	    i.types[this_operand].bitfield.disp32 = 1;
	  else
	    i.types[this_operand].bitfield.disp16 = 1;

#if defined (OBJ_AOUT) || defined (OBJ_MAYBE_AOUT)
	  /*
	   * exp_seg is used only for verification in
	   * i386_finalize_displacement, and we can end up seeing reg_section
	   * here - but we know we removed all registers from the expression
	   * (or error-ed on any remaining ones) in i386_intel_simplify.  I
	   * consider the check in i386_finalize_displacement bogus anyway, in
	   * particular because it doesn't allow for expr_section, so I'd
	   * rather see that check (and the similar one in
	   * i386_finalize_immediate) use SEG_NORMAL(), but not being an a.out
	   * expert I can't really say whether that would have other bad side
	   * effects.
	   */
	  if (OUTPUT_FLAVOR == bfd_target_aout_flavour
	      && exp_seg == reg_section)
	    exp_seg = expP->X_op != O_constant ? undefined_section
					       : absolute_section;
#endif

	  if (!i386_finalize_displacement (exp_seg, expP,
					   intel_state.reloc_types,
					   operand_string))
	    return 0;
	}

      if (intel_state.base || intel_state.index)
	i.types[this_operand].bitfield.baseindex = 1;

      if (intel_state.seg)
	{
	  for (;;)
	    {
	      expP = symbol_get_value_expression (intel_state.seg);
	      if (expP->X_op != O_full_ptr)
		break;
	      intel_state.seg = expP->X_add_symbol;
	    }
	  if (expP->X_op != O_register)
	    {
	      as_bad (_("segment register name expected"));
	      return 0;
	    }
	  if (!i386_regtab[expP->X_add_number].reg_type.bitfield.sreg2
	      && !i386_regtab[expP->X_add_number].reg_type.bitfield.sreg3)
	    {
	      as_bad (_("invalid use of register"));
	      return 0;
	    }
	  switch (i386_regtab[expP->X_add_number].reg_num)
	    {
	    case 0: i.seg[i.mem_operands] = &es; break;
	    case 1: i.seg[i.mem_operands] = &cs; break;
	    case 2: i.seg[i.mem_operands] = &ss; break;
	    case 3: i.seg[i.mem_operands] = &ds; break;
	    case 4: i.seg[i.mem_operands] = &fs; break;
	    case 5: i.seg[i.mem_operands] = &gs; break;
	    case RegFlat: i.seg[i.mem_operands] = NULL; break;
	    }
	}

      /* Swap base and index in 16-bit memory operands like
	 [si+bx]. Since i386_index_check is also used in AT&T
	 mode we have to do that here.  */
      if (intel_state.base
	  && intel_state.index
	  && intel_state.base->reg_type.bitfield.reg16
	  && intel_state.index->reg_type.bitfield.reg16
	  && intel_state.base->reg_num >= 6
	  && intel_state.index->reg_num < 6)
	{
	  i.base_reg = intel_state.index;
	  i.index_reg = intel_state.base;
	}
      else
	{
	  i.base_reg = intel_state.base;
	  i.index_reg = intel_state.index;
	}

      if (!i386_index_check (operand_string))
	return 0;

      i.types[this_operand].bitfield.mem = 1;
      ++i.mem_operands;
    }
  else
    {
      /* Immediate.  */
      if (i.imm_operands >= MAX_IMMEDIATE_OPERANDS)
	{
	  as_bad (_("at most %d immediate operands are allowed"),
		  MAX_IMMEDIATE_OPERANDS);
	  return 0;
	}

      expP = &im_expressions[i.imm_operands++];
      i.op[this_operand].imms = expP;
      *expP = exp;

      return i386_finalize_immediate (exp_seg, expP, intel_state.reloc_types,
				      operand_string);
    }

  return 1;
}
Esempio n. 24
0
File: lex.c Progetto: mikekap/wine
static int parse_numeric_literal(parser_ctx_t *ctx, literal_t **literal)
{
    LONG l, d;

    l = *ctx->ptr++ - '0';
    if(ctx->ptr == ctx->end) {
        *literal = new_int_literal(ctx, l);
        return tNumericLiteral;
    }

    if(!l) {
        if(*ctx->ptr == 'x' || *ctx->ptr == 'X') {
            if(++ctx->ptr == ctx->end) {
                ERR("unexpexted end of file\n");
                return 0;
            }

            while(ctx->ptr < ctx->end && (d = hex_to_int(*ctx->ptr)) != -1) {
                l = l*16 + d;
                ctx->ptr++;
            }

            if(ctx->ptr < ctx->end && is_identifier_char(*ctx->ptr)) {
                WARN("unexpected identifier char\n");
                return lex_error(ctx, E_FAIL);
            }

            *literal = new_int_literal(ctx, l);
            return tNumericLiteral;
        }

        if(isdigitW(*ctx->ptr) || is_identifier_char(*ctx->ptr)) {
            WARN("wrong char after zero\n");
            return lex_error(ctx, E_FAIL);
        }

        *literal = new_int_literal(ctx, 0);
    }

    while(ctx->ptr < ctx->end && isdigitW(*ctx->ptr))
    {
        d = l*10 + *(ctx->ptr)-'0';

        /* Check for integer overflow */
        if (l > INT_MAX/10 || d < 0)
            return parse_double_literal(ctx, l, literal);

        l = d;
        ctx->ptr++;
    }

    if(ctx->ptr < ctx->end) {
        if(*ctx->ptr == '.' || *ctx->ptr == 'e' || *ctx->ptr == 'E')
            return parse_double_literal(ctx, l, literal);

        if(is_identifier_char(*ctx->ptr)) {
            WARN("unexpected identifier char\n");
            return lex_error(ctx, E_FAIL);
        }
    }

    *literal = new_int_literal(ctx, l);
    return tNumericLiteral;
}
Esempio n. 25
0
static BOOL parse_double_literal(parser_ctx_t *ctx, LONG int_part, double *ret)
{
    LONGLONG d, hlp;
    int exp = 0;

    d = int_part;
    while(ctx->ptr < ctx->end && isdigitW(*ctx->ptr)) {
        hlp = d*10 + *(ctx->ptr++) - '0';
        if(d>MAXLONGLONG/10 || hlp<0) {
            exp++;
            break;
        }
        else
            d = hlp;
    }
    while(ctx->ptr < ctx->end && isdigitW(*ctx->ptr)) {
        exp++;
        ctx->ptr++;
    }

    if(*ctx->ptr == '.') {
        ctx->ptr++;

        while(ctx->ptr < ctx->end && isdigitW(*ctx->ptr)) {
            hlp = d*10 + *(ctx->ptr++) - '0';
            if(d>MAXLONGLONG/10 || hlp<0)
                break;

            d = hlp;
            exp--;
        }
        while(ctx->ptr < ctx->end && isdigitW(*ctx->ptr))
            ctx->ptr++;
    }

    if(ctx->ptr < ctx->end && (*ctx->ptr == 'e' || *ctx->ptr == 'E')) {
        int sign = 1, e = 0;

        ctx->ptr++;
        if(ctx->ptr < ctx->end) {
            if(*ctx->ptr == '+') {
                ctx->ptr++;
            }else if(*ctx->ptr == '-') {
                sign = -1;
                ctx->ptr++;
            }else if(!isdigitW(*ctx->ptr)) {
                WARN("Expected exponent part\n");
                lex_error(ctx, E_FAIL);
                return FALSE;
            }
        }

        if(ctx->ptr == ctx->end) {
            WARN("unexpected end of file\n");
            lex_error(ctx, E_FAIL);
            return FALSE;
        }

        while(ctx->ptr < ctx->end && isdigitW(*ctx->ptr)) {
            if(e > INT_MAX/10 || (e = e*10 + *ctx->ptr++ - '0')<0)
                e = INT_MAX;
        }
        e *= sign;

        if(exp<0 && e<0 && e+exp>0) exp = INT_MIN;
        else if(exp>0 && e>0 && e+exp<0) exp = INT_MAX;
        else exp += e;
    }

    if(is_identifier_char(*ctx->ptr)) {
        WARN("wrong char after zero\n");
        lex_error(ctx, JS_E_MISSING_SEMICOLON);
        return FALSE;
    }

    *ret = exp>=0 ? d*pow(10, exp) : d/pow(10, -exp);
    return TRUE;
}
Esempio n. 26
0
static BOOL parse_numeric_literal(parser_ctx_t *ctx, double *ret)
{
    HRESULT hres;

    if(*ctx->ptr == '0') {
        ctx->ptr++;

        if(*ctx->ptr == 'x' || *ctx->ptr == 'X') {
            double r = 0;
            int d;
            if(++ctx->ptr == ctx->end) {
                ERR("unexpected end of file\n");
                return FALSE;
            }

            while(ctx->ptr < ctx->end && (d = hex_to_int(*ctx->ptr)) != -1) {
                r = r*16 + d;
                ctx->ptr++;
            }

            if(ctx->ptr < ctx->end && is_identifier_char(*ctx->ptr)) {
                WARN("unexpected identifier char\n");
                lex_error(ctx, JS_E_MISSING_SEMICOLON);
                return FALSE;
            }

            *ret = r;
            return TRUE;
        }

        if(isdigitW(*ctx->ptr)) {
            unsigned base = 8;
            const WCHAR *ptr;
            double val = 0;

            for(ptr = ctx->ptr; ptr < ctx->end && isdigitW(*ptr); ptr++) {
                if(*ptr > '7') {
                    base = 10;
                    break;
                }
            }

            do {
                val = val*base + *ctx->ptr-'0';
            }while(++ctx->ptr < ctx->end && isdigitW(*ctx->ptr));

            /* FIXME: Do we need it here? */
            if(ctx->ptr < ctx->end && (is_identifier_char(*ctx->ptr) || *ctx->ptr == '.')) {
                WARN("wrong char after octal literal: '%c'\n", *ctx->ptr);
                lex_error(ctx, JS_E_MISSING_SEMICOLON);
                return FALSE;
            }

            *ret = val;
            return TRUE;
        }

        if(is_identifier_char(*ctx->ptr)) {
            WARN("wrong char after zero\n");
            lex_error(ctx, JS_E_MISSING_SEMICOLON);
            return FALSE;
        }
    }

    hres = parse_decimal(&ctx->ptr, ctx->end, ret);
    if(FAILED(hres)) {
        lex_error(ctx, hres);
        return FALSE;
    }

    return TRUE;
}
Esempio n. 27
0
HRESULT parse_decimal(const WCHAR **iter, const WCHAR *end, double *ret)
{
    const WCHAR *ptr = *iter;
    LONGLONG d = 0, hlp;
    int exp = 0;

    while(ptr < end && isdigitW(*ptr)) {
        hlp = d*10 + *(ptr++) - '0';
        if(d>MAXLONGLONG/10 || hlp<0) {
            exp++;
            break;
        }
        else
            d = hlp;
    }
    while(ptr < end && isdigitW(*ptr)) {
        exp++;
        ptr++;
    }

    if(*ptr == '.') {
        ptr++;

        while(ptr < end && isdigitW(*ptr)) {
            hlp = d*10 + *(ptr++) - '0';
            if(d>MAXLONGLONG/10 || hlp<0)
                break;

            d = hlp;
            exp--;
        }
        while(ptr < end && isdigitW(*ptr))
            ptr++;
    }

    if(ptr < end && (*ptr == 'e' || *ptr == 'E')) {
        int sign = 1, e = 0;

        if(++ptr < end) {
            if(*ptr == '+') {
                ptr++;
            }else if(*ptr == '-') {
                sign = -1;
                ptr++;
            }else if(!isdigitW(*ptr)) {
                WARN("Expected exponent part\n");
                return E_FAIL;
            }
        }

        if(ptr == end) {
            WARN("unexpected end of file\n");
            return E_FAIL;
        }

        while(ptr < end && isdigitW(*ptr)) {
            if(e > INT_MAX/10 || (e = e*10 + *ptr++ - '0')<0)
                e = INT_MAX;
        }
        e *= sign;

        if(exp<0 && e<0 && e+exp>0) exp = INT_MIN;
        else if(exp>0 && e>0 && e+exp<0) exp = INT_MAX;
        else exp += e;
    }

    if(is_identifier_char(*ptr)) {
        WARN("wrong char after zero\n");
        return JS_E_MISSING_SEMICOLON;
    }

    *ret = exp>=0 ? d*pow(10, exp) : d/pow(10, -exp);
    *iter = ptr;
    return S_OK;
}
Esempio n. 28
0
static int cc_token(parser_ctx_t *ctx, void *lval)
{
    unsigned id_len = 0;
    cc_var_t *var;

    static const WCHAR cc_onW[] = {'c','c','_','o','n',0};
    static const WCHAR setW[] = {'s','e','t',0};

    ctx->ptr++;

    if(!check_keyword(ctx, cc_onW, NULL))
        return init_cc(ctx) ? 0 : -1;

    if(!check_keyword(ctx, setW, NULL)) {
        const WCHAR *ident;
        unsigned ident_len;
        cc_var_t *var;

        if(!init_cc(ctx))
            return -1;

        if(!skip_spaces(ctx))
            return lex_error(ctx, JS_E_EXPECTED_AT);

        if(!parse_cc_identifier(ctx, &ident, &ident_len))
            return -1;

        if(!skip_spaces(ctx) || *ctx->ptr != '=')
            return lex_error(ctx, JS_E_EXPECTED_ASSIGN);
        ctx->ptr++;

        if(!parse_cc_expr(ctx)) {
            WARN("parsing CC expression failed\n");
            return -1;
        }

        var = find_cc_var(ctx->script->cc, ident, ident_len);
        if(var) {
            var->val = ctx->ccval;
        }else {
            if(!new_cc_var(ctx->script->cc, ident, ident_len, ctx->ccval))
                return lex_error(ctx, E_OUTOFMEMORY);
        }

        return 0;
    }

    if(!check_keyword(ctx, ifW, NULL)) {
        if(!init_cc(ctx))
            return -1;

        if(!skip_spaces(ctx) || *ctx->ptr != '(')
            return lex_error(ctx, JS_E_MISSING_LBRACKET);

        if(!parse_cc_expr(ctx))
            return -1;

        if(get_ccbool(ctx->ccval)) {
            /* continue parsing block inside if */
            ctx->cc_if_depth++;
            return 0;
        }

        return skip_code(ctx, TRUE);
    }

    if(!check_keyword(ctx, elifW, NULL) || !check_keyword(ctx, elseW, NULL)) {
        if(!ctx->cc_if_depth)
            return lex_error(ctx, JS_E_SYNTAX);

        return skip_code(ctx, FALSE);
    }

    if(!check_keyword(ctx, endW, NULL)) {
        if(!ctx->cc_if_depth)
            return lex_error(ctx, JS_E_SYNTAX);

        ctx->cc_if_depth--;
        return 0;
    }

    if(!ctx->script->cc)
        return lex_error(ctx, JS_E_DISABLED_CC);

    while(ctx->ptr+id_len < ctx->end && is_identifier_char(ctx->ptr[id_len]))
        id_len++;
    if(!id_len)
        return '@';

    TRACE("var %s\n", debugstr_wn(ctx->ptr, id_len));

    var = find_cc_var(ctx->script->cc, ctx->ptr, id_len);
    ctx->ptr += id_len;
    if(!var || var->val.is_num) {
        *(literal_t**)lval = new_double_literal(ctx, var ? var->val.u.n : NAN);
        return tNumericLiteral;
    }

    *(literal_t**)lval = new_boolean_literal(ctx, var->val.u.b);
    return tBooleanLiteral;
}
Esempio n. 29
0
void classbrowser_parse_file(Classbrowser_Backend *classback, gchar *filename)
{
  gchar *file_contents;
  gchar *o; // original pointer to start of contents
  gchar *c; // current position within contents
  #ifdef DEBUG  
    //debug var
    gchar *sss, *dss, *scs, *mcs, *hss;
  #endif  

  gboolean within_php;
  gboolean within_single_line_comment;
  gboolean within_multi_line_comment;
  gboolean within_heredoc;
  //gboolean within_nowdoc;
  gboolean within_single_string;
  gboolean within_double_string;
  guint brace_count;
  guint parenthesis_count;
  guint line_number;

  gchar *heredoc_tag_start;
  gchar *heredoc_closingtag;
  guint heredoctag_length = 0;
  gboolean looking_for_heredocident;

  gchar *within_class;
  guint class_length = 0;
  gboolean looking_for_class_name;
  gboolean within_class_name;
  gchar *start_class_name = NULL;
  gchar *within_function;
  guint function_length = 0;
  gboolean looking_for_function_name;
  gboolean within_function_name;
  gchar *start_function_name = NULL;
  gboolean within_function_param_list;
  gchar *start_param_list;
  gchar *param_list;
  guint param_list_length;
  gboolean function_awaiting_brace_or_parenthesis;

  gboolean posiblevar=FALSE;
  gchar *startvarname=NULL;
  gchar *posvarname=NULL;
  gchar *varname=NULL;
  gchar *beforevarname=NULL;

  within_php = FALSE;
  within_single_line_comment = FALSE;
  within_multi_line_comment = FALSE;
  within_single_string = FALSE;
  within_double_string = FALSE;
  within_heredoc = FALSE;
  looking_for_heredocident = FALSE;
  heredoc_closingtag = NULL;
  heredoc_tag_start = NULL;
  
  brace_count = 0;
  line_number = 1;
  within_class = NULL;
  looking_for_class_name = FALSE;
  within_class_name = FALSE;
  within_function = NULL;
  looking_for_function_name = FALSE;
  within_function_name = FALSE;
  within_function_param_list = FALSE;
  start_param_list = NULL;
  param_list = NULL;
  function_awaiting_brace_or_parenthesis = FALSE;

  g_return_if_fail(filename);
  file_contents = read_text_file(filename);
  g_return_if_fail(file_contents);
  o = file_contents;
  c = o;

  while (*c) {
    if (!within_php) {
      if (check_previous(o, c, "<?")) {
        within_php=TRUE;
      }
    } else {
      if (within_single_line_comment && is_newline(*c)) {
        #ifdef DEBUG
        str_sec_print("SLC", scs, c, line_number);
        #endif
        within_single_line_comment = FALSE;
      }
      else if (within_multi_line_comment && check_previous(o, c, "*/")) {
      #ifdef DEBUG
        str_sec_print("MLC", mcs, c, line_number);
      #endif
        within_multi_line_comment = FALSE;
      }
      //escaped single quote within single quoted string does not end the string 
      //single quote ends single quoted string
      if (within_single_string && *c=='\'' && !check_previous(o, c, "\\'")) {
      #ifdef DEBUG
        str_sec_print("SQS", sss, c, line_number);
      #endif
        within_single_string = FALSE;
      }
      //escaped double quote within double quoted string does not end the string 
      //double quote ends double quoted string
      else if (within_double_string && *c=='"' && !check_previous(o, c, "\\\"")) {
      #ifdef DEBUG
        str_sec_print("DQS", dss, c, line_number);
      #endif
        within_double_string = FALSE;
      }
      ///heredocs have custom closing tags. check it from the opening tag
      else if (within_heredoc && !looking_for_heredocident && *c=='\n' && (check_previous(o, c-1, heredoc_closingtag) || (*(c-1) == ';' && check_previous(o, c-2, heredoc_closingtag)))) {
      #ifdef DEBUG
        gphpedit_debug_message(DEBUG_CLASSBROWSER_PARSE, "%s(%d): End Heredoc", filename, line_number);
        str_sec_print("HDS", hss, c, line_number);
      #endif
        g_free(heredoc_closingtag);
        within_heredoc = FALSE;
      }
      else if (within_heredoc && looking_for_heredocident && *c == '\n') {
        //if nowdoc
        if (*heredoc_tag_start == '\'') {
          //-2 for the two single quotes
          heredoctag_length = c - heredoc_tag_start - 2;           
          heredoc_closingtag = g_malloc(heredoctag_length + 1);
          strncpy(heredoc_closingtag, heredoc_tag_start + 1, heredoctag_length);
          heredoc_closingtag[heredoctag_length]='\0';
          #ifdef DEBUG
            gphpedit_debug_message(DEBUG_CLASSBROWSER_PARSE,"Expecting Nowdoc closing tag: %s\n", heredoc_closingtag);
          #endif
        }
        else {
          heredoctag_length = c - heredoc_tag_start;           
          heredoc_closingtag = g_malloc(heredoctag_length + 1);
          strncpy(heredoc_closingtag, heredoc_tag_start, heredoctag_length);
          heredoc_closingtag[heredoctag_length]='\0';
          #ifdef DEBUG
          gphpedit_debug_message(DEBUG_CLASSBROWSER_PARSE, "Expecting Heredoc closing tag: %s", heredoc_closingtag);
          #endif
        }
        looking_for_heredocident = FALSE;
      }
      //if not within comments or strings or heredocs
      else if (!within_multi_line_comment && !within_single_line_comment && !within_double_string && !within_single_string && !within_heredoc) {
        if (check_previous(o, c, "?>")) {
          within_php = FALSE;
        }
        //when does the second condition happen?
        //you are already outside a string. you can't have a backslash 
        //just before a new opening single quote
        else if (*c == '\'' && !check_previous(o, c, "\\'")) {
          within_single_string=TRUE;
          #ifdef DEBUG
          sss = c;
          gphpedit_debug_message(DEBUG_CLASSBROWSER_PARSE,"Found Single Quoted String: %d", line_number);
          #endif
        }
        //when does the second condition happen?
        else if (*c == '"' && !check_previous(o, c, "\\\"")) {
          within_double_string=TRUE;
          #ifdef DEBUG
          dss = c;
          gphpedit_debug_message(DEBUG_CLASSBROWSER_PARSE, "Found Double Quoted String: %d", line_number);
          #endif
        }
        //more efficient to call function only when needed hence the first check
        else if (*c == '<' && check_previous(o, c, "<<<")) {
          #ifdef DEBUG
          hss = c-2;
          gphpedit_debug_message(DEBUG_CLASSBROWSER_PARSE, "%s(%d): Found Heredoc", filename, line_number);
          #endif
          within_heredoc=TRUE;
          heredoc_tag_start = c+1;
          looking_for_heredocident = TRUE;
        }
        //more efficient to call function only when needed hence the first check
        else if (*c == '/' && check_previous(o, c, "//")) {
          #ifdef DEBUG
          scs = c-1;
          gphpedit_debug_message(DEBUG_CLASSBROWSER_PARSE, "%s(%d): Found Single Line Comment", filename, line_number);
          #endif
          within_single_line_comment = TRUE;
        }
        //more efficient to call function only when needed hence the first check
        else if (*c == '*' && check_previous(o, c, "/*")) {
          #ifdef DEBUG
          mcs = c-1;
          gphpedit_debug_message(DEBUG_CLASSBROWSER_PARSE, "%s(%d): Found Multi Line Comment", filename, line_number);
          #endif
          within_multi_line_comment = TRUE;
        }
        else {
          if (check_previous(o, c, "class ") && non_letter_before(o, c, "class ")) {
            #ifdef DEBUG
            gphpedit_debug_message(DEBUG_CLASSBROWSER_PARSE, "%s(%d): Found Class", filename, line_number);
            #endif
            looking_for_class_name = TRUE;
          }
          else if (is_identifier_char(*c) && looking_for_class_name && !within_class_name) {
            start_class_name = c-1;
            looking_for_class_name = FALSE;
            within_class_name = TRUE;
          }
          else if ( (is_whitespace(*c) || is_opening_brace(*c)) && within_class_name) {
            class_length = (c - start_class_name);
            if (within_class) {
              g_free(within_class);
            }
            within_class = g_malloc(class_length+1);
            strncpy(within_class, start_class_name, class_length);
            within_class[class_length]='\0';
            #ifdef DEBUG
              gphpedit_debug_message(DEBUG_CLASSBROWSER_PARSE, "%s(%d): Class '%s'", filename, line_number, within_class);
            #endif
            classbrowser_classlist_add(classback, within_class, filename, line_number,TAB_PHP);
            within_class_name = FALSE;
          }
          else if (check_previous(o, c, "function ") && non_letter_before(o, c, "function ")) {
            #ifdef DEBUG
              gphpedit_debug_message(DEBUG_CLASSBROWSER_PARSE,"%s","Looking for function name");
            #endif
            looking_for_function_name = TRUE;
          }
          if (is_identifier_char(*c) && looking_for_function_name && !within_function_name) {
            #ifdef DEBUG
              gphpedit_debug_message(DEBUG_CLASSBROWSER_PARSE,"%s", "Storing function name");
            #endif
            start_function_name = c;
            function_length = 0;
            looking_for_function_name = FALSE;
            within_function_name = TRUE;
          }
          if ( (is_whitespace(*c) || is_opening_brace(*c) || is_opening_parenthesis(*c)) && within_function_name && function_length==0) {
            #ifdef DEBUG
              gphpedit_debug_message(DEBUG_CLASSBROWSER_PARSE,"%s", "Found function");
            #endif
            function_length = (c - start_function_name);
            if (within_function) {
              g_free(within_function);
            }
            within_function = g_malloc(function_length+1);
            strncpy(within_function, start_function_name, function_length);
            within_function[function_length]='\0';
            function_awaiting_brace_or_parenthesis = TRUE;
            within_function_name = FALSE;
          }

          if ( function_awaiting_brace_or_parenthesis && is_opening_brace(*c)) {
            function_awaiting_brace_or_parenthesis = FALSE;
            if (within_class) {
              classbrowser_functionlist_add(classback,within_class, within_function, filename, TAB_PHP, line_number, NULL);
              #ifdef DEBUG
                gphpedit_debug_message(DEBUG_CLASSBROWSER_PARSE, "%s(%d): Class method %s::%s", filename, line_number, within_class, within_function);
              #endif
            }
            else {
              classbrowser_functionlist_add(classback,NULL, within_function, filename, TAB_PHP, line_number, NULL);
              #ifdef DEBUG
                gphpedit_debug_message(DEBUG_CLASSBROWSER_PARSE, "%s(%d): Function %s", filename, line_number, within_function);
              #endif
            }
          }
          else if (function_awaiting_brace_or_parenthesis && is_opening_parenthesis(*c)) {
            within_function_param_list = TRUE;
            start_param_list = c+1;
            function_awaiting_brace_or_parenthesis = FALSE;
          }
          else if (is_closing_parenthesis(*c) && within_function_param_list) {
            param_list_length = (c - start_param_list);
            if (param_list) {
              g_free(param_list);
            }
            param_list = g_malloc(param_list_length+1);
            strncpy(param_list, start_param_list, param_list_length);
            param_list[param_list_length]='\0';
            if (within_class) {
              classbrowser_functionlist_add(classback, within_class, within_function, filename, TAB_PHP, line_number, param_list);
              #ifdef DEBUG
                gphpedit_debug_message(DEBUG_CLASSBROWSER_PARSE, "%s(%d): Class method %s::%s(%s)", filename, line_number, within_class, within_function, param_list);
              #endif
            }
            else {
              classbrowser_functionlist_add(classback, NULL, within_function, filename, TAB_PHP,line_number, param_list);
              #ifdef DEBUG
                gphpedit_debug_message(DEBUG_CLASSBROWSER_PARSE, "%s(%d): Function %s(%s)", filename, line_number, within_function, param_list);
              #endif
            }
            within_function_param_list = FALSE;
          }
          if (posiblevar){
            if (is_identifier_char(*c)){
              posvarname=c;
            } else {
              //g_print("char:%c ret:false\n",*c);
              posiblevar=FALSE;
            int len=posvarname - startvarname +1; /*include initial $*/
              if (len>1){ /*only if we have $ and something more */
                varname = g_malloc(len +1);
                strncpy(varname,startvarname,len);
                varname[len]='\0';
                if (!beforevarname){ beforevarname=g_strdup(varname); /*store last variable name found*/
                } else {
                  if (strcmp(beforevarname,varname)==0){
                    #ifdef DEBUG
                    gphpedit_debug_message(DEBUG_CLASSBROWSER_PARSE, "Duplicate variable: %s",varname);
                    #endif
                  } else {
                    #ifdef DEBUG
                    gphpedit_debug_message(DEBUG_CLASSBROWSER_PARSE, "Classbrowser var added:%s",varname);
                    #endif
                    classbrowser_varlist_add(classback, varname, within_function, filename);
                    g_free(beforevarname);
                    beforevarname=g_strdup(varname);
                  }
                }
                g_free(varname);
              }
            }
          }
          if (*c=='$' && !within_function_param_list && !within_multi_line_comment && !within_single_line_comment){ /* skip params vars */
            posiblevar=TRUE;
            startvarname=c;
          }
          if (is_opening_brace(*c)) {
            brace_count++;
            #ifdef DEBUG
              gphpedit_debug_message(DEBUG_CLASSBROWSER_PARSE,"Brace count %d:%c", brace_count, *c);
            #endif
          }
          else if (is_closing_brace(*c)) {
            brace_count--;
            #ifdef DEBUG
              gphpedit_debug_message(DEBUG_CLASSBROWSER_PARSE,"Brace count %d:%c", brace_count, *c);
            #endif
            if (brace_count == 0) {
              if (within_class) {
                #ifdef DEBUG
                  gphpedit_debug_message(DEBUG_CLASSBROWSER_PARSE, "Freeing class %s", within_class);
                #endif
                g_free(within_class);
                within_class = NULL;
              }
            }
          }
          else if (is_opening_parenthesis(*c)) {
            parenthesis_count++;
          }
          else if (is_closing_parenthesis(*c)) {
            parenthesis_count--;
          }
        }
      }
    }
    if (is_newline(*c)) {
      line_number++;
    }
    c++;
  }
  if (param_list) g_free(param_list);
  if (within_function) g_free(within_function);
  if (beforevarname) g_free(beforevarname);
  g_free(file_contents);
}