1 /*
   2  * Copyright (C) 2013 Oracle.
   3  *
   4  * This program is free software; you can redistribute it and/or
   5  * modify it under the terms of the GNU General Public License
   6  * as published by the Free Software Foundation; either version 2
   7  * of the License, or (at your option) any later version.
   8  *
   9  * This program is distributed in the hope that it will be useful,
  10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  12  * GNU General Public License for more details.
  13  *
  14  * You should have received a copy of the GNU General Public License
  15  * along with this program; if not, see http://www.gnu.org/copyleft/gpl.txt
  16  */
  17 
  18 #include "smatch.h"
  19 #include "smatch_slist.h"
  20 #include "smatch_extra.h"
  21 
  22 static int my_id;
  23 
  24 static char *get_source_parameter(struct expression *expr)
  25 {
  26         struct expression *tmp;
  27         struct symbol *sym;
  28         char *name;
  29         int param;
  30         char *ret = NULL;
  31         char buf[32];
  32         int cnt = 0;
  33 
  34         tmp = expr;
  35         while ((tmp = get_assigned_expr(tmp))) {
  36                 expr = tmp;
  37                 if (cnt++ > 3)
  38                         break;
  39         }
  40 
  41         expr = strip_expr(expr);
  42         if (expr->type != EXPR_SYMBOL)
  43                 return NULL;
  44 
  45         name = expr_to_var_sym(expr, &sym);
  46         if (!name || !sym)
  47                 goto free;
  48         param = get_param_num_from_sym(sym);
  49         if (param < 0)
  50                 goto free;
  51         if (param_was_set(expr))
  52                 goto free;
  53 
  54         snprintf(buf, sizeof(buf), "p %d", param);
  55         ret = alloc_string(buf);
  56 
  57 free:
  58         free_string(name);
  59         return ret;
  60 }
  61 
  62 static char *get_source_assignment(struct expression *expr)
  63 {
  64         struct expression *right;
  65         char *name;
  66         char buf[64];
  67         char *ret;
  68 
  69         right = get_assigned_expr(expr);
  70         right = strip_expr(right);
  71         if (!right)
  72                 return NULL;
  73         if (right->type != EXPR_CALL || right->fn->type != EXPR_SYMBOL)
  74                 return NULL;
  75         if (is_fake_call(right))
  76                 return NULL;
  77         name = expr_to_str(right->fn);
  78         if (!name)
  79                 return NULL;
  80         snprintf(buf, sizeof(buf), "r %s", name);
  81         ret = alloc_string(buf);
  82         free_string(name);
  83         return ret;
  84 }
  85 
  86 static char *get_source_str(struct expression *arg)
  87 {
  88         char *source;
  89 
  90         source = get_source_parameter(arg);
  91         if (source)
  92                 return source;
  93         return get_source_assignment(arg);
  94 }
  95 
  96 static void match_caller_info(struct expression *expr)
  97 {
  98         struct expression *arg;
  99         char *source;
 100         int i;
 101 
 102         i = -1;
 103         FOR_EACH_PTR(expr->args, arg) {
 104                 i++;
 105                 source = get_source_str(arg);
 106                 if (!source)
 107                         continue;
 108                 sql_insert_caller_info(expr, DATA_SOURCE, i, "$", source);
 109                 free_string(source);
 110         } END_FOR_EACH_PTR(arg);
 111 }
 112 
 113 void register_data_source(int id)
 114 {
 115 //      if (!option_info)
 116 //              return;
 117         my_id = id;
 118         add_hook(&match_caller_info, FUNCTION_CALL_HOOK);
 119 }