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); }
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; }
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; }
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; }
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; }
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(); } } }
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; }
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); }
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)); }
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; }
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; }
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; }
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; }
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; }
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; }
// 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; }
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_); }
/*----------------------------------------------------------------------*/ 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; }
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); }
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); } } }
/*----------------------------------------------------------------------*/ 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; }
/* 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; }
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; }
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; }
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; }
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; }
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; }
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); }