Print this page
new smatch

Split Close
Expand all
Collapse all
          --- old/usr/src/tools/smatch/src/smatch_expressions.c
          +++ new/usr/src/tools/smatch/src/smatch_expressions.c
↓ open down ↓ 154 lines elided ↑ open up ↑
 155  155          string->immutable = 0;
 156  156          memcpy(string->data, str, len);
 157  157  
 158  158          ret = alloc_tmp_expression(get_cur_pos(), EXPR_STRING);
 159  159          ret->wide = 0;
 160  160          ret->string = string;
 161  161  
 162  162          return ret;
 163  163  }
 164  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 +
 165  241  struct expression *gen_expression_from_key(struct expression *arg, const char *key)
 166  242  {
 167  243          struct expression *ret;
 168  244          struct token *token, *prev, *end;
 169  245          const char *p = key;
 170  246          char buf[4095];
 171  247          char *alloc;
 172  248          size_t len;
 173  249  
 174  250          /* The idea is that we can parse either $0->foo or $->foo */
↓ open down ↓ 70 lines elided ↑ open up ↑
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX