Esempio n. 1
0
/*!
 * Counts file language complexity based on specified language keywords/characters.
 *
 * \param fmap list of processed file lines
 * \param result counter results
 *
 * \return method status
 */
int CPythonCounter::CountComplexity(filemap* fmap, results* result)
{
	if (classtype == UNKNOWN || classtype == DATAFILE)
		return 0;
	filemap::iterator fit;
	size_t idx;
	unsigned int cnt, ret, cyclomatic_cnt = 0, ignore_cyclomatic_cnt = 0, main_cyclomatic_cnt = 1, function_count = 0, cyclomatic_logic_cnt = 0, main_cyclomatic_logic_cnt = 1;
    bool isMainExisted = false;
	string line, needIndentation = "", file_ext, function_name = "";
    	vector<int> indenStack;
    	indenStack.push_back(0);
    	int numWS;
	string exclude = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789_$";
	StringVector function_stack;
	stack<unsigned int> cyclomatic_stack;
	stack<unsigned int> cyclomatic_logic_stack;
	bool process_cyclomatic_complexity = false;
    
	// check whether to process cyclomatic complexity
	if (cmplx_cyclomatic_list.size() > 0)
	{
		process_cyclomatic_complexity = true;
		if (skip_cmplx_cyclomatic_file_extension_list.size() > 0)
		{
			idx = result->file_name.find_last_of(".");
			if (idx != string::npos)
			{
				file_ext = result->file_name.substr(idx);
				file_ext = CUtil::ToLower(file_ext);
				if (find(skip_cmplx_cyclomatic_file_extension_list.begin(), skip_cmplx_cyclomatic_file_extension_list.end(), file_ext) != skip_cmplx_cyclomatic_file_extension_list.end())
					process_cyclomatic_complexity = false;
			}
		}
	}
    
	// process each line
    	bool notEndFile = true;
	for (fit = fmap->begin(); notEndFile; fit++)
	{
        	if (fit == fmap->end()) {
            		notEndFile = false;
        	}
        	if (!notEndFile) {
           		 line = " endofmain";
            		//to handle last line of a file belongs to one function:
            		//                                  return(1) --> end of function.
        	}else{
            		line = fit->line;
            
           	 	if (CUtil::CheckBlank(line))
                		continue;
            
            		line = " " + line;
        	}
        
        	//cout << line << "meiyige";
		// mathematical functions
		cnt = 0;
		CUtil::CountTally(line, math_func_list, cnt, 1, exclude, "", "", &result->math_func_count, casesensitive);
		result->cmplx_math_lines += cnt;
        
		// trigonometric functions
		cnt = 0;
		CUtil::CountTally(line, trig_func_list, cnt, 1, exclude, "", "", &result->trig_func_count, casesensitive);
		result->cmplx_trig_lines += cnt;
        
		// logarithmic functions
		cnt = 0;
		CUtil::CountTally(line, log_func_list, cnt, 1, exclude, "", "", &result->log_func_count, casesensitive);
		result->cmplx_logarithm_lines += cnt;
        
		// calculations
		cnt = 0;
		CUtil::CountTally(line, cmplx_calc_list, cnt, 1, exclude, "", "", &result->cmplx_calc_count, casesensitive);
		result->cmplx_calc_lines += cnt;
        
		// conditionals
		cnt = 0;
		CUtil::CountTally(line, cmplx_cond_list, cnt, 1, exclude, "", "", &result->cmplx_cond_count, casesensitive);
		result->cmplx_cond_lines += cnt;
        
		// logical operators
		cnt = 0;
		CUtil::CountTally(line, cmplx_logic_list, cnt, 1, exclude, "", "", &result->cmplx_logic_count, casesensitive);
		result->cmplx_logic_lines += cnt;
        
		// preprocessor directives
		cnt = 0;
		CUtil::CountTally(line, cmplx_preproc_list, cnt, 1, exclude, "", "", &result->cmplx_preproc_count, casesensitive);
		result->cmplx_preproc_lines += cnt;
        
		// assignments
		cnt = 0;
		CUtil::CountTally(line, cmplx_assign_list, cnt, 1, exclude, "", "", &result->cmplx_assign_count, casesensitive);
		result->cmplx_assign_lines += cnt;
        
		// pointers
		cnt = 0;
		CUtil::CountTally(line, cmplx_pointer_list, cnt, 1, exclude, "", "", &result->cmplx_pointer_count, casesensitive);
		result->cmplx_pointer_lines += cnt;
        
		// cyclomatic complexity
		if (process_cyclomatic_complexity)
		{
            
			// search for cyclomatic complexity keywords
			CUtil::CountTally(line, cmplx_cyclomatic_list, cyclomatic_cnt, 1, exclude, "", "", 0, casesensitive);
            
			// search for keywords to exclude
			if (ignore_cmplx_cyclomatic_list.size() > 0)
				CUtil::CountTally(line, ignore_cmplx_cyclomatic_list, ignore_cyclomatic_cnt, 1, exclude, "", "", 0, casesensitive);

			// search for cyclomatic complexity logical keywords
			if (cmplx_cyclomatic_logic_list.size() > 0)
				CUtil::CountTally(line, cmplx_cyclomatic_logic_list, cyclomatic_logic_cnt, 1, exclude, "", "", 0, casesensitive);
           
			// parse function name if found
			ret = ParseFunctionName(line, needIndentation, function_stack, function_name, indenStack, numWS);
            
			if (ret != 1 && !cyclomatic_stack.empty() && cyclomatic_stack.size() == function_stack.size()-1)
			{
				// remove count stack entry for non-function names
				cyclomatic_cnt += cyclomatic_stack.top();
				ignore_cyclomatic_cnt = 0;
				cyclomatic_stack.pop();
			}
			if (ret != 1 && !cyclomatic_logic_stack.empty() && cyclomatic_logic_stack.size() == function_stack.size()-1)
			{
				// remove count stack entry for non-function names
				cyclomatic_logic_cnt += cyclomatic_logic_stack.top();
				cyclomatic_logic_stack.pop();
			}


            
            		// modify the condition when comes to function_stack.size() [add 1]
			if (ret == 1) // and modify this part
			{
                		//this line is not in the current function, handle it later
                		int remember = cyclomatic_cnt - ignore_cyclomatic_cnt + 1;
                		int remember2 = remember + cyclomatic_logic_cnt;

      
                		cyclomatic_cnt = 0;
                		ignore_cyclomatic_cnt = 0;
				cyclomatic_logic_cnt = 0;
                		CUtil::CountTally(line, cmplx_cyclomatic_list, cyclomatic_cnt, 1, exclude, "", "", 0, casesensitive);
                
                		// get this line's complexity
                		if (ignore_cmplx_cyclomatic_list.size() > 0)
                    			CUtil::CountTally(line, ignore_cmplx_cyclomatic_list, ignore_cyclomatic_cnt, 1, exclude, "", "", 0, casesensitive);
				if (cmplx_cyclomatic_logic_list.size() > 0)
					CUtil::CountTally(line, cmplx_cyclomatic_logic_list, cyclomatic_logic_cnt, 1, exclude, "", "", 0, casesensitive);
                
                		//substrack the current line's complexity
                		remember -= cyclomatic_cnt - ignore_cyclomatic_cnt;
				remember2 -= cyclomatic_cnt - ignore_cyclomatic_cnt + cyclomatic_logic_cnt;

				// capture count at end of function
                		lineElement element(remember, function_name);
                		result->cmplx_cycfunct_count.push_back(element);
				lineElement n_element(remember2, function_name);
				result->cmplx_cycfunct_CC2_count.push_back(n_element);

                		function_name = "";
				if (function_stack.size() > 1)
				{
					// grab previous function from stack to continue
					if (!cyclomatic_stack.empty())
					{
                        			int flag = 0;
                        			//both the stacks' first element is redundant so " ** > 1 "
                        			while (indenStack.size() > 1 && function_stack.size() > 1) {
                            				if (flag == 1) {
                                				indenStack.pop_back();
                                				function_stack.pop_back();
                            				}
                            				if (numWS >= indenStack.back()) {
                                				//the current line belongs to one of the functions in the function_stack
                                				break;
                            				}
                            				
                            				int temp = cyclomatic_stack.top() + 1;
                            				cyclomatic_stack.pop();
							int temp2 = cyclomatic_logic_stack.top();
							cyclomatic_logic_stack.pop();
                            				string str = function_stack.back();
                            
                            				size_t idx = str.find("(");
                            				if (idx != string::npos)
                            				{
                                				function_name = CUtil::ClearRedundantSpaces(str.substr(0, idx));
                            				}
                            				lineElement element(temp, function_name);
                            				result->cmplx_cycfunct_count.push_back(element);
							lineElement n_element(temp + temp2, function_name);
							result->cmplx_cycfunct_CC2_count.push_back(n_element);

                            				function_name = "";

                            				flag = 1;
                        			}
                        			if (indenStack.size() > 1) {
                            				//the current line belongs to one of the functions in the function_stack
                            				cyclomatic_cnt += cyclomatic_stack.top() - ignore_cyclomatic_cnt;
                            				cyclomatic_stack.pop();
							cyclomatic_logic_cnt += cyclomatic_logic_stack.top();
							cyclomatic_logic_stack.pop();
                        			}else{
                            				//the current line not belongs to any of the functions in the function_stack, so it should belong to main
                            				if (line != " endofmain") {
                                				main_cyclomatic_cnt += cyclomatic_cnt - ignore_cyclomatic_cnt;
								main_cyclomatic_logic_cnt += cyclomatic_cnt - ignore_cyclomatic_cnt + cyclomatic_logic_cnt;
                                				isMainExisted = true;
                            				}
                            				cyclomatic_cnt = cyclomatic_logic_cnt = 0;
                        			}
					}
				}
				else{
                    			if (line != " endofmain") {
                                		main_cyclomatic_cnt += cyclomatic_cnt - ignore_cyclomatic_cnt;
						main_cyclomatic_logic_cnt += cyclomatic_cnt - ignore_cyclomatic_cnt + cyclomatic_logic_cnt;
                        			isMainExisted = true;
                    			}
                            		cyclomatic_cnt = cyclomatic_logic_cnt = 0;
                		}
				ignore_cyclomatic_cnt = 0;
			}
			else if (ret == 2)
			{
				// some code doesn't belong to any function
				if (line != " endofmain") {
                                	main_cyclomatic_cnt += cyclomatic_cnt - ignore_cyclomatic_cnt;
					main_cyclomatic_logic_cnt += cyclomatic_cnt - ignore_cyclomatic_cnt + cyclomatic_logic_cnt;
                    			isMainExisted = true;
                    
                		}
				cyclomatic_cnt = ignore_cyclomatic_cnt = cyclomatic_logic_cnt = 0;
			}
			else { 
				if (function_stack.size() > 1 && (function_stack.size() - 1 > cyclomatic_stack.size() + 1 || (cyclomatic_stack.empty() && function_stack.size() - 1 > 1)))
				{
					// capture previous complexity count from open function
					cyclomatic_stack.push(cyclomatic_cnt - ignore_cyclomatic_cnt);
					cyclomatic_cnt = ignore_cyclomatic_cnt = 0;
				}
				if (function_stack.size() > 1 && (function_stack.size() - 1 > cyclomatic_logic_stack.size() + 1 || (cyclomatic_logic_stack.empty() && function_stack.size() - 1 > 1)))
				{
					// capture previous complexity count from open function
					cyclomatic_logic_stack.push(cyclomatic_logic_cnt);
					cyclomatic_logic_cnt = 0;
				}
			}
		}
	}
    
	// done with a file, if has "main" code add it
	if (isMainExisted)
	{
		lineElement element(main_cyclomatic_cnt, "main");
		lineElement n_element(main_cyclomatic_logic_cnt, "main");
		result->cmplx_cycfunct_count.push_back(element);
		result->cmplx_cycfunct_CC2_count.push_back(n_element);
	}
	return 1;
}
/*!
 * Counts file language complexity based on specified language keywords/characters.
 *
 * \param fmap list of processed file lines
 * \param result counter results
 *
 * \return method status
 */
