Print this page
new smatch

*** 160,169 **** --- 160,245 ---- ret->string = string; return ret; } + static struct expression *get_expression_from_base_and_str(struct expression *base, const char *addition) + { + struct expression *ret = NULL; + struct token *token, *prev, *end; + char *alloc; + + if (addition[0] == '\0') + return base; + + alloc = alloc_string_newline(addition); + + token = tokenize_buffer(alloc, strlen(alloc), &end); + if (!token) + goto free; + if (token_type(token) != TOKEN_STREAMBEGIN) + goto free; + token = token->next; + + ret = base; + while (token_type(token) == TOKEN_SPECIAL && + (token->special == SPECIAL_DEREFERENCE || token->special == '.')) { + prev = token; + token = token->next; + if (token_type(token) != TOKEN_IDENT) + goto free; + switch (prev->special) { + case SPECIAL_DEREFERENCE: + ret = deref_expression(ret); + ret = member_expression(ret, '*', token->ident); + break; + case '.': + ret = member_expression(ret, '.', token->ident); + break; + default: + goto free; + } + token = token->next; + } + + if (token_type(token) != TOKEN_STREAMEND) + goto free; + + free: + free_string(alloc); + + return ret; + } + + struct expression *gen_expression_from_name_sym(const char *name, struct symbol *sym) + { + struct expression *base; + int skip = 0; + struct expression *ret; + + if (!name || !sym) + return NULL; + + base = symbol_expression(sym); + while (name[skip] != '\0' && name[skip] != '.' && name[skip] != '-') + skip++; + + ret = get_expression_from_base_and_str(base, name + skip); + if (ret) { + char *new = expr_to_str(ret); + + /* + * FIXME: this sometimes changes "foo->bar.a.b->c" into + * "foo->bar.a.b.c". I don't know why... :( + * + */ + if (!new || strcmp(name, new) != 0) + return NULL; + } + return ret; + } + struct expression *gen_expression_from_key(struct expression *arg, const char *key) { struct expression *ret; struct token *token, *prev, *end; const char *p = key;