11f5207bJohn Levon/*
21f5207bJohn Levon * Copyright (C) 2018 Oracle.
31f5207bJohn Levon *
41f5207bJohn Levon * This program is free software; you can redistribute it and/or
51f5207bJohn Levon * modify it under the terms of the GNU General Public License
61f5207bJohn Levon * as published by the Free Software Foundation; either version 2
71f5207bJohn Levon * of the License, or (at your option) any later version.
81f5207bJohn Levon *
91f5207bJohn Levon * This program is distributed in the hope that it will be useful,
101f5207bJohn Levon * but WITHOUT ANY WARRANTY; without even the implied warranty of
121f5207bJohn Levon * GNU General Public License for more details.
131f5207bJohn Levon *
141f5207bJohn Levon * You should have received a copy of the GNU General Public License
151f5207bJohn Levon * along with this program; if not, see http://www.gnu.org/copyleft/gpl.txt
161f5207bJohn Levon */
171f5207bJohn Levon
181f5207bJohn Levon#include <stdlib.h>
191f5207bJohn Levon#include "parse.h"
201f5207bJohn Levon#include "smatch.h"
211f5207bJohn Levon#include "smatch_slist.h"
221f5207bJohn Levon#include "smatch_extra.h"
231f5207bJohn Levon
241f5207bJohn Levonstatic int my_id;
251f5207bJohn Levon
261f5207bJohn Levonstatic struct smatch_state *merge_states(struct smatch_state *s1, struct smatch_state *s2)
271f5207bJohn Levon{
281f5207bJohn Levon	int left, right, min;
291f5207bJohn Levon
301f5207bJohn Levon	left = PTR_INT(s1->data);
311f5207bJohn Levon	right = PTR_INT(s2->data);
321f5207bJohn Levon
331f5207bJohn Levon	min = left;
341f5207bJohn Levon	if (right < min)
351f5207bJohn Levon		min = right;
361f5207bJohn Levon	return alloc_state_num(min);
371f5207bJohn Levon}
381f5207bJohn Levon
391f5207bJohn Levonlong get_stmt_cnt(void)
401f5207bJohn Levon{
411f5207bJohn Levon	struct smatch_state *state;
421f5207bJohn Levon
431f5207bJohn Levon	state = get_state(my_id, "stmts", NULL);
441f5207bJohn Levon	if (!state)
451f5207bJohn Levon		return 0;
461f5207bJohn Levon	return (long)state->data;
471f5207bJohn Levon}
481f5207bJohn Levon
491f5207bJohn Levonstatic void match_statement(struct statement *stmt)
501f5207bJohn Levon{
511f5207bJohn Levon	int cnt;
521f5207bJohn Levon
531f5207bJohn Levon	cnt = get_stmt_cnt();
541f5207bJohn Levon	cnt++;
551f5207bJohn Levon	set_state(my_id, "stmts", NULL, alloc_state_num(cnt));
561f5207bJohn Levon}
571f5207bJohn Levon
581f5207bJohn Levonstatic void insert_return_info(int return_id, char *return_ranges, struct expression *expr)
591f5207bJohn Levon{
601f5207bJohn Levon	char buf[32];
611f5207bJohn Levon	int cnt;
621f5207bJohn Levon
631f5207bJohn Levon	cnt = get_stmt_cnt();
641f5207bJohn Levon	snprintf(buf, sizeof(buf), "%d", cnt);
651f5207bJohn Levon	sql_insert_return_states(return_id, return_ranges, STMT_CNT, -1, "", buf);
661f5207bJohn Levon}
671f5207bJohn Levon
681f5207bJohn Levonstatic void select_return_info(struct expression *expr, int param, char *key, char *value)
691f5207bJohn Levon{
701f5207bJohn Levon	int cnt, add;
711f5207bJohn Levon
721f5207bJohn Levon	cnt = get_stmt_cnt();
731f5207bJohn Levon	add = atoi(value);
741f5207bJohn Levon
751f5207bJohn Levon	set_state(my_id, "stmts", NULL, alloc_state_num(cnt + add));
761f5207bJohn Levon}
771f5207bJohn Levon
781f5207bJohn Levonvoid register_statement_count(int id)
791f5207bJohn Levon{
801f5207bJohn Levon	my_id = id;
811f5207bJohn Levon
82efe51d0John Levon	set_dynamic_states(my_id);
831f5207bJohn Levon	add_hook(match_statement, STMT_HOOK);
841f5207bJohn Levon	add_merge_hook(my_id, &merge_states);
851f5207bJohn Levon
861f5207bJohn Levon	add_split_return_callback(&insert_return_info);
871f5207bJohn Levon	select_return_states_hook(STMT_CNT, &select_return_info);
881f5207bJohn Levon}
891f5207bJohn Levon