Print this page
12724 update smatch to 0.6.1-rc1-il-5


 130  * get_argument_from_call_expr(expr, 0) to return the expression for
 131  * a.  Yes, it does start counting from 0.
 132  */
 133 struct expression *get_argument_from_call_expr(struct expression_list *args,
 134                                                int num)
 135 {
 136         struct expression *expr;
 137         int i = 0;
 138 
 139         if (!args)
 140                 return NULL;
 141 
 142         FOR_EACH_PTR(args, expr) {
 143                 if (i == num)
 144                         return expr;
 145                 i++;
 146         } END_FOR_EACH_PTR(expr);
 147         return NULL;
 148 }
 149 
 150 static struct expression *get_array_expr(struct expression *expr)
 151 {
 152         struct expression *parent;
 153         struct symbol *type;
 154 
 155         if (expr->type != EXPR_BINOP || expr->op != '+')
 156                 return NULL;
 157 
 158         type = get_type(expr->left);
 159         if (!type)
 160                 return NULL;
 161         if (type->type == SYM_ARRAY)
 162                 return expr->left;
 163         if (type->type != SYM_PTR)
 164                 return NULL;
 165 
 166         parent = expr_get_parent_expr(expr);
 167         if (!parent)  /* Sometimes we haven't set up the ->parent yet. FIXME!! */
 168                 return expr->left;
 169         if (parent->type == EXPR_PREOP && parent->op == '*')
 170                 return expr->left;
 171 
 172         return NULL;
 173 }
 174 
 175 static void __get_variable_from_expr(struct symbol **sym_ptr, char *buf,
 176                                      struct expression *expr, int len,
 177                                      int *complicated, int no_parens)
 178 {
 179 
 180 
 181         if (!expr) {
 182                 /* can't happen on valid code */
 183                 *complicated = 1;
 184                 return;
 185         }
 186 
 187         switch (expr->type) {
 188         case EXPR_DEREF: {
 189                 struct expression *deref;
 190                 int op;
 191 
 192                 deref = expr->deref;
 193                 op = deref->op;
 194                 if (deref->type == EXPR_PREOP && op == '*') {
 195                         struct expression *unop = strip_expr(deref->unop);
 196 
 197                         if (unop->type == EXPR_PREOP && unop->op == '&') {
 198                                 deref = unop->unop;
 199                                 op = '.';
 200                         } else {
 201                                 if (!is_pointer(deref) && !is_pointer(deref->unop))
 202                                         op = '.';
 203                                 deref = deref->unop;
 204                         }
 205                 }
 206 
 207                 __get_variable_from_expr(sym_ptr, buf, deref, len, complicated, no_parens);
 208 
 209                 if (op == '*')
 210                         append(buf, "->", len);
 211                 else
 212                         append(buf, ".", len);
 213 
 214                 if (expr->member)
 215                         append(buf, expr->member->name, len);
 216                 else
 217                         append(buf, "unknown_member", len);
 218 
 219                 return;
 220         }
 221         case EXPR_SYMBOL:
 222                 if (expr->symbol_name)
 223                         append(buf, expr->symbol_name->name, len);
 224                 if (sym_ptr) {
 225                         if (*sym_ptr)
 226                                 *complicated = 1;
 227                         *sym_ptr = expr->symbol;
 228                 }
 229                 return;
 230         case EXPR_PREOP: {
 231                 const char *tmp;
 232 
 233                 if (get_expression_statement(expr)) {
 234                         *complicated = 2;
 235                         return;
 236                 }
 237 
 238                 if (expr->op == '(') {
 239                         if (!no_parens && expr->unop->type != EXPR_SYMBOL)
 240                                 append(buf, "(", len);
 241                 } else if (expr->op != '*' || !get_array_expr(expr->unop)) {
 242                         tmp = show_special(expr->op);
 243                         append(buf, tmp, len);
 244                 }
 245                 __get_variable_from_expr(sym_ptr, buf, expr->unop,
 246                                                  len, complicated, no_parens);
 247 
 248                 if (expr->op == '(' && !no_parens && expr->unop->type != EXPR_SYMBOL)
 249                         append(buf, ")", len);
 250 
 251                 if (expr->op == SPECIAL_DECREMENT ||
 252                                 expr->op == SPECIAL_INCREMENT)
 253                         *complicated = 1;
 254 
 255                 return;
 256         }
 257         case EXPR_POSTOP: {
 258                 const char *tmp;
 259 
 260                 __get_variable_from_expr(sym_ptr, buf, expr->unop,
 261                                                  len, complicated, no_parens);
 262                 tmp = show_special(expr->op);
 263                 append(buf, tmp, len);
 264 
 265                 if (expr->op == SPECIAL_DECREMENT || expr->op == SPECIAL_INCREMENT)
 266                         *complicated = 1;
 267                 return;
 268         }
 269         case EXPR_ASSIGNMENT:
 270         case EXPR_COMPARE:
 271         case EXPR_LOGICAL:
 272         case EXPR_BINOP: {
 273                 char tmp[10];
 274                 struct expression *array_expr;
 275 
 276                 *complicated = 1;
 277                 array_expr = get_array_expr(expr);
 278                 if (array_expr) {
 279                         __get_variable_from_expr(sym_ptr, buf, array_expr, len, complicated, no_parens);
 280                         append(buf, "[", len);
 281                 } else {
 282                         __get_variable_from_expr(sym_ptr, buf, expr->left, len, complicated, no_parens);
 283                         snprintf(tmp, sizeof(tmp), " %s ", show_special(expr->op));
 284                         append(buf, tmp, len);
 285                 }
 286                 __get_variable_from_expr(NULL, buf, expr->right, len, complicated, no_parens);
 287                 if (array_expr)
 288                         append(buf, "]", len);
 289                 return;
 290         }
 291         case EXPR_VALUE: {
 292                 sval_t sval = {};
 293                 char tmp[25];
 294 
 295                 *complicated = 1;
 296                 if (!get_value(expr, &sval))
 297                         return;
 298                 snprintf(tmp, 25, "%s", sval_to_numstr(sval));
 299                 append(buf, tmp, len);
 300                 return;
 301         }
 302         case EXPR_FVALUE: {
 303                 sval_t sval = {};
 304                 char tmp[25];
 305 
 306                 *complicated = 1;
 307                 if (!get_value(expr, &sval))
 308                         return;
 309                 snprintf(tmp, 25, "%s", sval_to_numstr(sval));
 310                 append(buf, tmp, len);
 311                 return;
 312         }
 313         case EXPR_STRING:
 314                 append(buf, "\"", len);
 315                 if (expr->string)
 316                         append(buf, expr->string->data, len);
 317                 append(buf, "\"", len);
 318                 return;
 319         case EXPR_CALL: {
 320                 struct expression *tmp;
 321                 int i;
 322 
 323                 *complicated = 1;
 324                 __get_variable_from_expr(NULL, buf, expr->fn, len, complicated, no_parens);
 325                 append(buf, "(", len);
 326                 i = 0;
 327                 FOR_EACH_PTR(expr->args, tmp) {
 328                         if (i++)
 329                                 append(buf, ", ", len);
 330                         __get_variable_from_expr(NULL, buf, tmp, len, complicated, no_parens);
 331                 } END_FOR_EACH_PTR(tmp);
 332                 append(buf, ")", len);
 333                 return;
 334         }
 335         case EXPR_CAST:
 336         case EXPR_FORCE_CAST:
 337                 __get_variable_from_expr(sym_ptr, buf,
 338                                          expr->cast_expression, len,
 339                                          complicated, no_parens);
 340                 return;
 341         case EXPR_SIZEOF: {
 342                 sval_t sval;
 343                 int size;
 344                 char tmp[25];
 345 
 346                 if (expr->cast_type && get_base_type(expr->cast_type)) {
 347                         size = type_bytes(get_base_type(expr->cast_type));
 348                         snprintf(tmp, 25, "%d", size);
 349                         append(buf, tmp, len);
 350                 } else if (get_value(expr, &sval)) {
 351                         snprintf(tmp, 25, "%s", sval_to_str(sval));
 352                         append(buf, tmp, len);
 353                 }
 354                 return;
 355         }
 356         case EXPR_IDENTIFIER:
 357                 *complicated = 1;
 358                 if (expr->expr_ident)
 359                         append(buf, expr->expr_ident->name, len);
 360                 return;
 361         default:

 362                 *complicated = 1;
 363                 //printf("unknown type = %d\n", expr->type);






 364                 return;






 365         }


 366 }
 367 
 368 struct expr_str_cache_results {
 369         struct expression *expr;
 370         int no_parens;
 371         char str[VAR_LEN];
 372         struct symbol *sym;
 373         int complicated;
 374 };
 375 
 376 static void get_variable_from_expr(struct symbol **sym_ptr, char *buf,
 377                                      struct expression *expr, int len,
 378                                      int *complicated, int no_parens)
 379 {
 380         static struct expr_str_cache_results cached[8];
 381         struct symbol *tmp_sym = NULL;
 382         static int idx;
 383         int i;
 384 
 385         for (i = 0; i < ARRAY_SIZE(cached); i++) {
 386                 if (expr == cached[i].expr &&
 387                     no_parens == cached[i].no_parens) {
 388                         strncpy(buf, cached[i].str, len);
 389                         if (sym_ptr)
 390                                 *sym_ptr = cached[i].sym;
 391                         *complicated = cached[i].complicated;
 392                         return;
 393                 }
 394         }
 395 
 396         __get_variable_from_expr(&tmp_sym, buf, expr, len, complicated, no_parens);
 397         if (sym_ptr)
 398                 *sym_ptr = tmp_sym;
 399 



 400         cached[idx].expr = expr;
 401         cached[idx].no_parens = no_parens;
 402         strncpy(cached[idx].str, buf, VAR_LEN);
 403         cached[idx].sym = tmp_sym;
 404         cached[idx].complicated = *complicated;
 405 
 406         idx = (idx + 1) % ARRAY_SIZE(cached);
 407 }
 408 
 409 /*
 410  * This is returns a stylized "c looking" representation of the
 411  * variable name.
 412  *
 413  * It uses the same buffer every time so you have to save the result
 414  * yourself if you want to keep it.
 415  *
 416  */
 417 
 418 char *expr_to_str_sym(struct expression *expr, struct symbol **sym_ptr)
 419 {
 420         static char var_name[VAR_LEN];
 421         int complicated = 0;
 422 
 423         if (sym_ptr)
 424                 *sym_ptr = NULL;
 425         var_name[0] = '\0';
 426 
 427         if (!expr)
 428                 return NULL;
 429         get_variable_from_expr(sym_ptr, var_name, expr, sizeof(var_name),
 430                                  &complicated, 0);
 431         if (complicated < 2)
 432                 return alloc_string(var_name);
 433         else
 434                 return NULL;
 435 }
 436 
 437 char *expr_to_str(struct expression *expr)
 438 {
 439         return expr_to_str_sym(expr, NULL);
 440 }
 441 
 442 /*
 443  * get_variable_from_expr_simple() only returns simple variables.
 444  * If it's a complicated variable like a->foo[x] instead of just 'a->foo'
 445  * then it returns NULL.
 446  */
 447 char *expr_to_var_sym(struct expression *expr,
 448                                     struct symbol **sym_ptr)
 449 {
 450         static char var_name[VAR_LEN];
 451         int complicated = 0;
 452 
 453         if (sym_ptr)
 454                 *sym_ptr = NULL;
 455         var_name[0] = '\0';
 456 
 457         if (!expr)
 458                 return NULL;
 459         expr = strip_expr(expr);
 460         get_variable_from_expr(sym_ptr, var_name, expr, sizeof(var_name),
 461                                  &complicated, 1);
 462 
 463         if (complicated) {
 464                 if (sym_ptr)
 465                         *sym_ptr = NULL;
 466                 return NULL;
 467         }
 468         return alloc_string(var_name);
 469 }
 470 
 471 char *expr_to_var(struct expression *expr)
 472 {
 473         return expr_to_var_sym(expr, NULL);
 474 }
 475 
 476 struct symbol *expr_to_sym(struct expression *expr)
 477 {
 478         struct symbol *sym;
 479         char *name;
 480 
 481         name = expr_to_var_sym(expr, &sym);


1034         if (stmt->type == STMT_COMPOUND) {
1035                 last_stmt = last_ptr_list((struct ptr_list *)stmt->stmts);
1036                 if (!last_stmt)
1037                         return NULL;
1038                 if (last_stmt->type == STMT_LABEL)
1039                         last_stmt = last_stmt->label_statement;
1040                 if (last_stmt->type != STMT_EXPRESSION)
1041                         return NULL;
1042                 return last_stmt->expression;
1043         }
1044         if (stmt->type == STMT_EXPRESSION)
1045                 return stmt->expression;
1046         return NULL;
1047 }
1048 
1049 int get_param_num_from_sym(struct symbol *sym)
1050 {
1051         struct symbol *tmp;
1052         int i;
1053 
1054         if (!cur_func_sym)
1055                 return -1;
1056 















1057         i = 0;
1058         FOR_EACH_PTR(cur_func_sym->ctype.base_type->arguments, tmp) {
1059                 if (tmp == sym)
1060                         return i;
1061                 i++;
1062         } END_FOR_EACH_PTR(tmp);
1063         return -1;
1064 }
1065 
1066 int get_param_num(struct expression *expr)
1067 {
1068         struct symbol *sym;
1069         char *name;
1070 
1071         if (!cur_func_sym)
1072                 return -1;
1073         name = expr_to_var_sym(expr, &sym);
1074         free_string(name);
1075         if (!sym)
1076                 return -1;
1077         return get_param_num_from_sym(sym);
1078 }
1079 
1080 struct symbol *get_param_sym_from_num(int num)
1081 {
1082         struct symbol *sym;
1083         int i;
1084 
1085         if (!cur_func_sym)
1086                 return NULL;
1087 
1088         i = 0;
1089         FOR_EACH_PTR(cur_func_sym->ctype.base_type->arguments, sym) {
1090                 if (i++ == num)
1091                         return sym;
1092         } END_FOR_EACH_PTR(sym);
1093         return NULL;
1094 }
1095 
1096 int ms_since(struct timeval *start)




 130  * get_argument_from_call_expr(expr, 0) to return the expression for
 131  * a.  Yes, it does start counting from 0.
 132  */
 133 struct expression *get_argument_from_call_expr(struct expression_list *args,
 134                                                int num)
 135 {
 136         struct expression *expr;
 137         int i = 0;
 138 
 139         if (!args)
 140                 return NULL;
 141 
 142         FOR_EACH_PTR(args, expr) {
 143                 if (i == num)
 144                         return expr;
 145                 i++;
 146         } END_FOR_EACH_PTR(expr);
 147         return NULL;
 148 }
 149 
 150 struct expression *get_array_expr(struct expression *expr)
 151 {
 152         struct expression *parent;
 153         struct symbol *type;
 154 
 155         if (expr->type != EXPR_BINOP || expr->op != '+')
 156                 return NULL;
 157 
 158         type = get_type(expr->left);
 159         if (!type)
 160                 return NULL;
 161         if (type->type == SYM_ARRAY)
 162                 return expr->left;
 163         if (type->type != SYM_PTR)
 164                 return NULL;
 165 
 166         parent = expr_get_parent_expr(expr);
 167         if (!parent)  /* Sometimes we haven't set up the ->parent yet. FIXME!! */
 168                 return expr->left;
 169         if (parent->type == EXPR_PREOP && parent->op == '*')
 170                 return expr->left;
 171 
 172         return NULL;
 173 }
 174 
 175 static void __get_variable_from_expr(struct symbol **sym_ptr, char *buf,
 176                                      struct expression *expr, int len,
 177                                      int *complicated)
 178 {


 179         if (!expr) {
 180                 /* can't happen on valid code */
 181                 *complicated = 1;
 182                 return;
 183         }
 184 
 185         switch (expr->type) {
 186         case EXPR_DEREF: {
 187                 struct expression *deref;
 188                 int op;
 189 
 190                 deref = expr->deref;
 191                 op = deref->op;
 192                 if (deref->type == EXPR_PREOP && op == '*') {
 193                         struct expression *unop = strip_expr(deref->unop);
 194 
 195                         if (unop->type == EXPR_PREOP && unop->op == '&') {
 196                                 deref = unop->unop;
 197                                 op = '.';
 198                         } else {
 199                                 if (!is_pointer(deref) && !is_pointer(deref->unop))
 200                                         op = '.';
 201                                 deref = deref->unop;
 202                         }
 203                 }
 204 
 205                 __get_variable_from_expr(sym_ptr, buf, deref, len, complicated);
 206 
 207                 if (op == '*')
 208                         append(buf, "->", len);
 209                 else
 210                         append(buf, ".", len);
 211 
 212                 if (expr->member)
 213                         append(buf, expr->member->name, len);
 214                 else
 215                         append(buf, "unknown_member", len);
 216 
 217                 return;
 218         }
 219         case EXPR_SYMBOL:
 220                 if (expr->symbol_name)
 221                         append(buf, expr->symbol_name->name, len);
 222                 if (sym_ptr) {
 223                         if (*sym_ptr)
 224                                 *complicated = 1;
 225                         *sym_ptr = expr->symbol;
 226                 }
 227                 return;
 228         case EXPR_PREOP: {
 229                 const char *tmp;
 230 
 231                 if (get_expression_statement(expr)) {
 232                         *complicated = 2;
 233                         return;
 234                 }
 235 
 236                 if (expr->op == '(') {
 237                         if (expr->unop->type != EXPR_SYMBOL)
 238                                 append(buf, "(", len);
 239                 } else if (expr->op != '*' || !get_array_expr(expr->unop)) {
 240                         tmp = show_special(expr->op);
 241                         append(buf, tmp, len);
 242                 }
 243                 __get_variable_from_expr(sym_ptr, buf, expr->unop,
 244                                                  len, complicated);
 245 
 246                 if (expr->op == '(' && expr->unop->type != EXPR_SYMBOL)
 247                         append(buf, ")", len);
 248 
 249                 if (expr->op == SPECIAL_DECREMENT ||
 250                     expr->op == SPECIAL_INCREMENT)
 251                         *complicated = 1;
 252 
 253                 return;
 254         }
 255         case EXPR_POSTOP: {
 256                 const char *tmp;
 257 
 258                 __get_variable_from_expr(sym_ptr, buf, expr->unop,
 259                                                  len, complicated);
 260                 tmp = show_special(expr->op);
 261                 append(buf, tmp, len);
 262 
 263                 if (expr->op == SPECIAL_DECREMENT || expr->op == SPECIAL_INCREMENT)
 264                         *complicated = 1;
 265                 return;
 266         }
 267         case EXPR_ASSIGNMENT:
 268         case EXPR_COMPARE:
 269         case EXPR_LOGICAL:
 270         case EXPR_BINOP: {
 271                 char tmp[10];
 272                 struct expression *array_expr;
 273 
 274                 *complicated = 1;
 275                 array_expr = get_array_expr(expr);
 276                 if (array_expr) {
 277                         __get_variable_from_expr(sym_ptr, buf, array_expr, len, complicated);
 278                         append(buf, "[", len);
 279                 } else {
 280                         __get_variable_from_expr(sym_ptr, buf, expr->left, len, complicated);
 281                         snprintf(tmp, sizeof(tmp), " %s ", show_special(expr->op));
 282                         append(buf, tmp, len);
 283                 }
 284                 __get_variable_from_expr(NULL, buf, expr->right, len, complicated);
 285                 if (array_expr)
 286                         append(buf, "]", len);
 287                 return;
 288         }
 289         case EXPR_VALUE: {
 290                 sval_t sval = {};
 291                 char tmp[25];
 292 
 293                 *complicated = 1;
 294                 if (!get_value(expr, &sval))
 295                         return;
 296                 snprintf(tmp, 25, "%s", sval_to_numstr(sval));
 297                 append(buf, tmp, len);
 298                 return;
 299         }
 300         case EXPR_FVALUE: {
 301                 sval_t sval = {};
 302                 char tmp[25];
 303 
 304                 *complicated = 1;
 305                 if (!get_value(expr, &sval))
 306                         return;
 307                 snprintf(tmp, 25, "%s", sval_to_numstr(sval));
 308                 append(buf, tmp, len);
 309                 return;
 310         }
 311         case EXPR_STRING:
 312                 append(buf, "\"", len);
 313                 if (expr->string)
 314                         append(buf, expr->string->data, len);
 315                 append(buf, "\"", len);
 316                 return;
 317         case EXPR_CALL: {
 318                 struct expression *tmp;
 319                 int i;
 320 
 321                 *complicated = 1;
 322                 __get_variable_from_expr(NULL, buf, expr->fn, len, complicated);
 323                 append(buf, "(", len);
 324                 i = 0;
 325                 FOR_EACH_PTR(expr->args, tmp) {
 326                         if (i++)
 327                                 append(buf, ", ", len);
 328                         __get_variable_from_expr(NULL, buf, tmp, len, complicated);
 329                 } END_FOR_EACH_PTR(tmp);
 330                 append(buf, ")", len);
 331                 return;
 332         }
 333         case EXPR_CAST:
 334         case EXPR_FORCE_CAST:
 335                 __get_variable_from_expr(sym_ptr, buf,
 336                                          expr->cast_expression, len,
 337                                          complicated);
 338                 return;
 339         case EXPR_SIZEOF: {
 340                 sval_t sval;
 341                 int size;
 342                 char tmp[25];
 343 
 344                 if (expr->cast_type && get_base_type(expr->cast_type)) {
 345                         size = type_bytes(get_base_type(expr->cast_type));
 346                         snprintf(tmp, 25, "%d", size);
 347                         append(buf, tmp, len);
 348                 } else if (get_value(expr, &sval)) {
 349                         snprintf(tmp, 25, "%s", sval_to_str(sval));
 350                         append(buf, tmp, len);
 351                 }
 352                 return;
 353         }
 354         case EXPR_IDENTIFIER:
 355                 *complicated = 1;
 356                 if (expr->expr_ident)
 357                         append(buf, expr->expr_ident->name, len);
 358                 return;
 359         case EXPR_SELECT:
 360         case EXPR_CONDITIONAL:
 361                 *complicated = 1;
 362                 append(buf, "(", len);
 363                 __get_variable_from_expr(NULL, buf, expr->conditional, len, complicated);
 364                 append(buf, ") ?", len);
 365                 if (expr->cond_true)
 366                         __get_variable_from_expr(NULL, buf, expr->cond_true, len, complicated);
 367                 append(buf, ":", len);
 368                 __get_variable_from_expr(NULL, buf, expr->cond_false, len, complicated);
 369                 return;
 370         default: {
 371                         char tmp[64];
 372 
 373                         snprintf(tmp, sizeof(tmp), "$expr_%p(%d)", expr, expr->type);
 374                         append(buf, tmp, len);
 375                         *complicated = 1;
 376                 }
 377                 return;
 378         }
 379 }
 380 
 381 struct expr_str_cache_results {
 382         struct expression *expr;

 383         char str[VAR_LEN];
 384         struct symbol *sym;
 385         int complicated;
 386 };
 387 
 388 static void get_variable_from_expr(struct symbol **sym_ptr, char *buf,
 389                                      struct expression *expr, int len,
 390                                      int *complicated)
 391 {
 392         static struct expr_str_cache_results cached[8];
 393         struct symbol *tmp_sym = NULL;
 394         static int idx;
 395         int i;
 396 
 397         for (i = 0; i < ARRAY_SIZE(cached); i++) {
 398                 if (expr == cached[i].expr) {

 399                         strncpy(buf, cached[i].str, len);
 400                         if (sym_ptr)
 401                                 *sym_ptr = cached[i].sym;
 402                         *complicated = cached[i].complicated;
 403                         return;
 404                 }
 405         }
 406 
 407         __get_variable_from_expr(&tmp_sym, buf, expr, len, complicated);
 408         if (sym_ptr)
 409                 *sym_ptr = tmp_sym;
 410 
 411         if (expr->smatch_flags & Tmp)
 412                 return;
 413 
 414         cached[idx].expr = expr;

 415         strncpy(cached[idx].str, buf, VAR_LEN);
 416         cached[idx].sym = tmp_sym;
 417         cached[idx].complicated = *complicated;
 418 
 419         idx = (idx + 1) % ARRAY_SIZE(cached);
 420 }
 421 
 422 /*
 423  * This is returns a stylized "c looking" representation of the
 424  * variable name.
 425  *
 426  * It uses the same buffer every time so you have to save the result
 427  * yourself if you want to keep it.
 428  *
 429  */
 430 
 431 char *expr_to_str_sym(struct expression *expr, struct symbol **sym_ptr)
 432 {
 433         static char var_name[VAR_LEN];
 434         int complicated = 0;
 435 
 436         if (sym_ptr)
 437                 *sym_ptr = NULL;
 438         var_name[0] = '\0';
 439 
 440         if (!expr)
 441                 return NULL;
 442         get_variable_from_expr(sym_ptr, var_name, expr, sizeof(var_name),
 443                                &complicated);
 444         if (complicated < 2)
 445                 return alloc_string(var_name);
 446         else
 447                 return NULL;
 448 }
 449 
 450 char *expr_to_str(struct expression *expr)
 451 {
 452         return expr_to_str_sym(expr, NULL);
 453 }
 454 
 455 /*
 456  * get_variable_from_expr_simple() only returns simple variables.
 457  * If it's a complicated variable like a->foo[x] instead of just 'a->foo'
 458  * then it returns NULL.
 459  */
 460 char *expr_to_var_sym(struct expression *expr,
 461                                     struct symbol **sym_ptr)
 462 {
 463         static char var_name[VAR_LEN];
 464         int complicated = 0;
 465 
 466         if (sym_ptr)
 467                 *sym_ptr = NULL;
 468         var_name[0] = '\0';
 469 
 470         if (!expr)
 471                 return NULL;
 472         expr = strip_expr(expr);
 473         get_variable_from_expr(sym_ptr, var_name, expr, sizeof(var_name),
 474                                &complicated);
 475 
 476         if (complicated) {
 477                 if (sym_ptr)
 478                         *sym_ptr = NULL;
 479                 return NULL;
 480         }
 481         return alloc_string(var_name);
 482 }
 483 
 484 char *expr_to_var(struct expression *expr)
 485 {
 486         return expr_to_var_sym(expr, NULL);
 487 }
 488 
 489 struct symbol *expr_to_sym(struct expression *expr)
 490 {
 491         struct symbol *sym;
 492         char *name;
 493 
 494         name = expr_to_var_sym(expr, &sym);


1047         if (stmt->type == STMT_COMPOUND) {
1048                 last_stmt = last_ptr_list((struct ptr_list *)stmt->stmts);
1049                 if (!last_stmt)
1050                         return NULL;
1051                 if (last_stmt->type == STMT_LABEL)
1052                         last_stmt = last_stmt->label_statement;
1053                 if (last_stmt->type != STMT_EXPRESSION)
1054                         return NULL;
1055                 return last_stmt->expression;
1056         }
1057         if (stmt->type == STMT_EXPRESSION)
1058                 return stmt->expression;
1059         return NULL;
1060 }
1061 
1062 int get_param_num_from_sym(struct symbol *sym)
1063 {
1064         struct symbol *tmp;
1065         int i;
1066 
1067         if (!sym)
1068                 return UNKNOWN_SCOPE;
1069 
1070         if (sym->ctype.modifiers & MOD_TOPLEVEL) {
1071                 if (sym->ctype.modifiers & MOD_STATIC)
1072                         return FILE_SCOPE;
1073                 return GLOBAL_SCOPE;
1074         }
1075 
1076         if (!cur_func_sym) {
1077                 if (!parse_error) {
1078                         sm_msg("warn: internal.  problem with scope:  %s",
1079                                sym->ident ? sym->ident->name : "<anon var>");
1080                 }
1081                 return GLOBAL_SCOPE;
1082         }
1083 
1084 
1085         i = 0;
1086         FOR_EACH_PTR(cur_func_sym->ctype.base_type->arguments, tmp) {
1087                 if (tmp == sym)
1088                         return i;
1089                 i++;
1090         } END_FOR_EACH_PTR(tmp);
1091         return LOCAL_SCOPE;
1092 }
1093 
1094 int get_param_num(struct expression *expr)
1095 {
1096         struct symbol *sym;
1097         char *name;
1098 
1099         if (!cur_func_sym)
1100                 return UNKNOWN_SCOPE;
1101         name = expr_to_var_sym(expr, &sym);
1102         free_string(name);
1103         if (!sym)
1104                 return UNKNOWN_SCOPE;
1105         return get_param_num_from_sym(sym);
1106 }
1107 
1108 struct symbol *get_param_sym_from_num(int num)
1109 {
1110         struct symbol *sym;
1111         int i;
1112 
1113         if (!cur_func_sym)
1114                 return NULL;
1115 
1116         i = 0;
1117         FOR_EACH_PTR(cur_func_sym->ctype.base_type->arguments, sym) {
1118                 if (i++ == num)
1119                         return sym;
1120         } END_FOR_EACH_PTR(sym);
1121         return NULL;
1122 }
1123 
1124 int ms_since(struct timeval *start)