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)
|