Print this page
new smatch


 145 
 146 struct expression *string_expression(char *str)
 147 {
 148         struct expression *ret;
 149         struct string *string;
 150         int len;
 151 
 152         len = strlen(str) + 1;
 153         string = (void *)__alloc_sname(4 + len);
 154         string->length = len;
 155         string->immutable = 0;
 156         memcpy(string->data, str, len);
 157 
 158         ret = alloc_tmp_expression(get_cur_pos(), EXPR_STRING);
 159         ret->wide = 0;
 160         ret->string = string;
 161 
 162         return ret;
 163 }
 164 












































































 165 struct expression *gen_expression_from_key(struct expression *arg, const char *key)
 166 {
 167         struct expression *ret;
 168         struct token *token, *prev, *end;
 169         const char *p = key;
 170         char buf[4095];
 171         char *alloc;
 172         size_t len;
 173 
 174         /* The idea is that we can parse either $0->foo or $->foo */
 175         if (key[0] != '$')
 176                 return NULL;
 177         p++;
 178         while (*p >= '0' && *p <= '9')
 179                 p++;
 180         len = snprintf(buf, sizeof(buf), "%s\n", p);
 181         alloc = alloc_string(buf);
 182 
 183         token = tokenize_buffer(alloc, len, &end);
 184         if (!token)




 145 
 146 struct expression *string_expression(char *str)
 147 {
 148         struct expression *ret;
 149         struct string *string;
 150         int len;
 151 
 152         len = strlen(str) + 1;
 153         string = (void *)__alloc_sname(4 + len);
 154         string->length = len;
 155         string->immutable = 0;
 156         memcpy(string->data, str, len);
 157 
 158         ret = alloc_tmp_expression(get_cur_pos(), EXPR_STRING);
 159         ret->wide = 0;
 160         ret->string = string;
 161 
 162         return ret;
 163 }
 164 
 165 static struct expression *get_expression_from_base_and_str(struct expression *base, const char *addition)
 166 {
 167         struct expression *ret = NULL;
 168         struct token *token, *prev, *end;
 169         char *alloc;
 170 
 171         if (addition[0] == '\0')
 172                 return base;
 173 
 174         alloc = alloc_string_newline(addition);
 175 
 176         token = tokenize_buffer(alloc, strlen(alloc), &end);
 177         if (!token)
 178                 goto free;
 179         if (token_type(token) != TOKEN_STREAMBEGIN)
 180                 goto free;
 181         token = token->next;
 182 
 183         ret = base;
 184         while (token_type(token) == TOKEN_SPECIAL &&
 185                (token->special == SPECIAL_DEREFERENCE || token->special == '.')) {
 186                 prev = token;
 187                 token = token->next;
 188                 if (token_type(token) != TOKEN_IDENT)
 189                         goto free;
 190                 switch (prev->special) {
 191                 case SPECIAL_DEREFERENCE:
 192                         ret = deref_expression(ret);
 193                         ret = member_expression(ret, '*', token->ident);
 194                         break;
 195                 case '.':
 196                         ret = member_expression(ret, '.', token->ident);
 197                         break;
 198                 default:
 199                         goto free;
 200                 }
 201                 token = token->next;
 202         }
 203 
 204         if (token_type(token) != TOKEN_STREAMEND)
 205                 goto free;
 206 
 207 free:
 208         free_string(alloc);
 209 
 210         return ret;
 211 }
 212 
 213 struct expression *gen_expression_from_name_sym(const char *name, struct symbol *sym)
 214 {
 215         struct expression *base;
 216         int skip = 0;
 217         struct expression *ret;
 218 
 219         if (!name || !sym)
 220                 return NULL;
 221 
 222         base = symbol_expression(sym);
 223         while (name[skip] != '\0' && name[skip] != '.' && name[skip] != '-')
 224                 skip++;
 225 
 226         ret = get_expression_from_base_and_str(base, name + skip);
 227         if (ret) {
 228                 char *new = expr_to_str(ret);
 229 
 230                 /*
 231                  * FIXME: this sometimes changes "foo->bar.a.b->c" into
 232                  * "foo->bar.a.b.c".  I don't know why...  :(
 233                  *
 234                  */
 235                 if (!new || strcmp(name, new) != 0)
 236                         return NULL;
 237         }
 238         return ret;
 239 }
 240 
 241 struct expression *gen_expression_from_key(struct expression *arg, const char *key)
 242 {
 243         struct expression *ret;
 244         struct token *token, *prev, *end;
 245         const char *p = key;
 246         char buf[4095];
 247         char *alloc;
 248         size_t len;
 249 
 250         /* The idea is that we can parse either $0->foo or $->foo */
 251         if (key[0] != '$')
 252                 return NULL;
 253         p++;
 254         while (*p >= '0' && *p <= '9')
 255                 p++;
 256         len = snprintf(buf, sizeof(buf), "%s\n", p);
 257         alloc = alloc_string(buf);
 258 
 259         token = tokenize_buffer(alloc, len, &end);
 260         if (!token)