int CCshCounter::CountComplexity(filemap* fmap, results* result)
{
	if (classtype == UNKNOWN || classtype == DATAFILE)
		return 0;
	filemap::iterator fit;
	size_t idx;
	unsigned int cnt, ret, cyclomatic_cnt = 0, ignore_cyclomatic_cnt = 0, main_cyclomatic_cnt = 0, function_count = 0, cyclomatic_logic_cnt = 0, main_cyclomatic_logic_cnt = 1, cyclomatic_case_cnt = 0, main_cyclomatic_case_cnt = 1, cyclomatic_default_cnt = 0, cyclomatic_switch_cnt = 0;

	string line, lastline, file_ext, function_name = "";
	string exclude = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789_$";
	filemap function_stack;
	stack<unsigned int> cyclomatic_stack;
	stack<unsigned int> cyclomatic_logic_stack;
	stack<unsigned int> cyclomatic_case_stack;
	map<unsigned int, lineElement> function_map;
	map<unsigned int, lineElement> logical_map;
	map<unsigned int, lineElement> case_map;
	bool process_cyclomatic_complexity = false;
    
	// check whether to process cyclomatic complexity
	if (cmplx_cyclomatic_list.size() > 0)
	{
		process_cyclomatic_complexity = true;
		if (skip_cmplx_cyclomatic_file_extension_list.size() > 0)
		{
			idx = result->file_name.find_last_of(".");
			if (idx != string::npos)
			{
				file_ext = result->file_name.substr(idx);
				file_ext = CUtil::ToLower(file_ext);
				if (find(skip_cmplx_cyclomatic_file_extension_list.begin(), skip_cmplx_cyclomatic_file_extension_list.end(), file_ext) != skip_cmplx_cyclomatic_file_extension_list.end())
					process_cyclomatic_complexity = false;
			}
		}
	}
    
	// process each line
	for (fit = fmap->begin(); fit != fmap->end(); fit++)
	{
		line = fit->line;
        
		if (CUtil::CheckBlank(line))
			continue;
        	line = echoHelper(line);
        
        
		line = " " + line;
        
		// mathematical functions
		cnt = 0;
		CUtil::CountTally(line, math_func_list, cnt, 1, exclude, "", "", &result->math_func_count, casesensitive);
		result->cmplx_math_lines += cnt;
        
		// trigonometric functions
		cnt = 0;
		CUtil::CountTally(line, trig_func_list, cnt, 1, exclude, "", "", &result->trig_func_count, casesensitive);
		result->cmplx_trig_lines += cnt;
        
		// logarithmic functions
		cnt = 0;
		CUtil::CountTally(line, log_func_list, cnt, 1, exclude, "", "", &result->log_func_count, casesensitive);
		result->cmplx_logarithm_lines += cnt;
        
		// calculations
		cnt = 0;
		CUtil::CountTally(line, cmplx_calc_list, cnt, 1, exclude, "", "", &result->cmplx_calc_count, casesensitive);
		result->cmplx_calc_lines += cnt;
        
		// conditionals
		cnt = 0;
		CUtil::CountTally(line, cmplx_cond_list, cnt, 1, exclude, "", "", &result->cmplx_cond_count, casesensitive);
		result->cmplx_cond_lines += cnt;
        
		// logical operators
		cnt = 0;
		CUtil::CountTally(line, cmplx_logic_list, cnt, 1, exclude, "", "", &result->cmplx_logic_count, casesensitive);
		result->cmplx_logic_lines += cnt;
        
		// preprocessor directives
		cnt = 0;
		CUtil::CountTally(line, cmplx_preproc_list, cnt, 1, exclude, "", "", &result->cmplx_preproc_count, casesensitive);
		result->cmplx_preproc_lines += cnt;
        
		// assignments
		cnt = 0;
		CUtil::CountTally(line, cmplx_assign_list, cnt, 1, exclude, "", "", &result->cmplx_assign_count, casesensitive);
		result->cmplx_assign_lines += cnt;
        
		// pointers
		cnt = 0;
		CUtil::CountTally(line, cmplx_pointer_list, cnt, 1, exclude, "", "", &result->cmplx_pointer_count, casesensitive);
		result->cmplx_pointer_lines += cnt;
        
		// cyclomatic complexity
		if (process_cyclomatic_complexity)
		{
			// search for cyclomatic complexity keywords
			CUtil::CountTally(line, cmplx_cyclomatic_list, cyclomatic_cnt, 1, exclude, "", "", 0, casesensitive);

			CUtil::CountTally(line, cmplx_cyclomatic_switch_list, cyclomatic_switch_cnt, 1, exclude, "", "", 0, casesensitive);
          
			// search for keywords to exclude
			if (ignore_cmplx_cyclomatic_list.size() > 0)
				CUtil::CountTally(line, ignore_cmplx_cyclomatic_list, ignore_cyclomatic_cnt, 1, exclude, "", "", 0, casesensitive);

			// search for cyclomatic complexity logical keywords
			if (cmplx_cyclomatic_logic_list.size() > 0)
				CUtil::CountTally(line, cmplx_cyclomatic_logic_list, cyclomatic_logic_cnt, 1, exclude, "", "", 0, casesensitive);

			// search for cyclomatic complexity logical keywords
			if (cmplx_cyclomatic_case_list.size() > 0)
				CUtil::CountTally(line, cmplx_cyclomatic_case_list, cyclomatic_case_cnt, 1, exclude, "", "", 0, casesensitive);

			// search for cyclomatic complexity case default keywords
			if (cmplx_cyclomatic_default_list.size() > 0)
				CUtil::CountTally(line, cmplx_cyclomatic_default_list, cyclomatic_default_cnt, 1, exclude, "", "", 0, casesensitive);

			if(cyclomatic_default_cnt > 0)
			{
				cyclomatic_cnt -= cyclomatic_default_cnt;
				cyclomatic_case_cnt -= cyclomatic_default_cnt;
				cyclomatic_default_cnt = 0;
			}

			// parse function name if found
			ret = ParseFunctionName(line, lastline, function_stack, function_name);
			if (ret != 1 && !cyclomatic_stack.empty() && cyclomatic_stack.size() == function_stack.size())
			{
				// remove count stack entry for non-function names
				cyclomatic_cnt += cyclomatic_stack.top();
				ignore_cyclomatic_cnt = 0;
				cyclomatic_stack.pop();
			}
			if (ret != 1 && !cyclomatic_logic_stack.empty() && cyclomatic_logic_stack.size() == function_stack.size())
			{
				// remove count stack entry for non-function names
				cyclomatic_logic_cnt += cyclomatic_logic_stack.top();
				cyclomatic_logic_stack.pop();
			}
			if (ret != 1 && !cyclomatic_case_stack.empty() && cyclomatic_case_stack.size() == function_stack.size())
			{
				// remove count stack entry for non-function names
				cyclomatic_case_cnt += cyclomatic_case_stack.top();
				cyclomatic_case_stack.pop();
			}
			if (ret == 1)
			{
				// capture count at end of function
				lineElement element(cyclomatic_cnt - ignore_cyclomatic_cnt + 1, function_name);
				function_map[function_count] = element;
				
				lineElement n_element(cyclomatic_cnt - ignore_cyclomatic_cnt + cyclomatic_logic_cnt + 1, function_name);
				logical_map[function_count] = n_element;

				if (cyclomatic_case_cnt > 0)
				{
					lineElement c_element(cyclomatic_cnt - ignore_cyclomatic_cnt - cyclomatic_case_cnt + cyclomatic_switch_cnt + 1, function_name);
					case_map[function_count] = c_element;
				}
				else
					case_map[function_count] = element;
                
				if (!function_stack.empty())
				{
					// grab previous function from stack to continue
					if (!cyclomatic_stack.empty())
					{
						cyclomatic_cnt = cyclomatic_stack.top();
						cyclomatic_stack.pop();
					}
					if (!cyclomatic_logic_stack.empty())
					{
						cyclomatic_logic_cnt = cyclomatic_logic_stack.top();
						cyclomatic_logic_stack.pop();
					}
					if (!cyclomatic_case_stack.empty())
					{
						cyclomatic_case_cnt = cyclomatic_case_stack.top();
						cyclomatic_case_stack.pop();
					}
				}
				else {
					cyclomatic_cnt = 0;
					cyclomatic_logic_cnt = 0;
					cyclomatic_case_cnt = 0;
				}
				function_name = "";
				ignore_cyclomatic_cnt = 0;
				cyclomatic_switch_cnt = 0;
			}
			else if (ret == 2)
			{
				if (main_cyclomatic_cnt < 1)
					main_cyclomatic_cnt = 1;	// add 1 for main function here in case no other decision points are found in main
				// some code doesn't belong to any function
				main_cyclomatic_cnt += cyclomatic_cnt - ignore_cyclomatic_cnt;
				main_cyclomatic_logic_cnt += cyclomatic_cnt - ignore_cyclomatic_cnt + cyclomatic_logic_cnt;
				main_cyclomatic_case_cnt += cyclomatic_cnt - ignore_cyclomatic_cnt - cyclomatic_case_cnt + cyclomatic_switch_cnt;
				cyclomatic_cnt = ignore_cyclomatic_cnt = cyclomatic_logic_cnt = cyclomatic_case_cnt = cyclomatic_switch_cnt = 0;
			}
			else { 
				if (!function_stack.empty() && (function_stack.size() > cyclomatic_stack.size() + 1 || (cyclomatic_stack.empty() && function_stack.size() > 1)))
				{
					// capture previous complexity count from open function
					cyclomatic_stack.push(cyclomatic_cnt - ignore_cyclomatic_cnt);
					cyclomatic_cnt = ignore_cyclomatic_cnt = 0;
				}
				if (!function_stack.empty() && (function_stack.size() > cyclomatic_logic_stack.size() + 1 || (cyclomatic_logic_stack.empty() && function_stack.size() > 1)))
				{
					// capture previous complexity count from open function
					cyclomatic_logic_stack.push(cyclomatic_logic_cnt);
					cyclomatic_logic_cnt = 0;
				}
				if (!function_stack.empty() && (function_stack.size() > cyclomatic_case_stack.size() + 1 || (cyclomatic_case_stack.empty() && function_stack.size() > 1)))
				{
					// capture previous complexity count from open function
					cyclomatic_case_stack.push(cyclomatic_case_cnt - cyclomatic_switch_cnt);
					cyclomatic_case_cnt = 0;
					cyclomatic_switch_cnt = 0;
				}
			}
		}
	}

	// done with a file
	if (main_cyclomatic_cnt > 0)
	{
		// add "main" code
		lineElement element(main_cyclomatic_cnt, "main");
		lineElement n_element(main_cyclomatic_logic_cnt, "main");
		lineElement c_element(main_cyclomatic_case_cnt, "main");
		function_map[0] = element;
		logical_map[0] = n_element;
		case_map[0] = c_element;
	}
	else
	{
		// finish the first function if not closed
		while (!function_stack.empty())
		{
			function_name = function_stack.back().line;
			function_count = function_stack.back().lineNumber;
			function_stack.pop_back();

			if (!function_stack.empty())
			{
				// grab previous function from stack to continue
				if (!cyclomatic_stack.empty())
				{
					cyclomatic_cnt = cyclomatic_stack.top();
					cyclomatic_stack.pop();
				}
			}
			else
			{
				// capture count at end of function
				lineElement element(cyclomatic_cnt - ignore_cyclomatic_cnt + 1, function_name);
				lineElement n_element(cyclomatic_cnt - ignore_cyclomatic_cnt + cyclomatic_logic_cnt + 1, function_name);
				lineElement c_element(cyclomatic_cnt - ignore_cyclomatic_cnt - cyclomatic_case_cnt + cyclomatic_switch_cnt + 1, function_name);
				function_map[function_count] = element;
				logical_map[function_count] = n_element;
				case_map[function_count] = c_element;
			}
		}
	}

	// process ordered functions
	for (map<unsigned int, lineElement>::iterator it = function_map.begin(); it != function_map.end(); ++it)
		result->cmplx_cycfunct_count.push_back(it->second);
	if(cmplx_cyclomatic_logic_list.size() > 0)
	{
		for (map<unsigned int, lineElement>::iterator it = logical_map.begin(); it != logical_map.end(); ++it)
			result->cmplx_cycfunct_CC2_count.push_back(it->second);
	}
	if(cmplx_cyclomatic_case_list.size() > 0)
	{
		for (map<unsigned int, lineElement>::iterator it = case_map.begin(); it != case_map.end(); ++it)
			result->cmplx_cycfunct_CC3_count.push_back(it->second);
	}
	return 1;
}
int CVerilogCounter::CountComplexity(filemap* fmap, results* result)
{
	if (classtype == UNKNOWN || classtype == DATAFILE)
		return 0;
	filemap::iterator fit;
	filemap fitBak;
	filemap::iterator fitForw, fitBack;//used to check prior an later lines for semicolons
	//unsigned int cnt;
	//string line, line2;
	string exclude = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789_$><=:";
	tokLocVect conditionalVector;
	tokLocVect::reverse_iterator r_tlvIter;
	//StringVector::iterator strIter = this->cmplx_cond_list.begin(); warning fix
	string buf;			// have a buffer string
	stringstream ss;	// insert the string into a stream
	tokenLocation tl;
	int count;
	bool whenCont;
    
    	size_t idx;
	unsigned int cnt, ret, cyclomatic_cnt = 0, ignore_cyclomatic_cnt = 0, main_cyclomatic_cnt = 0, /*function_count = 0, */cyclomatic_logic_cnt = 0, main_cyclomatic_logic_cnt = 1, cyclomatic_case_cnt = 0, main_cyclomatic_case_cnt = 1; // warning fix
	string line, lastline, file_ext, function_name = "";
    	StringVector function_stack;
	stack<unsigned int> cyclomatic_stack;
	stack<unsigned int> cyclomatic_logic_stack;
	stack<unsigned int> cyclomatic_case_stack;
	bool process_cyclomatic_complexity = false;
    	bool first_line_in_main = true;

    	StringVector switch_case_key_list;
    	StringVector switch_case_stack;
    	switch_case_key_list.push_back(":");    
    
	// check whether to process cyclomatic complexity
	if (cmplx_cyclomatic_list.size() > 0)
	{
		process_cyclomatic_complexity = true;
		if (skip_cmplx_cyclomatic_file_extension_list.size() > 0)
		{
			idx = result->file_name.find_last_of(".");
			if (idx != string::npos)
			{
				file_ext = result->file_name.substr(idx);
				file_ext = CUtil::ToLower(file_ext);
				if (find(skip_cmplx_cyclomatic_file_extension_list.begin(), skip_cmplx_cyclomatic_file_extension_list.end(), file_ext) != skip_cmplx_cyclomatic_file_extension_list.end())
					process_cyclomatic_complexity = false;
			}
		}
	}
    
	for (fit = fmap->begin(); fit != fmap->end(); fit++)
	{
		line = fit->line;
        
		if (CUtil::CheckBlank(line))
			continue;
        
		line = " " + line;
        
		// mathematical functions
		cnt = 0;
		CUtil::CountTally(line, math_func_list, cnt, 1, exclude, "", "", &result->math_func_count, casesensitive);
		result->cmplx_math_lines += cnt;
        
		// trigonometric functions
		cnt = 0;
		CUtil::CountTally(line, trig_func_list, cnt, 1, exclude, "", "", &result->trig_func_count, casesensitive);
		result->cmplx_trig_lines += cnt;
        
		// logarithmic functions
		cnt = 0;
		CUtil::CountTally(line, log_func_list, cnt, 1, exclude, "", "", &result->log_func_count, casesensitive);
		result->cmplx_logarithm_lines += cnt;
        
		// calculations
		cnt = 0;
		CUtil::CountTally(line, cmplx_calc_list, cnt, 1, exclude, "", "", &result->cmplx_calc_count, casesensitive);
		result->cmplx_calc_lines += cnt;
        
		// conditionals
		cnt = 0;
		CUtil::CountTally(line, cmplx_cond_list, cnt, 1, exclude, "", "", &result->cmplx_cond_count, casesensitive);
		result->cmplx_cond_lines += cnt;
        
		// logical operators
		cnt = 0;
		StringVector tmpList = cmplx_logic_list;//making a temporary list with the '<=' operator removed from the list; counting it on another pass;
		tmpList.pop_back();
		CUtil::CountTally(line, tmpList, cnt, 1, exclude, "", "", &result->cmplx_logic_count, casesensitive);
		result->cmplx_logic_lines += cnt;
        
		// preprocessor directives
		cnt = 0;
		CUtil::CountTally(line, cmplx_preproc_list, cnt, 1, exclude, "", "", &result->cmplx_preproc_count, casesensitive);
		result->cmplx_preproc_lines += cnt;
        
		// assignments
		cnt = 0;
		tmpList.clear();
		tmpList = cmplx_assign_list;//making a temporary list with the '<=' operator removed from the list; counting it on another pass;
		tmpList.pop_back();
		CUtil::CountTally(line, tmpList, cnt, 1, exclude, "", "", &result->cmplx_assign_count, casesensitive);
		result->cmplx_assign_lines += cnt;
     
	/* No pointer for Verilog
		// pointers
		cnt = 0;
		// Pointers are embedded syntax so there is NO exclude string or include strings
		CUtil::CountTally(line, cmplx_pointer_list, cnt, 1, "", "", "", &result->cmplx_pointer_count, casesensitive);
		result->cmplx_pointer_lines += cnt;
	*/
        
        	// cyclomatic complexity
		if (process_cyclomatic_complexity)
		{
			// search for cyclomatic complexity keywords
			unsigned int temp = 0;
			CUtil::CountTally(line, cmplx_cyclomatic_list, temp, 1, exclude, "", "", 0, casesensitive);
            		cyclomatic_cnt += temp;

			// search for keywords to exclude
			if (ignore_cmplx_cyclomatic_list.size() > 0)
				CUtil::CountTally(line, ignore_cmplx_cyclomatic_list, ignore_cyclomatic_cnt, 1, exclude, "", "", 0, casesensitive);

			// search for cyclomatic complexity case keywords
			if (cmplx_cyclomatic_case_list.size() > 0)
				CUtil::CountTally(line, cmplx_cyclomatic_case_list, cyclomatic_case_cnt, 1, exclude, "", "", 0, casesensitive);
			cyclomatic_case_cnt += temp;

			//search for keyword "case"
            		size_t idx_case = CUtil::FindKeyword(line, "case");
            		if (idx_case != string::npos) {
                		switch_case_stack.push_back("case");
            		}
			//search for keyword "case"
            		idx_case = CUtil::FindKeyword(line, "casez");
            		if (idx_case != string::npos) {
                		switch_case_stack.push_back("case");
            		}
			//search for keyword "case"
            		idx_case = CUtil::FindKeyword(line, "casex");
            		if (idx_case != string::npos) {
                		switch_case_stack.push_back("case");
            		}

			//only if switch_case_stack is not empty, we will search keyword ":" and "[" and "?"
            		if(!switch_case_stack.empty()){
                		size_t idx = CUtil::FindKeyword(line, ":");
                		size_t idx_1 = CUtil::FindKeyword(line, "[");
                		size_t idx_2 = CUtil::FindKeyword(line, "?");
                		size_t idx_3 = CUtil::FindKeyword(line, "default");
                		if ((idx != string::npos) && ((idx_1 == string::npos) || (idx < idx_1)) && ((idx_2 == string::npos) || (idx < idx_2)) && (idx_3 == string::npos)) {
                        		cyclomatic_cnt++;
                		}
                
                		//search for keyword "endcase"
                		idx = CUtil::FindKeyword(line, "endcase");
                		if (idx != string::npos) {
                    			switch_case_stack.pop_back();
                		}
            		}

			// search for cyclomatic complexity logical keywords
			if (cmplx_cyclomatic_logic_list.size() > 0)
				CUtil::CountTally(line, cmplx_cyclomatic_logic_list, cyclomatic_logic_cnt, 1, exclude, "", "", 0, casesensitive);

            
			// parse function name if found
			ret = (unsigned)ParseFunctionName(line, lastline, function_stack, function_name);
			if (ret != 1 && !cyclomatic_stack.empty() && cyclomatic_stack.size() == function_stack.size())
			{
				// remove count stack entry for non-function names
				cyclomatic_cnt += cyclomatic_stack.top();
				ignore_cyclomatic_cnt = 0;
				cyclomatic_stack.pop();
			}
			if (ret != 1 && !cyclomatic_logic_stack.empty() && cyclomatic_logic_stack.size() == function_stack.size()-1)
			{
				// remove count stack entry for non-function names
				cyclomatic_logic_cnt += cyclomatic_logic_stack.top();
				cyclomatic_logic_stack.pop();
			}
			if (ret != 1 && !cyclomatic_case_stack.empty() && cyclomatic_case_stack.size() == function_stack.size()-1)
			{
				// remove count stack entry for non-function names
				cyclomatic_case_cnt += cyclomatic_case_stack.top();
				cyclomatic_case_stack.pop();
			}

			if (ret == 1)
			{
				// capture count at end of function
				lineElement element(cyclomatic_cnt - ignore_cyclomatic_cnt + 1, function_name);
				result->cmplx_cycfunct_count.push_back(element);

				lineElement n_element(cyclomatic_cnt - ignore_cyclomatic_cnt + cyclomatic_logic_cnt + 1, function_name);
				result->cmplx_cycfunct_CC2_count.push_back(n_element);

				lineElement c_element(cyclomatic_case_cnt - ignore_cyclomatic_cnt + 1, function_name);
				result->cmplx_cycfunct_CC3_count.push_back(c_element);
                
				if (!function_stack.empty())
				{
					// grab previous function from stack to continue
					if (!cyclomatic_stack.empty())
					{
						cyclomatic_cnt = cyclomatic_stack.top();
						cyclomatic_stack.pop();
					}
					if (!cyclomatic_logic_stack.empty())
					{
						cyclomatic_logic_cnt = cyclomatic_logic_stack.top();
						cyclomatic_logic_stack.pop();
					}
					if (!cyclomatic_case_stack.empty())
					{
						cyclomatic_case_cnt = cyclomatic_case_stack.top();
						cyclomatic_case_stack.pop();
					}
				}
				else {
					cyclomatic_cnt = 0;
					cyclomatic_logic_cnt = 0;
					cyclomatic_case_cnt = 0;
				}
				function_name = "";
				ignore_cyclomatic_cnt = 0;
			}
			else if (ret == 2)
			{
                		if (first_line_in_main) 
				{
                    			main_cyclomatic_cnt = 1;
                    			first_line_in_main = false;
                		}
				if (main_cyclomatic_cnt < 1)
					main_cyclomatic_cnt = 1;	// add 1 for main function here in case no other decision points are found in main
				// some code doesn't belong to any function
				main_cyclomatic_cnt += cyclomatic_cnt - ignore_cyclomatic_cnt;
				main_cyclomatic_logic_cnt += cyclomatic_cnt - ignore_cyclomatic_cnt + cyclomatic_logic_cnt;
				main_cyclomatic_case_cnt += cyclomatic_case_cnt - ignore_cyclomatic_cnt;
				cyclomatic_cnt = ignore_cyclomatic_cnt = cyclomatic_logic_cnt = cyclomatic_case_cnt = 0;
			}
			else { 
				if (!function_stack.empty() && (function_stack.size() > cyclomatic_stack.size() + 1 || (cyclomatic_stack.empty() && function_stack.size() > 1)))
				{
					// capture previous complexity count from open function
					cyclomatic_stack.push(cyclomatic_cnt - ignore_cyclomatic_cnt);
					cyclomatic_cnt = ignore_cyclomatic_cnt = 0;
				}
				if (!function_stack.empty() && (function_stack.size() > cyclomatic_logic_stack.size() + 1 || (cyclomatic_logic_stack.empty() && function_stack.size() > 1)))
				{
					// capture previous complexity count from open function
					cyclomatic_logic_stack.push(cyclomatic_logic_cnt);
					cyclomatic_logic_cnt = 0;
				}
				if (!function_stack.empty() && (function_stack.size() > cyclomatic_case_stack.size() + 1 || (cyclomatic_case_stack.empty() && function_stack.size() > 1)))
				{
					// capture previous complexity count from open function
					cyclomatic_case_stack.push(cyclomatic_case_cnt);
					cyclomatic_case_cnt = 0;
				}
			}
		}
        
	}
    
	// do a single pass to mark and replace logical operator lessThan or equal "<="
	// these appear only in conditional statements
	// the remaining are signal assignment operators
	for (fit = fmap->begin(); fit != fmap->end(); fit++)
	{
		line = fit->line;
		line = CUtil::ToLower(line);
		
		if (CUtil::CheckBlank(line))
			continue;
		ss.clear();
		ss.str("");
		ss << line;
		count = -1;
		while (ss >> buf)
		{
			++count;
			if (!buf.compare("if"))
			{
				tl.lineNumber = fit->lineNumber;
				tl.position = count;
				tl.token = buf;
				buf.clear();
				conditionalVector.push_back(tl);
				continue;
			}
			// No wait in Verilog
			// No until"))
			// No assert"))
			if (!buf.compare("while"))
			{
				tl.lineNumber = fit->lineNumber;
				tl.position = count;
				tl.token = buf;
				buf.clear();
				conditionalVector.push_back(tl);
				continue;
			}
			// No loop"))
			// No next"))
			// No when"))
			// No exit"))
			if (!buf.compare("return"))
			{
				tl.lineNumber = fit->lineNumber;
				tl.position = count;
				tl.token = buf;
				buf.clear();
				conditionalVector.push_back(tl);
				continue;
			}
			if (!buf.compare("case"))
			{
				tl.lineNumber = fit->lineNumber;
				tl.position = count;
				tl.token = buf;
				buf.clear();
				conditionalVector.push_back(tl);
				continue;
			}
			if (!buf.compare("casex"))
			{
				tl.lineNumber = fit->lineNumber;
				tl.position = count;
				tl.token = buf;
				buf.clear();
				conditionalVector.push_back(tl);
				continue;
			}
			if (!buf.compare("casez"))
			{
				tl.lineNumber = fit->lineNumber;
				tl.position = count;
				tl.token = buf;
				buf.clear();
				conditionalVector.push_back(tl);
				continue;
			}
			if (buf.find_last_of(";") != string::npos)
			{
				tl.lineNumber = fit->lineNumber;
				tl.position = count;
				tl.token = ";";
				buf.clear();
				conditionalVector.push_back(tl);
				continue;
			}
			if (buf.find("<=") != string::npos)
			{
				whenCont = false;
				// iterate up the vector an look for the first conditional statement
				r_tlvIter = conditionalVector.rbegin();
				while (r_tlvIter != conditionalVector.rend())
				{
					if (!r_tlvIter->token.compare(";"))
					{
						result->cmplx_assign_count.back()++;
						result->cmplx_assign_lines++;
						tl.token = "assign";
						break;
					}
					else
					{
						if ((!r_tlvIter->token.compare("if") || !r_tlvIter->token.compare("elsif") || !r_tlvIter->token.compare("assert") ||
                             !r_tlvIter->token.compare("while") || !r_tlvIter->token.compare("return") || !r_tlvIter->token.compare("until") ) && !whenCont)
						{
                            result->cmplx_logic_count.back()++;
                            result->cmplx_logic_lines++;
                            tl.token = "lte";
                            break;
						}
						if (!r_tlvIter->token.compare("when"))
						{
							whenCont = true;
							r_tlvIter++;
							continue;
						}
						if (!r_tlvIter->token.compare("case") || !r_tlvIter->token.compare("next") || !r_tlvIter->token.compare("exit"))
						{
							result->cmplx_assign_count.back()++;
							result->cmplx_assign_lines++;
							tl.token = "assign";
							whenCont = false;
							break;
						}
						result->cmplx_assign_count.back()++;
						result->cmplx_assign_lines++;
						tl.token = "assign";
						break;
					}
					//  r_tlvIter++;   MS VC++ warning C4702 unreachable code  TODO:  Review ! ! !
				}
				tl.lineNumber = fit->lineNumber;
				tl.position = count;
				buf.clear();
				conditionalVector.push_back(tl);
				continue;
			}
		}
        
	}
    	// done with a file, if has "main" code add it
	if (main_cyclomatic_cnt > 0)
	{
		lineElement element(main_cyclomatic_cnt, "main");
		lineElement n_element(main_cyclomatic_logic_cnt, "main");
		lineElement c_element(main_cyclomatic_case_cnt, "main");
		result->cmplx_cycfunct_count.push_back(element);
		result->cmplx_cycfunct_CC2_count.push_back(n_element);
		result->cmplx_cycfunct_CC3_count.push_back(c_element);
	}
	return 1;
}