1 /*
   2  * Copyright (C) 2018 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 <stdlib.h>
  19 #include "parse.h"
  20 #include "smatch.h"
  21 #include "smatch_slist.h"
  22 #include "smatch_extra.h"
  23 
  24 static int my_id;
  25 
  26 static struct smatch_state *merge_states(struct smatch_state *s1, struct smatch_state *s2)
  27 {
  28         int left, right, min;
  29 
  30         left = PTR_INT(s1->data);
  31         right = PTR_INT(s2->data);
  32 
  33         min = left;
  34         if (right < min)
  35                 min = right;
  36         return alloc_state_num(min);
  37 }
  38 
  39 long get_stmt_cnt(void)
  40 {
  41         struct smatch_state *state;
  42 
  43         state = get_state(my_id, "stmts", NULL);
  44         if (!state)
  45                 return 0;
  46         return (long)state->data;
  47 }
  48 
  49 static void match_statement(struct statement *stmt)
  50 {
  51         int cnt;
  52 
  53         cnt = get_stmt_cnt();
  54         cnt++;
  55         set_state(my_id, "stmts", NULL, alloc_state_num(cnt));
  56 }
  57 
  58 static void insert_return_info(int return_id, char *return_ranges, struct expression *expr)
  59 {
  60         char buf[32];
  61         int cnt;
  62 
  63         cnt = get_stmt_cnt();
  64         snprintf(buf, sizeof(buf), "%d", cnt);
  65         sql_insert_return_states(return_id, return_ranges, STMT_CNT, -1, "", buf);
  66 }
  67 
  68 static void select_return_info(struct expression *expr, int param, char *key, char *value)
  69 {
  70         int cnt, add;
  71 
  72         cnt = get_stmt_cnt();
  73         add = atoi(value);
  74 
  75         set_state(my_id, "stmts", NULL, alloc_state_num(cnt + add));
  76 }
  77 
  78 void register_statement_count(int id)
  79 {
  80         my_id = id;
  81 
  82         add_hook(match_statement, STMT_HOOK);
  83         add_merge_hook(my_id, &merge_states);
  84 
  85         add_split_return_callback(&insert_return_info);
  86         select_return_states_hook(STMT_CNT, &select_return_info);
  87 }
  88