/*!
 * Parses lines for function/procedure names.
 *
 * \param line line to be processed
 * \param lastline last line processed
 * \param functionStack stack of functions
 * \param functionName function name found
 *
 * \return 1 if function name is found
 * \return 0 if it is still in some function
 * \return 2 if the code line doesn't belong to any function
 */
int CVerilogCounter::ParseFunctionName(const string &line, string &lastline, StringVector &functionStack, string &functionName)
{
	string str;
	size_t idx;
	/* FIND KEYWORD "task" / "function" */
	static int func_flag = 0, task_flag = 0;
	/* FIND KEYWORD "task" / "function" */
	idx = CUtil::FindKeyword(line, "task");
	if (idx != string::npos)
	{
		if (idx + 5 < line.length())
		{
			str = line.substr(idx + 5);
			functionStack.push_back(str);
		}
		task_flag++;/* FOUND KEYWORD "task" */
	}
	
	idx = CUtil::FindKeyword(line, "function");
	if (idx != string::npos)
	{
		if (idx + 9 < line.length())
		{
			str = line.substr(idx + 9);
			functionStack.push_back(str);
		}
		func_flag++;/* FOUND KEYWORD "function" */
	}
    
	if (functionStack.empty())
	{
		// dealing with some code out of any subroutines, it a "main" code
		return 2;
	}
    
	idx = CUtil::FindKeyword(line, "endtask");
	if(idx != string::npos){
		task_flag--;
	}
	else{
		idx = CUtil::FindKeyword(line, "endfunction");
		if(idx != string::npos){
			func_flag--;
		}
	}
	
	if (idx != string::npos)
	{
		str = functionStack.back();
		functionStack.pop_back();
		idx = str.find(";");
		if (idx != string::npos)
		{
			functionName = CUtil::ClearRedundantSpaces(str.substr(0, idx));
			lastline=line; // warning fix
			return 1;
		}
	}
	return 0;
}
예제 #2
0
TEST_F(IdfFixture, IdfObject_GroupPushingAndPopping) {
  // NON-EXTENSIBLE OBJECT
  IdfObject object(IddObjectType::Lights);
  EXPECT_TRUE(object.pushExtensibleGroup().empty());

  // MINFIELDS INCLUDES AN EXTENSIBLE GROUP, BUT EXTENSIBLE GROUPS STILL INITIALIZED AS EMPTY
  object = IdfObject(IddObjectType::BuildingSurface_Detailed);
  EXPECT_EQ(static_cast<unsigned>(10),object.numFields());
  // push empty strings
  EXPECT_FALSE(object.pushExtensibleGroup().empty());
  EXPECT_EQ(static_cast<unsigned>(13),object.numFields());
  // push non-empty strings (correct number)
  StringVector values;
  values.push_back("2.1");
  values.push_back("100.0");
  values.push_back("0.0");
  EXPECT_FALSE(object.pushExtensibleGroup(values).empty());
  EXPECT_EQ(static_cast<unsigned>(16),object.numFields());
  // try to push incorrect number of non-empty strings
  values.pop_back();
  EXPECT_TRUE(object.pushExtensibleGroup(values).empty());
  EXPECT_EQ(static_cast<unsigned>(16),object.numFields());
  // pop until false
  StringVector result;
  result.push_back("Fake entry.");
  unsigned n = 16;
  while (!result.empty()) {
    result = object.popExtensibleGroup();
    if (!result.empty()) { n -= 3; }
    EXPECT_EQ(n,object.numFields());
  }
  EXPECT_EQ(static_cast<unsigned>(10),object.numFields());

}
예제 #3
0
파일: FullID.cpp 프로젝트: ecell/ecell3
void SystemPath::canonicalize()
{
    StringVector aNewPathComponents;

    for ( StringVector::const_iterator i( theComponents.begin() );
           i != theComponents.end(); ++i )
    {
        if ( *i == "." )
        {
            continue;
        }
        else if ( *i == ".." )
        {
            if ( aNewPathComponents.empty() )
            {
                break;
            }
            aNewPathComponents.pop_back();
        }
        else
        {
            aNewPathComponents.push_back( *i );
        }
    }

    theComponents.swap( aNewPathComponents );
}
/*!
* Extracts and stores logical lines of code.
* Determines and extract logical SLOC to place in the result variable
* using addSLOC function. Each time the addSLOC function is called,
* a new logical SLOC is added. This function assumes that the directive
* is handled before it is called.
*
* \param result counter results
* \param line processed physical line of code
* \param lineBak original physical line of code
* \param strLSLOC processed logical string
* \param strLSLOCBak original logical string
* \param paren_cnt count of parenthesis
* \param forflag found for flag
* \param found_forifwhile found for, if, or while flag
* \param found_while found while flag
* \param prev_char previous character
* \param data_continue continuation of a data declaration line
* \param temp_lines tracks physical line count
* \param phys_exec_lines number of physical executable lines
* \param phys_data_lines number of physical data lines
* \param inArrayDec marks an array declaration
* \param openBrackets number of open brackets (no matching close bracket)
* \param loopLevel nested loop level
*/
void CJavascriptCounter::LSLOC(results* result, string line, size_t lineNumber, string lineBak, string &strLSLOC, string &strLSLOCBak, unsigned int &paren_cnt,
							   bool &forflag, bool &found_forifwhile, bool &found_while, char &prev_char, bool &data_continue,
							   unsigned  int &temp_lines, unsigned int &phys_exec_lines, unsigned int &phys_data_lines, bool &inArrayDec,
							   unsigned int &openBrackets, StringVector &loopLevel)
{
	// paren_cnt is used with 'for' statement only
	size_t start = 0; //starting index of the working string
	size_t i = 0, strSize;
	bool found_do, found_try, found_else, trunc_flag = false;
	string exclude = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789_$:";
	unsigned int cnt = 0;
	unsigned int loopCnt = 0;
	StringVector::iterator lit;

	string tmp = CUtil::TrimString(strLSLOC);

	// do, try
	found_do = (CUtil::FindKeyword(tmp, "do") != string::npos);
	found_try = (CUtil::FindKeyword(tmp, "try") != string::npos);
	// else is treated differently, else is included in SLOC, do and try are not
	found_else = (CUtil::FindKeyword(tmp, "else") != string::npos);

	// there may be more than 1 logical SLOC in this line
	while (i < line.length())
	{
		switch (line[i])
		{
		case ';': case '{': // LSLOC terminators
			                // ';' for normal executable or declaration statement
			                // '{' for starting a function or 'do' stmt or a block (which is counted)
			
			// get the previous logical mark until i-1 index is the new LSLOC
			// except 'do' precedes '{'
			// except '}' precedes ';' ??
			// do nothing inside 'for' statement
			if (paren_cnt > 0 && line[i] == ';')
				break;			
			
			// record open bracket for nested loop processing
			if (print_cmplx)
			{
				if (line[i] == '{')
				{
					openBrackets++;
					if ((unsigned int)loopLevel.size() < openBrackets)
						loopLevel.push_back("");
				}
				else
				{
					if ((unsigned int)loopLevel.size() > openBrackets && openBrackets > 0)
						loopLevel.pop_back();
				}
			}

			// case 'while(...);', 'while(...) {', and '} while(...);'
			// this case is handled in case ')'
			if (found_while && found_forifwhile) 
			{
				found_while = false;
				found_forifwhile = false;
				start = i + 1;
				break;
			}

			if (line[i] == '{')
			{
				if (prev_char == '=')
					inArrayDec = true;

				// continue until seeing ';'
				if (inArrayDec)
					break;

				// case for(...); and if (...) {
				// these specials are handled
				if (found_forifwhile)
				{
					found_forifwhile = false;
					start = i + 1;
					break;
				}

				// check if 'do' precedes '{'
				if (!found_do && !found_try && !found_else)
				{
					// find for 'do' in string before tmp string
					tmp = CUtil::TrimString(line.substr(start, i - start));
					found_do = (tmp == "do");		// found 'do' statement
					found_try = (tmp == "try");		// found 'try' statement
					// same as else
					found_else = (tmp == "else");	// found 'else' statement
				}
				if (found_do || found_try || found_else)
				{
					if (found_do && print_cmplx)
					{
						if (loopLevel.size() > 0)
							loopLevel.pop_back();
						loopLevel.push_back("do");
					}
					found_do = false;
					found_try = false;
					if (!found_else)
					{
						// everything before 'do', 'try' are cleared
						strLSLOC = "";
						strLSLOCBak = "";
						start = i + 1;
					}
					break; // do not store '{' following 'do'
				}
			}

			// wrong, e.g., a[]={1,2,3};
			if (line[i] == ';' && prev_char == '}')
			{
				// check if in array declaration or not
				// if no, skip, otherwise, complete the SLOC containing array declaration
				if (!inArrayDec)
				{
					start = i + 1;
					break; 
				}
			}

			inArrayDec = false;

			// check for empty statement (=1 LSLOC)
			if (CUtil::TrimString(line.substr(start, i + 1 - start)) == ";" && strLSLOC.length() < 1)
			{
				strLSLOC = ";";
				strLSLOCBak = ";";
			}
			else
			{
				strSize = CUtil::TruncateLine(i + 1 - start, strLSLOC.length(), this->lsloc_truncate, trunc_flag);
				if (strSize > 0)
				{
					strLSLOC += line.substr(start, strSize);
					strLSLOCBak += lineBak.substr(start, strSize);
				}
			}
			if (result->addSLOC(strLSLOCBak, lineNumber, trunc_flag))
			{
				cnt = 0;
				CUtil::CountTally(strLSLOC, data_name_list, cnt, 1, exclude, "", "", &result->data_name_count);

				temp_lines++;
				if (data_continue == true && line[i] == ';')
				{
					result->data_lines[LOG]++;
					phys_data_lines = temp_lines;
				}
				else
				{
					if (cnt > 0 && line[i] == ';')
					{
						result->data_lines[LOG]++;
						phys_data_lines = temp_lines;
					}
					else
					{
						result->exec_lines[LOG]++;
						phys_exec_lines = temp_lines;
					}
				}
			}
			else if (data_continue == true && line[i] == ';')
				phys_data_lines = temp_lines;
			else
				phys_exec_lines = temp_lines;
			data_continue = false;
			temp_lines = 0;
			strLSLOC = strLSLOCBak = "";
			start = i + 1;

			break;
		case '(':
			if (forflag)
				paren_cnt++;
			else
			{
				// handle 'for', 'foreach', 'while', 'if' the same way
				tmp = CUtil::TrimString(line.substr(start,i));
				if (CUtil::FindKeyword(tmp, "for") != string::npos
					|| CUtil::FindKeyword(tmp, "foreach") != string::npos
					|| CUtil::FindKeyword(tmp, "while")!= string::npos
					|| CUtil::FindKeyword(tmp, "if") != string::npos)
				{
					forflag = true;
					paren_cnt++;

					if (print_cmplx && (unsigned int)loopLevel.size() > openBrackets && openBrackets > 0)
						loopLevel.pop_back();

					if (CUtil::FindKeyword(tmp, "while")!= string::npos)
					{
						if (print_cmplx)
							loopLevel.push_back("while");
						found_while = true;
					}
					else if (print_cmplx)
					{
						if (CUtil::FindKeyword(tmp, "for") != string::npos)
							loopLevel.push_back("for");
						else if (CUtil::FindKeyword(tmp, "foreach") != string::npos)
							loopLevel.push_back("foreach");

						// record nested loop level
						if (CUtil::FindKeyword(tmp, "if") == string::npos)
						{
							loopCnt = 0;
							for (lit = loopLevel.begin(); lit < loopLevel.end(); lit++)
							{
								if ((*lit) != "")
									loopCnt++;
							}
							if ((unsigned int)result->cmplx_nestloop_count.size() < loopCnt)
								result->cmplx_nestloop_count.push_back(1);
							else
								result->cmplx_nestloop_count[loopCnt-1]++;
						}
					}
				}
			}
			break;
		case ')':
			if (forflag)
			{
				if (paren_cnt > 0)
					paren_cnt--;
				if (paren_cnt == 0) 
				{
					// handle 'for', 'foreach', 'while', 'if'
					strSize = CUtil::TruncateLine(i + 1 - start, strLSLOC.length(), this->lsloc_truncate, trunc_flag);
					if (strSize > 0)
					{
						strLSLOC += line.substr(start, strSize);
						strLSLOCBak += lineBak.substr(start, strSize);
					}
					if (result->addSLOC(strLSLOCBak, lineNumber, trunc_flag))
						result->exec_lines[LOG]++;
					strLSLOCBak = strLSLOC = "";
					phys_exec_lines = temp_lines;
					temp_lines = 0;
					start = i + 1;
					found_forifwhile = true;	
					forflag = false;
				}
			}
			break;
		case '}':
			// skip '}' when found ';' and then '}' because '{' is counted already
			// also, {} is also skipped, counted
			if (prev_char == ';' || prev_char == '{' || prev_char == '}')
				if (!inArrayDec) start = i + 1;

			// record close bracket for nested loop processing
			if (print_cmplx)
			{
				if (openBrackets > 0)
					openBrackets--;
				if (loopLevel.size() > 0)
					loopLevel.pop_back();
			}
			break;
		}

		if (line[i] != ' ' && line[i] != '\t')
		{
			// if ;}}} --> don't count }}} at all
			// also, if {}}} --> don't count }}} at all
			// if ( !(line[i] == '}' && (prev_char == ';' || prev_char == '{'))) // see case '}' above
			prev_char = line[i];

			// change to not found if a char appears before
			if (line[i] != ')' && found_forifwhile)
				found_forifwhile = false;
		}

		i++;
	}

	tmp = CUtil::TrimString(line.substr(start, i - start));
	strSize = CUtil::TruncateLine(tmp.length(), strLSLOC.length(), this->lsloc_truncate, trunc_flag);
	if (strSize > 0)
	{
		strLSLOC += tmp.substr(0, strSize);
		tmp = CUtil::TrimString(lineBak.substr(start, i - start));
		strLSLOCBak += tmp.substr(0, strSize);

		// drop continuation symbol
		if (strLSLOC[strLSLOC.length()-1] == '\\')
		{
			strLSLOC = strLSLOC.substr(0, strLSLOC.length()-1);
			strLSLOCBak = strLSLOCBak.substr(0, strLSLOCBak.length()-1);
		}
	}
	
	// make sure that we are not beginning to process a new data line
	cnt = 0;
	CUtil::CountTally(strLSLOC, data_name_list, cnt, 1, exclude, "", "", NULL);

	if (cnt > 0)
		data_continue = true;
	if (data_continue)
		temp_lines++;
	if (temp_lines == 0 && phys_data_lines == 0 && phys_exec_lines == 0)
		phys_exec_lines = 1;
}
예제 #5
0
/*!
* Parses lines for function/method names.
*
* \param line line to be processed
* \param lastline last line processed
* \param functionStack stack of functions
* \param functionName function name found
*
* \return 1 if function name is found
*/
int CCJavaCsCounter::ParseFunctionName(const string &line, string &lastline, StringVector &functionStack, string &functionName)
{
	string tline, str;
	size_t idx, tidx, cnt, cnt2;
	unsigned int cyclomatic_cnt = 0;
	string exclude = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789_$";

	tline = CUtil::TrimString(line);
	idx = tline.find('{');
	if (idx != string::npos)
	{
		// check whether it is at first index, if yes then function name is at above line
		if (idx == 0)
		{
			functionStack.push_back(lastline);
			lastline.erase();
		}
		else
		{
			str = tline.substr(0, idx);
			tidx = cnt = cnt2 = 0;
			if (str[0] != '(' && str[0] != ':' && (lastline.length() < 1 || lastline[lastline.length() - 1] != ':'))
			{
				while (tidx != string::npos)
				{
					tidx = str.find('(', tidx);
					if (tidx != string::npos)
					{
						cnt++;
						tidx++;
					}
				}
				if (cnt > 0)
				{
					tidx = 0;
					while (tidx != string::npos)
					{
						tidx = str.find(')', tidx);
						if (tidx != string::npos)
						{
							cnt2++;
							tidx++;
						}
					}
				}
			}
			// make sure parentheses are closed and no parent class listed
			if ((cnt > 0 && cnt == cnt2) || (lastline.length() > 0 && lastline[lastline.length() - 1] == ';'))
				lastline = str;
			else
				lastline += " " + str;
			functionStack.push_back(CUtil::TrimString(lastline));
			lastline.erase();
		}
	}
	else if (tline.length() > 0 && tline[tline.length() - 1] != ';' &&
		lastline.length() > 0 && lastline[lastline.length() - 1] != ';')
	{
		// append until all parentheses are closed
		tidx = lastline.find('(');
		if (tidx != string::npos)
		{
			cnt = 1;
			while (tidx != string::npos)
			{
				tidx = lastline.find('(', tidx + 1);
				if (tidx != string::npos)
					cnt++;
			}
			tidx = lastline.find(')');
			while (tidx != string::npos)
			{
				cnt++;
				tidx = lastline.find(')', tidx + 1);
			}
			if (cnt % 2 != 0)
				lastline += " " + tline;
			else
				lastline = tline;
		}
		else
			lastline = tline;
	}
	else
		lastline = tline;

	idx = line.find('}');
	if (idx != string::npos && !functionStack.empty())
	{
		str = functionStack.back();
		functionStack.pop_back();
		idx = str.find('(');

		if (idx != string::npos)
		{
			// search for cyclomatic complexity keywords and other possible keywords
			CUtil::CountTally(str, cmplx_cyclomatic_list, cyclomatic_cnt, 1, exclude, "", "", 0, casesensitive);
			if (cyclomatic_cnt <= 0 && CUtil::FindKeyword(str, "switch") == string::npos &&
				CUtil::FindKeyword(str, "try") == string::npos && CUtil::FindKeyword(str, "finally") == string::npos &&
				CUtil::FindKeyword(str, "return") == string::npos && str.find('=') == string::npos)
			{
				functionName = CUtil::ClearRedundantSpaces(str.substr(0, idx));
				lastline.erase();
				return 1;
			}
		}
		lastline.erase();
	}
	return 0;
}
/*!
* Extracts and stores logical lines of code.
* Determines and extract logical SLOC to place in the result variable
* using addSLOC function. Each time the addSLOC function is called,
* a new logical SLOC is added. This function assumes that the directive
* is handled before it is called.
*
* \param result counter results
* \param line processed physical line of code
* \param lineBak original physical line of code
* \param strLSLOC processed logical string
* \param strLSLOCBak original logical string
* \param cont_str continue string
* \param openBrackets number of open brackets (no matching close bracket)
* \param loopLevel nested loop level
*/
void CIdlCounter::LSLOC(results* result, string line, string lineBak, string &strLSLOC, string &strLSLOCBak,
    bool &cont_str, unsigned int &openBrackets, StringVector &loopLevel)
{
    size_t start = 0, len;
    size_t i = 0, j, k, strSize;
    bool trunc_flag = false;
    string tmp, tmpBak, str;

    int inlineStatement = 0;

    // check exclusions/continuation  
    tmp = CUtil::TrimString(line);
    tmpBak = CUtil::TrimString(lineBak);
    if (CUtil::FindKeyword(tmp, "end", 0, TO_END_OF_STRING, casesensitive) == 0 ||
        CUtil::FindKeyword(tmp, "endforeach", 0, TO_END_OF_STRING, casesensitive) == 0 ||
        CUtil::FindKeyword(tmp, "endfor", 0, TO_END_OF_STRING, casesensitive) == 0 ||
        CUtil::FindKeyword(tmp, "endwhile", 0, TO_END_OF_STRING, casesensitive) == 0 ||
        CUtil::FindKeyword(tmp, "endelse", 0, TO_END_OF_STRING, casesensitive) == 0 ||
        CUtil::FindKeyword(tmp, "endif", 0, TO_END_OF_STRING, casesensitive) == 0 ||
        CUtil::FindKeyword(tmp, "endcase", 0, TO_END_OF_STRING, casesensitive) == 0 ||
        CUtil::FindKeyword(tmp, "endswitch", 0, TO_END_OF_STRING, casesensitive) == 0)
    {
        if (loopLevel.size() > 0)
            loopLevel.pop_back();
        return;
    }
    else if (CUtil::FindKeyword(tmp, "repeat", 0, TO_END_OF_STRING, casesensitive) != string::npos &&
        CUtil::FindKeyword(tmp, "begin", 0, TO_END_OF_STRING, casesensitive) != string::npos)
    {
        if (loopLevel.size() > 0)
            loopLevel.pop_back();
        return;
    }
    else if (CUtil::FindKeyword(tmp, "else", 0, TO_END_OF_STRING, casesensitive) != string::npos &&
        tmp.find_first_of(":") != std::string::npos &&
        CUtil::FindKeyword(tmp, "begin", 0, TO_END_OF_STRING, casesensitive) != string::npos)
    {
        if (loopLevel.size() > 0)
            loopLevel.pop_back();
        return;
    }
    else if (CUtil::FindKeyword(tmp, "of", 0, TO_END_OF_STRING, casesensitive) == 0 )
    {
        strLSLOC += tmp + " ";
        strLSLOCBak += tmpBak + " ";
        return;
    }
    // process nested loops
    if (print_cmplx)
    {
        if (CUtil::FindKeyword(tmp, "for", 0, TO_END_OF_STRING, casesensitive) != string::npos ||
            CUtil::FindKeyword(tmp, "while", 0, TO_END_OF_STRING, casesensitive) != string::npos ||
            CUtil::FindKeyword(tmp, "foreach", 0, TO_END_OF_STRING, casesensitive) != string::npos ||
            CUtil::FindKeyword(tmp, "goto", 0, TO_END_OF_STRING, casesensitive) != string::npos ||
            CUtil::FindKeyword(tmp, "break", 0, TO_END_OF_STRING, casesensitive) != string::npos ||
            CUtil::FindKeyword(tmp, "continue", 0, TO_END_OF_STRING, casesensitive) != string::npos ||
            CUtil::FindKeyword(tmp, "until", 0, TO_END_OF_STRING, casesensitive) != string::npos)
        {
            loopLevel.push_back("loop");

            // record nested loop level
            unsigned int loopCnt = 0;
            for (StringVector::iterator lit = loopLevel.begin(); lit < loopLevel.end(); lit++)
            {
                if ((*lit) != "")
                    loopCnt++;
            }
            if ((unsigned int)result->cmplx_nestloop_count.size() < loopCnt)
                result->cmplx_nestloop_count.push_back(1);
            else
                result->cmplx_nestloop_count[loopCnt - 1]++;
        }
        else if (CUtil::FindKeyword(tmp, "if", 0, TO_END_OF_STRING, casesensitive) != string::npos ||
                 CUtil::FindKeyword(tmp, "case", 0, TO_END_OF_STRING, casesensitive) != string::npos ||
                 CUtil::FindKeyword(tmp, "switch", 0, TO_END_OF_STRING, casesensitive) != string::npos)
                loopLevel.push_back("");
    }

	if (CUtil::FindKeyword(tmp, "do", 0, TO_END_OF_STRING, casesensitive) != string::npos &&
                CUtil::FindKeyword(tmp, "begin", 0, TO_END_OF_STRING, casesensitive) == string::npos)
	{
                strSize = CUtil::TruncateLine(tmp.length(), strLSLOC.length(), this->lsloc_truncate, trunc_flag);
                if (strSize > 0)
                {
                    strLSLOC += tmp.substr(0, strSize);
                    strLSLOCBak += tmpBak.substr(0, strSize);

                    j = CUtil::ToLower(strLSLOC).find("do");
                    if (j != string::npos)
                    {
                        result->addSLOC(strLSLOCBak.substr(0, j + 2), trunc_flag);  // sloc before and including "do"
                        result->exec_lines[LOG]++;

                        result->addSLOC(strLSLOCBak.substr(j + 2), trunc_flag);     // sloc past "do"
                        result->exec_lines[LOG]++;

                        strLSLOC = strLSLOCBak = "";
                        cont_str = false;
                        inlineStatement = 1;
                    }
                }
	}
    else if (CUtil::FindKeyword(tmp, "do", 0, TO_END_OF_STRING, casesensitive) != string::npos &&
                CUtil::FindKeyword(tmp, "begin", 0, TO_END_OF_STRING, casesensitive) != string::npos)
    {
				strSize = CUtil::TruncateLine(tmp.length(), strLSLOC.length(), this->lsloc_truncate, trunc_flag);
                if (strSize > 0)
                {
                    strLSLOC += tmp.substr(0, strSize);
                    strLSLOCBak += tmpBak.substr(0, strSize);

                    j = CUtil::ToLower(strLSLOC).find("do");
                    if (j != string::npos)
                    {
                        result->addSLOC(strLSLOCBak.substr(0, j + 2), trunc_flag);  // sloc before and including "do"
						result->exec_lines[LOG]++;

						string next_str = strLSLOCBak.substr(j + 2);  // sloc past "do" and ending after "begin"

						if (CUtil::FindKeyword(next_str, "else", 0, TO_END_OF_STRING, casesensitive) != string::npos)  
						{
							size_t found_then = CUtil::ToLower(next_str).find("then");
							if (found_then != string::npos)
							{
								result->addSLOC(next_str.substr(0, found_then + 4), trunc_flag);     // sloc before and including "then"
								result->exec_lines[LOG]++;

								size_t found_else = CUtil::ToLower(next_str).find("else");
								result->addSLOC(next_str.substr(found_then + 4, found_else- found_then -4), trunc_flag);  // sloc past "then" and before "else"
								result->exec_lines[LOG]++;

								strLSLOC = strLSLOCBak = next_str = "";
								cont_str = false;
								inlineStatement = 1;
							}
						}
						else
						{
							string next_str_1 = strLSLOCBak.substr(j + 2);
							if (CUtil::FindKeyword(next_str_1, "begin", 0, TO_END_OF_STRING, casesensitive) == string::npos)   // no "begin" 
							{
								result->addSLOC(strLSLOCBak.substr(j + 2), trunc_flag);     // sloc past "do" with no "else"
								result->exec_lines[LOG]++;
							}
							else  // "begin" exists
							{
								size_t found_begin = CUtil::ToLower(next_str_1).find("begin");
								string next_str_2 = next_str_1.substr(0, found_begin);
								if(next_str_2.find_first_not_of(' ') != std::string::npos)
								{
									// There's a non-space.
									result->addSLOC(strLSLOCBak.substr(j + 2), trunc_flag);     // sloc past "do" with no "else"
									result->exec_lines[LOG]++;
								}
							}
						}

                        strLSLOC = strLSLOCBak = "";
                        cont_str = false;
                        inlineStatement = 1;
                    }
                }
	}

    if (CUtil::FindKeyword(tmp, "do", 0, TO_END_OF_STRING, casesensitive) != string::npos &&
        CUtil::FindKeyword(tmp, "begin", 0, TO_END_OF_STRING, casesensitive) == string::npos &&
        inlineStatement != 1)
    {
        strSize = CUtil::TruncateLine(tmp.length(), strLSLOC.length(), this->lsloc_truncate, trunc_flag);
        if (strSize > 0)
        {
            strLSLOC += tmp.substr(0, strSize);
            strLSLOCBak += tmpBak.substr(0, strSize);

            j = CUtil::ToLower(strLSLOC).find("do");
            if (j != string::npos)
            {
                result->addSLOC(strLSLOCBak.substr(0, j + 2), trunc_flag);  // sloc before and including "do"
                result->exec_lines[LOG]++;

                result->addSLOC(strLSLOCBak.substr(j + 2), trunc_flag);     // sloc past "do"
                result->exec_lines[LOG]++;

                strLSLOC = strLSLOCBak = "";
                cont_str = false;
                inlineStatement = 1;
            }
        }
    }

    if (CUtil::FindKeyword(tmp, "begin", 0, TO_END_OF_STRING, casesensitive) != string::npos &&
        tmp.find_first_of(":") != std::string::npos &&
        inlineStatement != 1)
    {
        strSize = CUtil::TruncateLine(tmp.length(), strLSLOC.length(), this->lsloc_truncate, trunc_flag);
        if (strSize > 0)
        {
            strLSLOC += tmp.substr(0, strSize);
            strLSLOCBak += tmpBak.substr(0, strSize);

            j = strLSLOC.find(":");
            if (j != string::npos)
            {
                string temp_string = strLSLOCBak.substr(0, j);  // sloc before ":"
                for (vector<string>::const_iterator i = statement_list.begin(); i != statement_list.end(); ++i)
                {
                    std::size_t found = temp_string.find(*i);
                    if (found != string::npos)
                    {
                        result->addSLOC(temp_string, trunc_flag);
                        result->exec_lines[LOG]++;
                        strLSLOC = strLSLOCBak = temp_string = "";
                        cont_str = false;
                        break;
                    }
                }
                inlineStatement = 1;
            }
        }
    }
    if (CUtil::FindKeyword(tmp, "begin", 0, TO_END_OF_STRING, casesensitive) == string::npos &&
        CUtil::FindKeyword(tmp, "else", 0, TO_END_OF_STRING, casesensitive) == string::npos &&
        tmp.find_first_of(":") != std::string::npos &&
		tmp.find_first_of("?") == std::string::npos &&
        inlineStatement != 1)
    {
        strSize = CUtil::TruncateLine(tmp.length(), strLSLOC.length(), this->lsloc_truncate, trunc_flag);
        if (strSize > 0)
        {
            strLSLOC += tmp.substr(0, strSize);
            strLSLOCBak += tmpBak.substr(0, strSize);

            j = strLSLOC.find(":");
            if (j != string::npos)
            {
                string temp_string_before = strLSLOCBak.substr(0, j);   // sloc before ":"
                for (vector<string>::const_iterator i = statement_list.begin(); i != statement_list.end(); ++i)
                {
                    std::size_t found = temp_string_before.find(*i);
                    if (found != std::string::npos)
                    {
                        result->addSLOC(temp_string_before, trunc_flag);
                        result->exec_lines[LOG]++;
                        break;
                    }
                }

                result->addSLOC(strLSLOCBak.substr(j + 1), trunc_flag); // sloc after ":" to the end
                result->exec_lines[LOG]++;

                strLSLOC = strLSLOCBak = temp_string_before = "";
                cont_str = false;
                inlineStatement = 1;
            }
        }
    }
    if (CUtil::FindKeyword(tmp, "begin", 0, TO_END_OF_STRING, casesensitive) == string::npos &&
        CUtil::FindKeyword(tmp, "else", 0, TO_END_OF_STRING, casesensitive) == string::npos &&
        tmp.find_first_of(":") != std::string::npos &&
		tmp.find_first_of("?") != std::string::npos &&
        inlineStatement != 1)
    {
        strSize = CUtil::TruncateLine(tmp.length(), strLSLOC.length(), this->lsloc_truncate, trunc_flag);
        if (strSize > 0)
        {
            strLSLOC += tmp.substr(0, strSize);
            strLSLOCBak += tmpBak.substr(0, strSize);

            j = strLSLOC.find("?");
            if (j != string::npos)
            {
                string temp_string_before = strLSLOCBak.substr(0, j+1);   // sloc before "?"
                for (vector<string>::const_iterator i = statement_list.begin(); i != statement_list.end(); ++i)
                {
                    std::size_t found = temp_string_before.find(*i);
                    if (found != std::string::npos)
                    {
                        result->addSLOC(temp_string_before, trunc_flag);
                        result->exec_lines[LOG]++;
                        break;
                    }
                }

				string temp_string_after = strLSLOCBak.substr(j + 1);
				k = strLSLOC.find(":");

                result->addSLOC(strLSLOCBak.substr(j + 1, k - j - 1), trunc_flag); // sloc after "?" to ":"
                result->exec_lines[LOG]++;

                result->addSLOC(strLSLOCBak.substr(k), trunc_flag); // sloc after ":" to the end
                result->exec_lines[LOG]++;

				strLSLOC = strLSLOCBak = temp_string_before = temp_string_after = "";
				cont_str = false;
				inlineStatement = 1;


            }
        }
    }

    if (CUtil::FindKeyword(tmp, "repeat", 0, TO_END_OF_STRING, casesensitive) != string::npos &&
        CUtil::FindKeyword(tmp, "until", 0, TO_END_OF_STRING, casesensitive) != string::npos &&
        CUtil::FindKeyword(tmp, "begin", 0, TO_END_OF_STRING, casesensitive) == string::npos &&
        inlineStatement != 1)
    {
        strSize = CUtil::TruncateLine(tmp.length(), strLSLOC.length(), this->lsloc_truncate, trunc_flag);
        if (strSize > 0)
        {
            strLSLOC += tmp.substr(0, strSize);
            strLSLOCBak += tmpBak.substr(0, strSize);

            j = CUtil::ToLower(strLSLOC).find("until");
            if (j != string::npos)
            {
                result->addSLOC(strLSLOCBak.substr(0, j), trunc_flag);  // sloc before "until"
                result->exec_lines[LOG]++;

                result->addSLOC(strLSLOCBak.substr(j), trunc_flag);     // sloc from "until" to the end
                result->exec_lines[LOG]++;

                strLSLOC = strLSLOCBak = "";
                cont_str = false;
                inlineStatement = 1;
            }
        }
    }

    if (CUtil::FindKeyword(tmp, "then", 0, TO_END_OF_STRING, casesensitive) != string::npos &&
        CUtil::FindKeyword(tmp, "begin", 0, TO_END_OF_STRING, casesensitive) == string::npos &&
        CUtil::FindKeyword(tmp, "else", 0, TO_END_OF_STRING, casesensitive) == string::npos &&
        inlineStatement != 1 &&
		tmp.substr(tmp.length() - 1, 1) != "$")
    {
        strSize = CUtil::TruncateLine(tmp.length(), strLSLOC.length(), this->lsloc_truncate, trunc_flag);
        if (strSize > 0)
        {
            strLSLOC += tmp.substr(0, strSize);
            strLSLOCBak += tmpBak.substr(0, strSize);

            size_t found_then = CUtil::ToLower(strLSLOC).find("then");
            if (found_then != string::npos)
            {
                result->addSLOC(strLSLOCBak.substr(0, found_then + 4), trunc_flag);  // sloc before and including "then"
                result->exec_lines[LOG]++;

                result->addSLOC(strLSLOCBak.substr(found_then + 4), trunc_flag);     // sloc past "then"
                result->exec_lines[LOG]++;

                strLSLOC = strLSLOCBak = "";
                cont_str = false;
                inlineStatement = 1;
            }
        }
    }

    if (CUtil::FindKeyword(tmp, "then", 0, TO_END_OF_STRING, casesensitive) != string::npos &&
        CUtil::FindKeyword(tmp, "else", 0, TO_END_OF_STRING, casesensitive) != string::npos &&
        CUtil::FindKeyword(tmp, "begin", 0, TO_END_OF_STRING, casesensitive) == string::npos &&
        inlineStatement != 1)
    {
        strSize = CUtil::TruncateLine(tmp.length(), strLSLOC.length(), this->lsloc_truncate, trunc_flag);
        if (strSize > 0)
        {
            strLSLOC += tmp.substr(0, strSize);
            strLSLOCBak += tmpBak.substr(0, strSize);

            str = CUtil::ToLower(strLSLOC);
            size_t found_then = str.find("then");
            if (found_then != string::npos)
            {
                result->addSLOC(strLSLOCBak.substr(0, found_then + 4), trunc_flag);     // sloc before and including "then"
                result->exec_lines[LOG]++;

                size_t found_else = str.find("else");
                result->addSLOC(strLSLOCBak.substr(found_then + 4, found_else - found_then - 4), trunc_flag);  // sloc past "then" and before "else"
                result->exec_lines[LOG]++;

                result->addSLOC(strLSLOCBak.substr(found_else), trunc_flag);                    // sloc from "else" to the end
                result->exec_lines[LOG]++;

                strLSLOC = strLSLOCBak = "";
                cont_str = false;
                inlineStatement = 1;
            }
        }
    }

    if (CUtil::FindKeyword(tmp, "then", 0, TO_END_OF_STRING, casesensitive) != string::npos &&
        CUtil::FindKeyword(tmp, "else", 0, TO_END_OF_STRING, casesensitive) != string::npos &&
        CUtil::FindKeyword(tmp, "begin", 0, TO_END_OF_STRING, casesensitive) != string::npos &&
        inlineStatement != 1)
    {
        strSize = CUtil::TruncateLine(tmp.length(), strLSLOC.length(), this->lsloc_truncate, trunc_flag);
        if (strSize > 0)
        {
            strLSLOC += tmp.substr(0, strSize);
            strLSLOCBak += tmpBak.substr(0, strSize);

            str = CUtil::ToLower(strLSLOC);
            size_t found_then = str.find("then");
            if (found_then != string::npos)
            {
                result->addSLOC(strLSLOCBak.substr(0, found_then + 4), trunc_flag);     // sloc before and including "then"
                result->exec_lines[LOG]++;

                size_t found_else = str.find("else");
                result->addSLOC(strLSLOCBak.substr(found_then + 4, found_else- found_then -4), trunc_flag);  // sloc past "then" and before "else"
                result->exec_lines[LOG]++;

                strLSLOC = strLSLOCBak = "";
                cont_str = false;
                inlineStatement = 1;
            }
        }
    }

    // there may be more than 1 logical SLOC in this line
    while (i < line.length())
    {
        switch (line[i])
        {
        case '&': case '\n': // LSLOC terminators
		{
            if (openBrackets > 0)
            {
                i++;
                continue;
            }
            tmp = CUtil::TrimString(line.substr(start, i - start + 1));
            tmpBak = CUtil::TrimString(lineBak.substr(start, i - start + 1));

            if (cont_str && strLSLOC.length() > 0)
            {
                // check for string continuation
                if (tmp[0] == '$')
                {
                    tmp = tmp.substr(1, tmp.length() - 1);
                    tmpBak = tmpBak.substr(1, tmpBak.length() - 1);
                }
            }
            strSize = CUtil::TruncateLine(tmp.length(), strLSLOC.length(), this->lsloc_truncate, trunc_flag);
            if (strSize > 0)
            {
                strLSLOC += tmp.substr(0, strSize);
                strLSLOCBak += tmpBak.substr(0, strSize);
            }

		    std::size_t found = strLSLOCBak.find("&");

		    if (found!=std::string::npos)
		    {
				  result->addSLOC(strLSLOCBak.substr(0, found), trunc_flag);     // sloc before "&"
				  result->exec_lines[LOG]++;
		    }
			else 
			{
				result->addSLOC(strLSLOCBak, trunc_flag);  	  
				result->exec_lines[LOG]++;
			}

            strLSLOC = strLSLOCBak = "";
            cont_str = false;
            start = i + 1;
            break;
		}
        case '[': case '(': case '{':
            openBrackets++;
            break;
        case ']': case ')': case '}':
            openBrackets--;
            break;
        }
        i++;
    }

    // check for line continuation
    tmp = CUtil::TrimString(line.substr(start, i - start));
    tmpBak = CUtil::TrimString(lineBak.substr(start, i - start));
    if (tmp.length() > 3 && tmp.substr(tmp.length() - 1, 1) == "$")
    {
        // strip off trailing ($)
        tmp = tmp.substr(0, tmp.length() - 1);
        tmpBak = tmpBak.substr(0, tmpBak.length() - 1);
        len = tmp.length();

        strSize = CUtil::TruncateLine(len, strLSLOC.length(), this->lsloc_truncate, trunc_flag);
        if (strSize > 0)
        {
            if (cont_str)
            {
                strLSLOC += CUtil::TrimString(tmp.substr(0, strSize), -1);
                strLSLOCBak += CUtil::TrimString(tmpBak.substr(0, strSize), -1);
            }
            else
            {
                strLSLOC += CUtil::TrimString(tmp.substr(0, strSize)) + " ";
                strLSLOCBak += CUtil::TrimString(tmpBak.substr(0, strSize)) + " ";
            }
        }
    }
    else if (inlineStatement == 0)
    {
        strSize = CUtil::TruncateLine(tmp.length(), strLSLOC.length(), this->lsloc_truncate, trunc_flag);
        if (strSize > 0)
        {
            strLSLOC += tmp.substr(0, strSize);
            strLSLOCBak += tmpBak.substr(0, strSize);

            result->addSLOC(strLSLOCBak, trunc_flag);
            result->exec_lines[LOG]++;
            strLSLOC = strLSLOCBak = "";
            cont_str = false;
        }
    }
	inlineStatement = 0;
 
}
예제 #7
0
/*!
* Extracts and stores logical lines of code.
* Determines and extract logical SLOC to place in the result variable
* using addSLOC function. Each time the addSLOC function is called,
* a new logical SLOC is added. This function assumes that the directive
* is handled before it is called.
*
* \param result counter results
* \param line processed physical line of code
* \param lineBak original physical line of code
* \param strLSLOC processed logical string
* \param strLSLOCBak original logical string
* \param data_continue continuation of a data declaration line
* \param temp_lines tracks physical line count
* \param phys_exec_lines number of physical executable lines
* \param phys_data_lines number of physical data lines
* \param loopLevel nested loop level
*/
void CBashCounter::LSLOC(results* result, string line, string lineBak, string &strLSLOC, string &strLSLOCBak,
						 bool &data_continue, unsigned int &temp_lines, unsigned int &phys_exec_lines,
						 unsigned int &phys_data_lines, StringVector &loopLevel)
{
	size_t start, end;
	size_t i = 0, m, strSize;
	bool trunc_flag = false, found;
	string exclude = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789_$";
	string str, spc;
	unsigned int cnt = 0;

	string tmp    = CUtil::TrimString(line);
	string tmpBak = CUtil::TrimString(lineBak);
	start = 0;

	// skip whole line '{' or '}'
	if (tmp == "{" || tmp == "}")
	{
		strLSLOC = strLSLOCBak = "";
		phys_exec_lines++;
		temp_lines = 0;
		return;
	}

	// trim trailing '{'
	if (tmp[tmp.length() - 1] == '{')
	{
		tmp = CUtil::TrimString(tmp.substr(0, tmp.length() - 1));
		tmpBak = CUtil::TrimString(tmpBak.substr(0, tmpBak.length() - 1));
	}

	// there may be more than 1 logical SLOC in this line
	while (start < tmp.length())
	{
		// check for semicolon to denote end of SLOC
		end = tmp.find(";", start);
		if (end != string::npos)
		{
			// handle empty statement
			if (CUtil::TrimString(tmp.substr(start, end - start + 1)) == ";")
			{
				start = end + 1;
				strLSLOC = strLSLOCBak = "";
				temp_lines = 0;
				if (tmp == ";")
					phys_exec_lines++;
				continue;
			}

			// handle for (( ; ; ))
			i = CUtil::FindKeyword(tmp, "for", start, end); 
			if (i != string::npos)
			{
				i += 3;
				i = tmp.find("((", i);
				if (i != string::npos && i < end)
				{
					i += 2;
					i = tmp.find("))", i);
					if (i != string::npos)
					{
						i += 2;
						end = tmp.find(";", i);
						if (end == string::npos)
							end = tmp.length() - 1;
					}
					else
						end = tmp.length() - 1;
				}
			}

			// handle case ';;' or ';&' or ';;&'
			if (end < tmp.length() - 1)
			{
				if (tmp[end + 1] == ';' || tmp[end + 1] == '&')
					end++;
				if (end < tmp.length() - 2 && tmp[end + 2] == '&')
					end++;
			}
		}
		else
			end = tmp.length() - 1;

		// process nested loops
		if (print_cmplx)
		{
			str = CUtil::TrimString(tmp.substr(start, end - start + 1));
			if (CUtil::FindKeyword(str, "for") != string::npos
				|| CUtil::FindKeyword(str, "while") != string::npos
				|| CUtil::FindKeyword(str, "until")!= string::npos
				|| CUtil::FindKeyword(str, "select")!= string::npos)
			{
				if (CUtil::FindKeyword(str, "for") != string::npos)
					loopLevel.push_back("for");
				else if (CUtil::FindKeyword(str, "while")!= string::npos)
					loopLevel.push_back("while");
				else if (CUtil::FindKeyword(str, "until") != string::npos)
					loopLevel.push_back("until");
				else if (CUtil::FindKeyword(str, "select") != string::npos)
					loopLevel.push_back("");

				// record nested loop level
				if (CUtil::FindKeyword(str, "select") == string::npos)
				{
					unsigned int loopCnt = 0;
					for (StringVector::iterator lit = loopLevel.begin(); lit < loopLevel.end(); lit++)
					{
						if ((*lit) != "")
							loopCnt++;
					}
					if ((unsigned int)result->cmplx_nestloop_count.size() < loopCnt)
						result->cmplx_nestloop_count.push_back(1);
					else
						result->cmplx_nestloop_count[loopCnt-1]++;
				}
			}
			if (CUtil::FindKeyword(str, "done") != string::npos && loopLevel.size() > 0)
				loopLevel.pop_back();
		}

		// check for line containing excluded keywords
		for (StringVector::iterator it = exclude_keywords.begin(); it != exclude_keywords.end(); it++)
		{
			i = CUtil::FindKeyword(tmp, (*it), start, end);
			if (i != string::npos)
			{
				// strip specified keyword and skip if empty
				start = i + (*it).length();
				if (CUtil::CheckBlank(CUtil::TrimString(tmp.substr(start, end - start))))
					start = end + 1;
				break;
			}
		}
		if (start > end)
		{
			if (temp_lines == 0 && phys_data_lines == 0 && phys_exec_lines == 0)
				phys_exec_lines = 1;
			continue;
		}

		// check for continuation words
		found = false;
		if (tmp[end] == ';')
			str = CUtil::TrimString(tmp.substr(start, end - start));
		else
			str = CUtil::TrimString(tmp.substr(start, end - start + 1));
		for (StringVector::iterator it = continue_keywords.begin(); it != continue_keywords.end(); it++)
		{
			if (str == (*it))
			{
				found = true;
				strLSLOC += str + " ";
				strLSLOCBak += str + " ";
				start = end + 1;
				if (temp_lines == 0 && phys_data_lines == 0 && phys_exec_lines == 0)
					phys_exec_lines = 1;
				temp_lines = 0;
			}
		}
		if (found)
			continue;

		// check for line continuation
		if (tmp[end] == '\\')
		{
			// strip off trailing (\)
			strSize = CUtil::TruncateLine(end - start, strLSLOC.length(), this->lsloc_truncate, trunc_flag);
			if (strSize > 0)
			{
				spc = "";
				str = tmp.substr(start, strSize);
				for (m = str.length() - 1; m > 0; m--)
				{
					if (str[m] == ' ')
						spc += " ";
					else
						break;
				}
				if (m == 0)
				{
					if (str[0] == ' ')
						spc += " ";
				}
				strLSLOC += CUtil::TrimString(tmp.substr(start, strSize)) + spc;
				strLSLOCBak += CUtil::TrimString(tmpBak.substr(start, strSize)) + spc;
			}
			start = end + 1;

			// make sure that we are not beginning to process a new data line
			cnt = 0;
			CUtil::CountTally(strLSLOC, data_name_list, cnt, 1, exclude, "", "", NULL);

			if (cnt > 0)
				data_continue = true;
			if (data_continue == true)
				temp_lines++;
			if (temp_lines == 0 && phys_data_lines == 0 && phys_exec_lines == 0)
				phys_exec_lines = 1;
		}
		else
		{
			// save LSLOC
			if (tmp[end] == ';')
			{
				// don't trim if ';;'
				if (tmp.length() > 1 && tmp[end - 1] == ';')
					strSize = CUtil::TruncateLine(end - start + 1, strLSLOC.length(), this->lsloc_truncate, trunc_flag);
				else
					strSize = CUtil::TruncateLine(end - start, strLSLOC.length(), this->lsloc_truncate, trunc_flag);
			}
			else
				strSize = CUtil::TruncateLine(end - start + 1, strLSLOC.length(), this->lsloc_truncate, trunc_flag);
			if (strSize > 0)
			{
				strLSLOC += CUtil::TrimString(tmp.substr(start, strSize));
				strLSLOCBak += CUtil::TrimString(tmpBak.substr(start, strSize));
			}
			start = end + 1;
			if (strLSLOCBak.length() > 0)
			{
				if (result->addSLOC(strLSLOCBak, trunc_flag))
				{
					// add a logical SLOC
					cnt = 0;
					CUtil::CountTally(strLSLOC, data_name_list, cnt, 1, exclude, "", "", &result->data_name_count);

					temp_lines++;
					if (data_continue == true || cnt > 0)
					{
						result->data_lines[LOG]++;
						phys_data_lines = temp_lines;
					}
					else
					{
						result->exec_lines[LOG]++;
						phys_exec_lines = temp_lines;
					}
				}
				else if (data_continue == true)
					phys_data_lines = temp_lines;
				else
					phys_exec_lines = temp_lines;
			}
			data_continue = false;
			temp_lines = 0;
			strLSLOC = strLSLOCBak = "";
		}
	}
}
예제 #8
0
bool CConverToMK::ProcessPath(const char* pszVCPath,
							  const char* pszPath,
							  string& strRes )
{
	if (0 == pszPath || !*pszPath)
	{
		return false;
	}

	if (strRes.size())
	{
		strRes = "";
	}

	filesystem::path kVCFile(pszVCPath);
	filesystem::path kMKFile(m_pszMKFile);
	filesystem::path kInputPath(pszPath);

	unsigned int uiParentFolderCount = 0;
	string strFilename = kInputPath.filename().string();

	kInputPath = kInputPath.parent_path();

	kVCFile = kVCFile.parent_path();
	kMKFile = kMKFile.parent_path();

	StringVector kVCSets;
	StringVector kMKSets;
	StringVector kTargetSets;
	StringVector kTempVC;

	BOOST_AUTO(pkInputPathPos,kInputPath.begin());
	BOOST_AUTO(pkVCPos,kVCFile.begin());
	BOOST_AUTO(pkMKPos,kMKFile.begin());

	while (pkInputPathPos != kInputPath.end())
	{
		string strPath = pkInputPathPos->string().c_str();

		if (strcmp(strPath.c_str(),"..") == 0)
		{
			uiParentFolderCount++;
			pkInputPathPos++;
			continue;
		}

		kTargetSets.push_back(strPath);
		pkInputPathPos++;
	}

	while (pkVCPos != kVCFile.end())
	{
		filesystem::path strVC = *pkVCPos;
		kVCSets.push_back(strVC.string());
		pkVCPos++;
	}

	kTempVC = kVCSets;

	while (0 < uiParentFolderCount)
	{
		kTempVC.pop_back();
		kVCSets.pop_back();
		uiParentFolderCount--;
	}

	while (pkMKPos != kMKFile.end())
	{
		string strVC = pkMKPos->string();
		kMKSets.push_back(strVC);
		pkMKPos++;
	}

	unsigned int uiMin = kMKSets.size() < kVCSets.size() ?
		kMKSets.size() : kVCSets.size();
	unsigned int uiIndex = 0;

	for (uiIndex = 0;uiIndex < uiMin;uiIndex++)
	{
		if (strcmp(kMKSets[uiIndex].c_str(),kVCSets[uiIndex].c_str()) != 0)
		{
			break;
		}
	}

	kMKSets.erase(kMKSets.begin(),kMKSets.begin() + uiIndex);
	kVCSets.erase(kVCSets.begin(),kVCSets.begin() + uiIndex);

	strRes += ".";
	string strPrePath = "";

	for (unsigned int uiIndex = 0;uiIndex < kTempVC.size();uiIndex++)
	{
		strPrePath += kTempVC[uiIndex];
		strPrePath += "\\";
	}

	for (unsigned int uiIndex = 0;uiIndex < kVCSets.size();uiIndex++)
	{
		strRes += "\\";
		strRes += kVCSets[uiIndex];
	}

	for (unsigned int uiIndex = 0;uiIndex < kTargetSets.size();uiIndex++)
	{
		strRes += "\\";
		strPrePath += kTargetSets[uiIndex];
		strPrePath += "\\";

		strRes += kTargetSets[uiIndex];
	}

	strRes += "\\";
	strRes += strFilename;
	strPrePath += strFilename;

	if (!CheckFileExist(strPrePath.c_str()))
	{
		return false;
	}

	return true;
}
예제 #9
0
/*!
 * Parses lines for function/method names.
 *
 * \param line line to be processed
 * \param needIndentation last line processed
 * \param functionStack stack of functions
 * \param functionName function name found
 *
 * \return 1 if function name is found
 */
int CPythonCounter::ParseFunctionName(const string &line, string & needIndentation, StringVector &functionStack, string &functionName, vector<int> &indenStack, int & numWS)
{
    	string str;
	size_t idx;
    	int functionWS = 0;
    	if(indenStack.empty()){
        	indenStack.push_back(0);
    	}
    	functionWS = indenStack.back(); // current function's indentation
    	if (functionStack.empty()) {        
        	functionStack.push_back("");
        	needIndentation = "";
    	}
    
    	string tmp;
    	//get white spaces
    	tmp = line;
    	tmp = CUtil::TrimString(tmp, -1);
    
    	numWS = (unsigned)(line.length() - tmp.length());

    	//last line is with "def", if needIndentation=="YES"
    	//not consider the body of function is in the same line of "def"
    	if(needIndentation.length() >= 3 && needIndentation == "YES"){
        	indenStack.push_back(numWS);
        	needIndentation = "";
    	}
    	string mark = needIndentation; 
    
	idx = CUtil::FindKeyword(line, "def");
	if (idx != string::npos)
	{
		if (idx + 4 < line.length())
		{
			str = line.substr(idx + 4);
			functionStack.push_back(str);
            		needIndentation = "YES"; //indicate next line need to get the indentation
		}
	}
    if (functionStack.size() == 1 || functionStack.size() == 0)
	{
		// dealing with some code out of any subroutines, it is a "main" code
		return 2;
	}
    
    	if(mark != "YES"){
        	if (functionWS > numWS && functionStack.size() > 1 ) {
		    	//the first element in functionStack is ""
		    
		    	//we need to get the function and pop the function from the functionStack
			if(needIndentation=="YES"){
				//we have already pushed the new function to the functionStack
				string tempp = functionStack.back(); //pop new function
				functionStack.pop_back();
				
				str = functionStack.back();
				functionStack.pop_back();
				
				functionStack.push_back(tempp); // push new function
				indenStack.pop_back(); //pop the function's indentation in the stack
			}
			else{
		        	str = functionStack.back();
		        	functionStack.pop_back();
		        	indenStack.pop_back(); //pop the function's indentation in the stack

			}
		   
			//get function's name
			idx = str.find("(");
			if (idx != string::npos)
			{
				functionName = CUtil::ClearRedundantSpaces(str.substr(0, idx));
				return 1;
			}
        	}
	}
	return 0;    
}
예제 #10
0
파일: main.cpp 프로젝트: sed-szeged/soda
void processJsonFiles(String path)
{
    try {
        std::cout << "[INFO] Processing " << path << " configuration file." << endl;

        boost::filesystem::path jsonPath(path);
        CSelectionData selectionData;
        CJsonReader reader = CJsonReader(path);

        String programName = reader.getStringFromProperty("program-name");
        if (programName.empty()) {
            std::cerr << "[ERROR] Program name is missing in configuration file:" << path << std::endl;
            return;
        }

        StringVector reductionList = reader.getStringVectorFromProperty("reduction-method");
        if (reductionList.empty()) {
            std::cerr << "[ERROR] reduction-algorithm is missing from the configuration file("
                      << path << ")." << std::endl;
            printPluginNames(kernel.getTestSuiteReductionPluginManager().getPluginNames());
            return;
        } else {
            int iteration = reader.getIntFromProperty("iteration");
            for (StringVector::const_iterator it = reductionList.begin(); it != reductionList.end(); ++it) {
                if (*it == "duplation" && !iteration) {
                    std::cerr << "[ERROR] Missing iteration parameter for duplation reduction method in configuration file: "
                              << path << "." << std::endl;
                    return;
                }

                if (*it == "random" && !iteration && reader.getIntVectorFromProperty("reduction-sizes").empty()) {
                    std::cerr << "[ERROR] Missing iteration or reduction-sizes parameter for random reduction method in configuration file: "
                              << path << "." << std::endl;
                    return;
                }

                try {
                    kernel.getTestSuiteReductionPluginManager().getPlugin(*it);
                } catch (std::out_of_range &e) {
                    std::cerr << "[ERROR] Invalid reduction algorithm name(" << *it
                              << ") in configuration file: " << path << "." << std::endl;
                    return;
                }
            }
        }

        String covPath = reader.getStringFromProperty("coverage-data");
        if (covPath[0] == '.') {
            covPath = jsonPath.parent_path().string() + "/" + covPath;
        }

        String resPath = reader.getStringFromProperty("results-data");
        if (resPath[0] == '.') {
            resPath = jsonPath.parent_path().string() + "/" + resPath;
        }

        if (exists(covPath)
                && exists(resPath)) {
            (std::cerr << "[INFO] loading coverage from " << covPath << " ...").flush();
            selectionData.loadCoverage(covPath);
            (std::cerr << " done\n[INFO] loading results from " << resPath << " ...").flush();
            selectionData.loadResults(resPath);
            (std::cerr << " done" << std::endl).flush();
        } else {
            std::cerr << "[ERROR] Missing or invalid input files in config file " << path << "." << std::endl;
            return;
        }

        if (reader.getBoolFromProperty("globalize")) {
            // Globalize data.
            (std::cerr << "[INFO] Globalizing ... ").flush();
            selectionData.globalize();
            selectionData.filterToCoverage();
            (std::cerr << " done" << std::endl).flush();
        }

        String dirPath = reader.getStringFromProperty("output-dir");
        if (dirPath[0] == '.') {
            dirPath = jsonPath.parent_path().string() + "/" + dirPath;
            reader.setProperty("output-dir", dirPath);
        }

        if (!(boost::filesystem::exists(dirPath))) {
            boost::filesystem::create_directory(dirPath);
        }

        boost::filesystem::path p = boost::filesystem::path(covPath).filename();

        while (!reductionList.empty()) {
            string reductionMethod = reductionList.back();
            reductionList.pop_back();
            ITestSuiteReductionPlugin *plugin = NULL;

            std::ofstream outStream((dirPath + "/" + reductionMethod + "-" + p.string() + ".reduced").c_str());
            if (!outStream.good()) {
                throw CException("Reduction output file error.", reader.getStringFromProperty("coverage-data") + ".reduced");
            }

            try {
                plugin = kernel.getTestSuiteReductionPluginManager().getPlugin(reductionMethod);
                plugin->init(&selectionData, reader);
            } catch (std::out_of_range &e) {
                std::cerr << "[ERROR] Unknown reduction mode. " << std::endl;
                printPluginNames(kernel.getTestSuiteReductionPluginManager().getPluginNames());
                return;
            }
            plugin->reduction(outStream);
            outStream.close();
        }
    } catch (std::exception &e) {
        std::cerr << e.what() << std::endl;
        return;
    } catch (...) {
        std::cerr << "Exception of unknown type while processsing configuration file(" << path << ") arguments."
                  << std::endl;
        return;
    }
    return;
}
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;
}
/*!
 * Extracts and stores logical lines of code.
 * Determines and extract logical SLOC to place in the result variable
 * using addSLOC function. Each time the addSLOC function is called,
 * a new logical SLOC is added. This function assumes that the directive
 * is handled before it is called.
 *
 * \param result counter results
 * \param line processed physical line of code
 * \param lineBak original physical line of code
 * \param strLSLOC processed logical string
 * \param strLSLOCBak original logical string
 * \param paren_cnt count of parenthesis
 * \param forflag found for flag
 * \param found_forifwhile found for, if, or while flag
 * \param found_while found while flag
 * \param prev_char previous character
 * \param data_continue continuation of a data declaration line
 * \param temp_lines tracks physical line count
 * \param phys_exec_lines number of physical executable lines
 * \param phys_data_lines number of physical data lines
 * \param found_for found for loop
 * \param loopLevel nested loop level
 * \param always_flag found always
 * \param case_flag found case
 * \param repeat_flag found repeat
 */
void CVerilogCounter::LSLOC(results* result, string line, size_t lineNumber, string lineBak, string &strLSLOC, string &strLSLOCBak, 
				unsigned int &paren_cnt, bool &forflag, bool &found_forifwhile, bool &found_while, char &prev_char, 
				bool &data_continue, unsigned int &temp_lines, unsigned int &phys_exec_lines, unsigned int &phys_data_lines,
				bool &found_for, StringVector &loopLevel, bool &always_flag, bool &case_flag, bool &repeat_flag)
{
	// paren_cnt is used with 'for' statement only
	size_t start = 0, startmax = 0; // starting index of the working string
	size_t i = 0, strSize;
	bool trunc_flag = false;
	string exclude = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789_$:";
	string dataExclude = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789_$:().";	// avoid double count of casts as data and executable lines (e.g. set { m_uiValue = (uint)value; }
	bool found_end = false, found_endcase = false;
	unsigned int cnt = 0;
	bool newline = true;
    
	string tmp = CUtil::TrimString(strLSLOC);
	size_t tmpi;
    
	// there may be more than 1 logical SLOC in this line
	while (i < line.length())
	{
		tmp = CUtil::TrimString(line.substr(start, i + 1 - start));
		if (CUtil::FindKeyword(tmp, "end") != string::npos && loopLevel.size() > 0 && loopLevel.back().compare("begin") == 0)
		{
			loopLevel.pop_back();	// pop begin
			loopLevel.pop_back();	// pop looping
			start = i + 1;
		}
		if ((tmpi = CUtil::FindKeyword(line.substr(start, i + 1 - start), "generate")) != string::npos)
		{
			strSize = CUtil::TruncateLine(i + 1 - start, strLSLOC.length(), this->lsloc_truncate, trunc_flag);
			if (strSize > 0)
			{
				strLSLOC += line.substr(start, strSize);
				strLSLOCBak += lineBak.substr(start, strSize);
			}
			if (result->addSLOC(strLSLOCBak, lineNumber, trunc_flag))
				result->exec_lines[LOG]++;
			strLSLOCBak = strLSLOC = "";
			phys_exec_lines = temp_lines;
			temp_lines = 0;
			start = start + 7 + tmpi;
			found_forifwhile = false;
			forflag = false;
			found_for = false;
			always_flag = false;
			case_flag = false;
			repeat_flag = false;
		}
        
		if ((tmpi = CUtil::FindKeyword(line.substr(start, i + 1 - start), "forever")) != string::npos)
		{
			if (print_cmplx)
			{
				tmp = CUtil::TrimString(line.substr(start, i + 1 - start));
				tmp = strLSLOC + " " + tmp;
				if (CUtil::FindKeyword(tmp, "begin") != string::npos && loopLevel.size() > 0 && loopLevel.back().compare("looping") == 0)
				{
					loopLevel.push_back("begin");
				}
				else if (loopLevel.size() > 0)
				{
					// didn't find begin, so pop off since no longer in a looping block
					loopLevel.pop_back();
				}
				loopLevel.push_back("looping");
				// forever doesn't have any conditions so just add it to sloc
				unsigned int loopCnt = 0;
				for (StringVector::iterator lit = loopLevel.begin(); lit < loopLevel.end(); lit++)
				{
					if ((*lit) != "begin")
						loopCnt++;
				}
				if ((unsigned int)result->cmplx_nestloop_count.size() < loopCnt)
					result->cmplx_nestloop_count.push_back(1);
				else
					result->cmplx_nestloop_count[loopCnt-1]++;
			}
			strSize = CUtil::TruncateLine(i + 1 - start, strLSLOC.length(), this->lsloc_truncate, trunc_flag);
			if (strSize > 0)
			{
				strLSLOC += line.substr(start, strSize);
				strLSLOCBak += lineBak.substr(start, strSize);
			}
			if (result->addSLOC(strLSLOCBak, lineNumber, trunc_flag))
				result->exec_lines[LOG]++;
			strLSLOCBak = strLSLOC = "";
			phys_exec_lines = temp_lines;
			temp_lines = 0;
			start = start + 7 + tmpi;
			found_forifwhile = true;
			forflag = false;
			found_for = false;
			always_flag = false;
			case_flag = false;
			repeat_flag = false;
		}
        
		switch (line[i])
		{
            case ';': // LSLOC terminators
                // ';' for normal executable or declaration statement
                // '{' for starting a function or 'do' stmt or a block (which is counted)
                // get the previous logical mark until i-1 index is the new LSLOC
                // except 'do' precedes '{'
                // except '}' precedes ';' ??
                // do nothing inside 'for' statement
                if (found_for == true && paren_cnt > 0 && line[i] == ';')
                    break;
                
                // record open bracket for nested loop processing
                if (print_cmplx)
                {
                    tmp = CUtil::TrimString(line.substr(start, i + 1 - start));
                    tmp = strLSLOC + " " + tmp;
                    
                    if (CUtil::FindKeyword(tmp, "begin") != string::npos && loopLevel.size() > 0 && loopLevel.back().compare("looping") == 0)
                    {
                        loopLevel.push_back("begin");
                    }
                    else if (loopLevel.size() > 0 && loopLevel.back().compare("begin") != 0)	// check that this isn't already in a begin block...if it is leave it alone
                    {
                        // didn't find begin, so pop off since no longer in a looping block
                        loopLevel.pop_back();
                    }
                }
                // case 'while(...);', 'while(...) {', and '} while(...);'
                // this case is handled in case ')'
                if (found_while && found_forifwhile)
                {
                    found_while = false;
                    found_forifwhile = false;
                    start = i + 1;
                    break;
                }
                
                // check for empty statement (=1 LSLOC)
                if (CUtil::TrimString(line.substr(start, i + 1 - start)) == ";" && strLSLOC.length() < 1)
                {
                    strLSLOC = ";";
                    strLSLOCBak = ";";
                }
                else
                {
                    strSize = CUtil::TruncateLine(i + 1 - start, strLSLOC.length(), this->lsloc_truncate, trunc_flag);
                    if (strSize > 0)
                    {
                        strLSLOC += line.substr(start, strSize);
                        strLSLOCBak += lineBak.substr(start, strSize);
                    }
                }
                if (result->addSLOC(strLSLOCBak, lineNumber, trunc_flag))
                {
                    cnt = 0;
                    CUtil::CountTally(strLSLOC, data_name_list, cnt, 1, dataExclude, "", "", &result->data_name_count);
                    
                    temp_lines++;
                    if (data_continue == true && line[i] == ';')
                    {
                        result->data_lines[LOG]++;
                        phys_data_lines = temp_lines;
                    }
                    else
                    {
                        if (cnt > 0 && line[i] == ';' )
                        {
                            result->data_lines[LOG]++;
                            if (newline)
                            {
                                // only add a physical line once per line, otherwise a line of code might have multiple physical data and exec lines
                                phys_data_lines = temp_lines;
                                newline = false;
                            }
                        }
                        else
                        {
                            result->exec_lines[LOG]++;
                            if (newline)
                            {
                                // only add a physical line once per line, otherwise a line of code might have multiple physical data and exec lines
                                phys_exec_lines = temp_lines;
                                newline = false;
                            }
                        }
                    }
                }
                else if (data_continue == true && line[i] == ';')
                    phys_data_lines = temp_lines;
                else
                    phys_exec_lines = temp_lines;
                data_continue = false;
                temp_lines = 0;
                strLSLOC = strLSLOCBak = "";
                start = i + 1;
                
                // reset some flagging parameters
                forflag = false;
                paren_cnt = 0;
                found_while = false;
                found_forifwhile = false;
                found_for = false;
                
                break;
            case '(':
                tmp = CUtil::TrimString(line.substr(start, i));
                if (CUtil::FindKeyword(tmp, "always") != string::npos)
                {
                    // found always
                    paren_cnt++;
                    always_flag = true;
                }
                if (CUtil::FindKeyword(tmp, "case") != string::npos || CUtil::FindKeyword(tmp, "casex") != string::npos || CUtil::FindKeyword(tmp, "casez") != string::npos)
                {
                    // found case
                    paren_cnt++;
                    case_flag = true;
                }
                if (forflag)
                    paren_cnt++;
                else
                {
                    // handle 'for', 'while', 'if', 'repeat' the same way
                    
                    if (CUtil::FindKeyword(tmp, "for") != string::npos
                        || CUtil::FindKeyword(tmp, "while")!= string::npos
                        || CUtil::FindKeyword(tmp, "if") != string::npos
                        || CUtil::FindKeyword(tmp, "repeat") != string::npos)
                    {
                        forflag = true;
                        paren_cnt++;
                        
                        if (print_cmplx)
                        {
                            tmp = CUtil::TrimString(line.substr(start, i + 1 - start));
                            tmp = strLSLOC + " " + tmp;
                            if (CUtil::FindKeyword(tmp, "begin") != string::npos && loopLevel.size() > 0 && loopLevel.back().compare("looping") == 0)
                            {
                                loopLevel.push_back("begin");
                            }
                            else if (loopLevel.size() > 0 && loopLevel.back().compare("begin") != 0)
                            {
                                // didn't find begin, so pop off since no longer in a looping block
                                loopLevel.pop_back();
                            }
                        }
                        
                        if (CUtil::FindKeyword(tmp, "for") != string::npos)
                        {
                            if (print_cmplx)
                                loopLevel.push_back("looping");
                            found_for = true;
                        }
                        else if (CUtil::FindKeyword(tmp, "while")!= string::npos)
                        {
                            if (print_cmplx)
                                loopLevel.push_back("looping");
                            found_while = true;
                        }
                        else if (CUtil::FindKeyword(tmp, "repeat")!= string::npos)
                        {
                            if (print_cmplx)
                                loopLevel.push_back("looping");
                            repeat_flag = true;
                        }
                        
                        
                        // record nested loop level
                        if (print_cmplx)
                        {
                            if (CUtil::FindKeyword(tmp, "if") == string::npos)
                            {
                                unsigned int loopCnt = 0;
                                for (StringVector::iterator lit = loopLevel.begin(); lit < loopLevel.end(); lit++)
                                {
                                    if ((*lit) != "begin")
                                        loopCnt++;
                                }
                                if ((unsigned int)result->cmplx_nestloop_count.size() < loopCnt)
                                    result->cmplx_nestloop_count.push_back(1);
                                else
                                    result->cmplx_nestloop_count[loopCnt-1]++;
                            }
                        }
                    }
                }
                break;
            case ')':
                if (always_flag || case_flag || repeat_flag || forflag)
                {
                    if (paren_cnt > 0)
                        paren_cnt--;
                    if (paren_cnt == 0)
                    {
                        // handle always @
                        strSize = CUtil::TruncateLine(i + 1 - start, strLSLOC.length(), this->lsloc_truncate, trunc_flag);
                        if (strSize > 0)
                        {
                            strLSLOC += line.substr(start, strSize);
                            strLSLOCBak += lineBak.substr(start, strSize);
                        }
                        if (result->addSLOC(strLSLOCBak, lineNumber, trunc_flag))
                            result->exec_lines[LOG]++;
                        strLSLOCBak = strLSLOC = "";
                        phys_exec_lines = temp_lines;
                        temp_lines = 0;
                        start = i + 1;
                        found_forifwhile = true;
                        forflag = false;
                        found_for = false;
                        always_flag = false;
                        case_flag = false;
                        repeat_flag = false;
                    }
                }
                break;
		}
        
		if (line[i] != ' ' && line[i] != '\t')
		{
			// if ;}}} --> don't count }}} at all
			// also, if {}}} --> don't count }}} at all
			// if ( !(line[i] == '}' && (prev_char == ';' || prev_char == '{'))) // see case '}' above
			prev_char = line[i];
            
			// change to not found if a char appears before
			if (line[i] != ')' && found_forifwhile)
				found_forifwhile = false;
		}
		i++;
	}
    
	// don't save end statements to add to next sloc, they will be counted as physical sloc but not logical
	tmp = CUtil::TrimString(line.substr(start, i - start));
	if ((tmpi = CUtil::FindKeyword(tmp, "endcase")) != string::npos)
	{
		startmax = max((start + tmpi + 8), startmax);
		found_endcase = true;
	}
	if ((tmpi = CUtil::FindKeyword(tmp, "endmodule")) != string::npos)
	{
		startmax = max((start + tmpi + 10), startmax);
	}
	if ((tmpi = CUtil::FindKeyword(tmp, "endtask")) != string::npos)
	{
		startmax = max((start + tmpi + 8), startmax);
	}
	if ((tmpi = CUtil::FindKeyword(tmp, "endfunction")) != string::npos)
	{
		startmax = max((start + tmpi + 12), startmax);
	}
	if ((tmpi = CUtil::FindKeyword(tmp, "end")) != string::npos)
	{
		startmax = max((start + tmpi + 4), startmax);
		found_end = true;	// this is to catch any empty begin and end statements
	}
	if (startmax != 0) start = min(i, startmax);	// if we found and end statement update start to be the max of i and startmax
    
	tmp = CUtil::TrimString(line.substr(start, i - start));
	strSize = CUtil::TruncateLine(tmp.length(), strLSLOC.length(), this->lsloc_truncate, trunc_flag);
	if (strSize > 0 || (strLSLOC.size() > 0 && found_end))
	{
		strLSLOC += tmp.substr(0, strSize);
		tmp = CUtil::TrimString(lineBak.substr(start, i - start));
		strLSLOCBak += tmp.substr(0, strSize);
        
		if (found_end)
		{
			found_end = false;
			if (strLSLOC.compare(strLSLOCBak) != 0)
			{
				if (result->addSLOC(strLSLOCBak, lineNumber, trunc_flag))
					result->exec_lines[LOG]++;
				strLSLOCBak = strLSLOC = "";
				phys_exec_lines = temp_lines;
				temp_lines = 0;
			}
		}
	}
    
	// make sure that we are not beginning to process a new data line
	cnt = 0;
	CUtil::CountTally(strLSLOC, data_name_list, cnt, 1, exclude, "", "", NULL);
    
	if (cnt > 0)
		data_continue = true;
	if (data_continue)
		temp_lines++;
	if (startmax > 0 && !found_endcase && !found_end)
		phys_data_lines = 1;
	else if (temp_lines == 0 && phys_data_lines == 0 && phys_exec_lines == 0)
		phys_exec_lines = 1;
}
/*!
* Extracts and stores logical lines of code.
* Determines and extract logical SLOC to place in the result variable
* using addSLOC function. Each time the addSLOC function is called,
* a new logical SLOC is added. This function assumes that the directive
* is handled before it is called.
*
* \param result counter results
* \param line processed physical line of code
* \param lineBak original physical line of code
* \param strLSLOC processed logical string
* \param strLSLOCBak original logical string
* \param fixed_continue fixed format line continues on next line
* \param data_continue continuation of a data declaration line
* \param temp_lines tracks physical line count
* \param phys_exec_lines number of physical executable lines
* \param phys_data_lines number of physical data lines
* \param loopEnd nested loop end string(s)
*/
void CFortranCounter::LSLOC(results* result, string line, size_t lineNumber, string lineBak, string &strLSLOC, string &strLSLOCBak,
					bool &fixed_continue, bool &data_continue, unsigned int &temp_lines, unsigned int &phys_exec_lines,
					unsigned int &phys_data_lines, StringVector &loopEnd)
{
	size_t start, end;
	size_t i, j, k, m, strSize;
	bool found_exclusion = false, trunc_flag = false, found;
	string exclude = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789_$";
	string str, spc;
	unsigned int cnt = 0;
	unsigned int paren_cnt;

	string tmp    = CUtil::TrimString(line);
	string tmpBak = CUtil::TrimString(lineBak);
	start = 0;

	// if continuation, prepend previous line for correct processing
	if (strLSLOC.length() > 0)
	{
		found = false;
		if (tmpBak[0] == '&' && tmpBak.length() > 1)
			found = true;
		else
		{
			if (line.length() > 6)
			{
				str = line.substr(0, 5);
				if ((CUtil::CheckBlank(str) || CUtil::IsInteger(str)) &&
					line[5] != ' ' && line[5] != '0')
					found = true;
			}
		}
		if (found)
		{
			tmp = tmp.substr(1, tmp.length() - 1);
			tmpBak = tmpBak.substr(1, tmpBak.length() - 1);
		}
		tmp = strLSLOC + tmp;
		tmpBak = strLSLOCBak + tmpBak;
		strLSLOC = strLSLOCBak = "";
	}

	// there may be more than 1 logical SLOC in this line
	while (start < tmp.length())
	{
		// check for semicolon to denote end of SLOC
		end = tmp.find(";", start);
		if (end == string::npos)
			end = tmp.length() - 1;
		else
		{
			// skip empty ";"
			str = CUtil::TrimString(tmp.substr(start, end - start + 1));
			if (str == ";")
			{
				start = end + 1;
				continue;
			}
		}

		// record nested loops
		if (print_cmplx)
		{
			bool new_loop = false;
			i = CUtil::FindKeyword(tmp, "end do", start, end, false);
			if (i != string::npos)
				i = string::npos;
			else
				i = CUtil::FindKeyword(tmp, "do", start, end, false);
			if (i != string::npos)
			{
				// check for label after do
				found = false;
				if (i + 2 < end && tmp[i+2] == ' ')
				{
					for (j = i + 3; j <= end; j++)
					{
						if (tmp[j] != ' ')
						{
							for (k = j; k <= end; k++)
							{
								if (tmp[k] == ' ' || tmp[k] == ',')
									break;
							}
							k--;
							str = CUtil::TrimString(tmp.substr(j, k - j + 1));
							if (CUtil::IsInteger(str))
							{
								loopEnd.push_back(str);
								found = true;
							}
							break;
						}
					}
				}
				if (!found)
					loopEnd.push_back("end do");
				new_loop = true;
			}
			else
			{
				i = CUtil::FindKeyword(tmp, "end forall", start, end, false);
				if (i != string::npos)
					i = string::npos;
				else
					i = CUtil::FindKeyword(tmp, "forall", start, end, false);
				if (i != string::npos)
				{
					loopEnd.push_back("end forall");
					new_loop = true;
				}
				else if (loopEnd.size() > 0)
				{
					str = loopEnd.back();
					if (CUtil::FindKeyword(tmp, str, start, end, false) != string::npos)
					{
						loopEnd.pop_back();
						if (CUtil::IsInteger(str))
						{
							// remove additional label terminators
							if (loopEnd.size() > 0)
							{
								for (m = loopEnd.size() - 1; m > 0; m--)
								{
									if (loopEnd[m] == str)
										loopEnd.pop_back();
									else
										break;
								}
								if (m == 0)
								{
									if (loopEnd[0] == str)
										loopEnd.pop_back();
								}
							}
						}
					}
					else if (loopEnd.back() == "end do")
					{
						if (CUtil::FindKeyword(tmp, "enddo", start, end, false) != string::npos)
							loopEnd.pop_back();
					}
					else if (loopEnd.back() == "end forall")
					{
						if (CUtil::FindKeyword(tmp, "endforall", start, end, false) != string::npos)
							loopEnd.pop_back();
					}
				}
			}
			if (new_loop)
			{
				if (result->cmplx_nestloop_count.size() < loopEnd.size())
					result->cmplx_nestloop_count.push_back(1);
				else
					result->cmplx_nestloop_count[loopEnd.size()-1]++;
			}
		}

		// check for line containing excluded keywords (don't count as LSLOC)
		found_exclusion = false;
		for (StringVector::iterator it = exclude_keywords.begin(); it != exclude_keywords.end(); it++)
		{
			i = CUtil::FindKeyword(tmp, (*it), start, end, false);
			if (i != string::npos)
			{
				found_exclusion = true;

				// exceptions
				if ((*it) == "else")
				{
					// make sure not else if
					if (CUtil::FindKeyword(tmp, "else if", i, i + 6, false) == string::npos)
						break;
				}
				if ((*it) == "elsewhere")
				{
					// make sure elsewhere does not have condition
					str = CUtil::TrimString(tmp.substr(i + 9, end - (i + 9) + 1));
					if (str[0] != '(')
						break;
				}
				else
					break;
			}
		}
		if (found_exclusion)
		{
			strLSLOC = strLSLOCBak = "";
			phys_exec_lines++;
			temp_lines = 0;
			return;
		}

		// check for inline if, where, forall
		found = false;
		i = CUtil::FindKeyword(tmp, "if", start, end, false);
		if (i != string::npos)
		{
			if (CUtil::FindKeyword(tmp, "then", start, end, false) == string::npos)
				found = true;
		}
		if (!found)
		{
			i = CUtil::FindKeyword(tmp, "where", start, end, false);
			if (i != string::npos)
				found = true;
		}
		if (!found)
		{
			i = CUtil::FindKeyword(tmp, "forall", start, end, false);
			if (i != string::npos)
				found = true;
		}
		if (found)
		{
			// check if in-line action exists after if statement (past ())
			found = false;
			paren_cnt = 0;
			for (j = i + 2; j <= end; j++)
			{
				if (tmp[j] == '(')
				{
					found = true;
					paren_cnt++;
				}
				else if (tmp[j] == ')' && paren_cnt > 0)
					paren_cnt--;
				if (found && paren_cnt == 0)
				{
					if (j < end)
					{
						str = CUtil::TrimString(tmp.substr(j + 1, end - j + 1));
						if (!CUtil::CheckBlank(str) && str != ";" && str != "&" && !fixed_continue)
						{
							// save LSLOC for if statement, then process in-line action
							strSize = CUtil::TruncateLine(j - start + 1, strLSLOC.length(), this->lsloc_truncate, trunc_flag);
							if (strSize > 0)
							{
								strLSLOC += CUtil::TrimString(tmp.substr(start, strSize));
								strLSLOCBak += CUtil::TrimString(tmpBak.substr(start, strSize));
							}
							if (result->addSLOC(strLSLOCBak, lineNumber, trunc_flag))
								result->exec_lines[LOG]++;
							strLSLOC = strLSLOCBak = "";
							start = j + 1;
						}
					}
					break;
				}
			}
		}

		// check for fixed continuation or free continuation (&)
		if (tmp[end] == '&' || (fixed_continue && end >= tmp.length() - 1))
		{
			// strip off trailing (&)
			if (tmp[end] == '&')
				strSize = CUtil::TruncateLine(end - start, strLSLOC.length(), this->lsloc_truncate, trunc_flag);
			else
				strSize = CUtil::TruncateLine(end - start + 1, strLSLOC.length(), this->lsloc_truncate, trunc_flag);
			if (strSize > 0)
			{
				spc = "";
				str = tmp.substr(start, strSize);
				for (m = str.length() - 1; m > 0; m--)
				{
					if (str[m] == ' ')
						spc += " ";
					else
						break;
				}
				if (m == 0)
				{
					if (str[0] == ' ')
						spc += " ";
				}
				strLSLOC += CUtil::TrimString(tmp.substr(start, strSize)) + spc;
				strLSLOCBak += CUtil::TrimString(tmpBak.substr(start, strSize)) + spc;
			}
			start = end + 1;

			// make sure that we are not beginning to process a new data line
			cnt = 0;
			CUtil::CountTally(strLSLOC, data_name_list, cnt, 1, exclude, "", "", NULL, false);

			if (cnt > 0)
				data_continue = true;
			if (data_continue == true)
				temp_lines++;
			if (temp_lines == 0 && phys_data_lines == 0 && phys_exec_lines == 0)
				phys_exec_lines = 1;
		}
		else
		{
			// save LSLOC
			if (tmp[end] == ';')
				strSize = CUtil::TruncateLine(end - start, strLSLOC.length(), this->lsloc_truncate, trunc_flag);
			else
				strSize = CUtil::TruncateLine(end - start + 1, strLSLOC.length(), this->lsloc_truncate, trunc_flag);
			if (strSize > 0)
			{
				strLSLOC += CUtil::TrimString(tmp.substr(start, strSize));
				strLSLOCBak += CUtil::TrimString(tmpBak.substr(start, strSize));
			}
			start = end + 1;
			if (strLSLOCBak.length() > 0)
			{
				if (result->addSLOC(strLSLOCBak, lineNumber, trunc_flag))
				{
					// add a logical SLOC
					cnt = 0;
					CUtil::CountTally(strLSLOC, data_name_list, cnt, 1, exclude, "", "", &result->data_name_count, false);

					temp_lines++;
					if (data_continue == true || cnt > 0)
					{
						result->data_lines[LOG]++;
						phys_data_lines = temp_lines;
					}
					else
					{
						result->exec_lines[LOG]++;
						phys_exec_lines = temp_lines;
					}
				}
				else if (data_continue == true)
					phys_data_lines = temp_lines;
				else
					phys_exec_lines = temp_lines;
			}
			data_continue = false;
			temp_lines = 0;
			strLSLOC = strLSLOCBak = "";
		}
	}
}
/*!
* Extracts and stores logical lines of code.
* Determines and extract logical SLOC to place in the result variable
* using addSLOC function. Each time the addSLOC function is called,
* a new logical SLOC is added. This function assumes that the directive
* is handled before it is called.
*
* \param result counter results
* \param line processed physical line of code
* \param lineBak original physical line of code
* \param strLSLOC processed logical string
* \param strLSLOCBak original logical string
* \param paren_cnt count of parenthesis
* \param forflag found for flag
* \param found_forifwhile found for, if, or while flag
* \param found_while found while flag
* \param prev_char previous character
* \param data_continue continuation of a data declaration line
* \param temp_lines tracks physical line count
* \param phys_exec_lines number of physical executable lines
* \param phys_data_lines number of physical data lines
* \param openBrackets number of open brackets (no matching close bracket)
* \param loopLevel nested loop level
*/
void CPerlCounter::LSLOC(results* result, string line, size_t lineNumber, string lineBak, string &strLSLOC, string &strLSLOCBak, unsigned int &paren_cnt,
	bool &forflag, bool &found_forifwhile, bool &found_while, char &prev_char, bool &data_continue,
	unsigned int &temp_lines, unsigned int &phys_exec_lines, unsigned int &phys_data_lines,
	unsigned int &openBrackets, StringVector &loopLevel)
{
	size_t start = 0; // starting index of the working string
	size_t i = 0, strSize, pos;
	bool do_boolean, trunc_flag = false;
	string exclude = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789_";
	unsigned int cnt = 0;
	unsigned int loopCnt = 0;
	StringVector::iterator lit;
	string tmp = CUtil::TrimString(strLSLOC);
	string tmp2;

	// check for the keyword do
	do_boolean = (CUtil::FindKeyword(tmp, "do") == tmp.length() - 2);

	// check the entire line for SLOC present in it
	while (i < line.length())
	{
		if (line[i] == ';' || line[i] == '{')
		{
			// LSLOC terminators
			// ';' any valid perl command ends with a ';' terminator
			// do statements start with a '{' and ends with '}'

			if (line[i] == ';' && paren_cnt > 0)
			{
				// for a 'for' statement counter is incremented.
				i++;
				continue;
			}

			// record open bracket for nested loop processing
			if (print_cmplx)
			{
				if (line[i] == '{')
				{
					openBrackets++;
					if ((unsigned int)loopLevel.size() < openBrackets)
						loopLevel.push_back("");
				}
				else
				{
					if ((unsigned int)loopLevel.size() > openBrackets && openBrackets > 0)
						loopLevel.pop_back();
				}
			}

			if (found_while && found_forifwhile)
			{
				found_while = false;
				found_forifwhile = false;
				start = i + 1;
				i++;
				continue;
			}

			if (line[i] == '{')
			{
				// case for(...); and if (...) {
				// these specials are handled
				if (found_forifwhile)
				{
					found_forifwhile = false;
					start = i + 1;
					i++;
					continue;
				}

				// check if 'do' precedes '{'
				if (!do_boolean)
				{
					// find for 'do' in string before tmp string
					tmp = CUtil::TrimString(line.substr(start, i - start));

					// check for 'do' statement
					do_boolean = (tmp == "do");
				}
				if (do_boolean)
				{
					if (print_cmplx)
					{
						if (loopLevel.size() > 0) loopLevel.pop_back();
						loopLevel.push_back("do");
					}

					do_boolean = false;
					start = i + 1;
					i++;
					continue; // do not store '{' following 'do'
				}
			}

			if (line[i] == ';' && prev_char == '}')
			{
				i++;
				continue;
			}

			// the 'for(...)' or 'while(..)' or anything with the '{' on the next line gets counted as an extra SLOC
			// so to avoid that increment the counter and continue
			if (line[i] == '{' && prev_char == ')')
			{
				i++;
				continue;
			}

			// check for expression modifiers using 'foreach', 'while', 'if', 'unless', 'until' (for example, statement unless condition;)
			pos = string::npos;
			if (line[i] == ';')
			{
				// check for empty statement (=1 LSLOC)
				if (CUtil::TrimString(line.substr(start, i + 1 - start)) == ";" && strLSLOC.length() < 1)
				{
					strLSLOC = ";";
					strLSLOCBak = ";";
				}
				else
				{
					tmp = CUtil::TrimString(strLSLOC + line.substr(start, i + 1 - start));
					pos = CUtil::FindKeyword(tmp, "foreach");
					if (pos == string::npos)
					{
						pos = CUtil::FindKeyword(tmp, "while");
						if (pos == string::npos)

							pos = CUtil::FindKeyword(tmp, "if");
						if (pos == string::npos)
						{
							pos = CUtil::FindKeyword(tmp, "unless");
							if (pos == string::npos)
								pos = CUtil::FindKeyword(tmp, "until");
						}
					}
				}
			}
			if (pos != string::npos)
			{
				// capture statement before modifier
				tmp2 = CUtil::TrimString(strLSLOCBak + lineBak.substr(start, i - start));
				strSize = CUtil::TruncateLine(pos, 0, this->lsloc_truncate, trunc_flag);
				if (strSize > 0)
				{
					strLSLOC = tmp.substr(0, strSize);
					strLSLOCBak = tmp2.substr(0, strSize);
				}
				if (result->addSLOC(strLSLOCBak, lineNumber, trunc_flag))
					result->exec_lines[LOG]++;
				strLSLOC = "";
				strLSLOCBak = "";

				strSize = CUtil::TruncateLine(tmp.length() - pos, 0, this->lsloc_truncate, trunc_flag);
				if (strSize > 0)
				{
					strLSLOC = tmp.substr(pos, strSize);
					strLSLOCBak = tmp2.substr(pos, strSize);
				}
				if (result->addSLOC(strLSLOCBak, lineNumber, trunc_flag))
					result->exec_lines[LOG]++;
				found_forifwhile = false;
			}
			else
			{
				strSize = CUtil::TruncateLine(i - start, strLSLOC.length(), this->lsloc_truncate, trunc_flag);
				if (strSize > 0)
				{
					strLSLOC += line.substr(start, strSize);
					strLSLOCBak += lineBak.substr(start, strSize);
				}
				tmp = strLSLOC;
				if (result->addSLOC(strLSLOCBak, lineNumber, trunc_flag))
				{
					cnt = 0;
					CUtil::CountTally(strLSLOC, data_name_list, cnt, 1, exclude, "", "", &result->data_name_count);

					temp_lines++;
					if (data_continue == true)
					{
						result->data_lines[LOG]++;
						phys_data_lines = temp_lines;
					}
					else
					{
						if (cnt > 0)
						{
							result->data_lines[LOG]++;
							phys_data_lines = temp_lines;
						}
						else
						{
							result->exec_lines[LOG]++;
							phys_exec_lines = temp_lines;
						}
					}
				}
				else if (data_continue == true)
					phys_data_lines = temp_lines;
				else
					phys_exec_lines = temp_lines;
			}
			data_continue = false;
			temp_lines = 0;
			strLSLOC = "";
			strLSLOCBak = "";
			start = i + 1;
		}
		else if (line[i] == '}')
		{
			// also, {} is also skipped, empty block is not counted
			if (prev_char == ';' || prev_char == '{')
				start = i + 1; 

			// record close bracket for nested loop processing
			if (print_cmplx)
			{
				if (openBrackets > 0)
					openBrackets--;
				if (loopLevel.size() > 0)
					loopLevel.pop_back();
			}
		}
		else if (line[i] == '(')
		{ 
			if (!forflag)
			{
				// handle 'for', 'foreach', 'while', 'if', 'elsif,  and 'unless'
				tmp = "xxx " + CUtil::TrimString(line.substr(start, i));
				if ((CUtil::FindKeyword(tmp, "for") != string::npos) || (CUtil::FindKeyword(tmp, "foreach") != string::npos) ||
					(CUtil::FindKeyword(tmp, "while")!= string::npos) || (CUtil::FindKeyword(tmp, "if") != string::npos) ||
					(CUtil::FindKeyword(tmp, "elsif") != string::npos) || (CUtil::FindKeyword(tmp, "unless") != string::npos) ||
					(CUtil::FindKeyword(tmp, "until") != string::npos))
				{
					forflag = true;
					paren_cnt++;

					if (print_cmplx && (loopLevel.size() > openBrackets) && (openBrackets > 0))
						loopLevel.pop_back();

					if (CUtil::FindKeyword(tmp, "while")!= string::npos)
					{
						if (print_cmplx)
							loopLevel.push_back("while");
						found_while = true;
					}
					else if (CUtil::FindKeyword(tmp, "until")!= string::npos)
					{
						if (print_cmplx)
							loopLevel.push_back("until");
						found_while = true;
					}
					else if (print_cmplx)
					{
						if (CUtil::FindKeyword(tmp, "for") != string::npos)
							loopLevel.push_back("for");
						else if (CUtil::FindKeyword(tmp, "foreach") != string::npos)
							loopLevel.push_back("foreach");

						// record nested loop level
						if (CUtil::FindKeyword(tmp, "if") == string::npos && CUtil::FindKeyword(tmp, "elsif") == string::npos &&
							CUtil::FindKeyword(tmp, "unless") == string::npos)
						{
							loopCnt = 0;
							for (lit = loopLevel.begin(); lit < loopLevel.end(); lit++)
							{
								if ((*lit) != "")
									loopCnt++;
							}
							if ((unsigned int)result->cmplx_nestloop_count.size() < loopCnt)
								result->cmplx_nestloop_count.push_back(1);
							else
								result->cmplx_nestloop_count[loopCnt-1]++;
						}
					}
				}
			}
			else
				paren_cnt++;
		}
		else if (line[i] == ')')
		{
			/* 
			cases 
			'while(...);', 
			'while(...) {' and 
			'} while(...);' 
			is handled in this case
			*/
			if (forflag)
			{
				if (paren_cnt > 0)
					paren_cnt--;
				if (paren_cnt == 0)
				{
					// handling 'for', 'foreach', 'while', 'if', 'elsif', 'unless', 'until'
					// check for expression modifiers using 'foreach', 'while', 'if', 'unless', 'until' (for example, statement unless (condition);)
					tmp = CUtil::TrimString(strLSLOC + line.substr(start, i + 1 - start));
					pos = CUtil::FindKeyword(tmp, "foreach");
					if (pos == string::npos)
					{
						pos = CUtil::FindKeyword(tmp, "while");
						if (pos == string::npos)
						{
							pos = CUtil::FindKeyword(tmp, "if");
							if (pos == string::npos)
							{
								pos = CUtil::FindKeyword(tmp, "unless");
								if (pos == string::npos)
									pos = CUtil::FindKeyword(tmp, "until");
							}
						}
					}
					if (pos != string::npos)
					{
						// capture statement before modifier
						tmp2 = CUtil::TrimString(strLSLOCBak + lineBak.substr(start, i + 1 - start));
						strSize = CUtil::TruncateLine(pos, 0, this->lsloc_truncate, trunc_flag);
						if (strSize > 0)
						{
							strLSLOC = tmp.substr(0, strSize);
							strLSLOCBak = tmp2.substr(0, strSize);
						}
						if (result->addSLOC(strLSLOCBak, lineNumber, trunc_flag))
							result->exec_lines[LOG]++;
						strLSLOC = "";
						strLSLOCBak = "";

						strSize = CUtil::TruncateLine(tmp.length() - pos, 0, this->lsloc_truncate, trunc_flag);
						if (strSize > 0)
						{
							strLSLOC = tmp.substr(pos, strSize);
							strLSLOCBak = tmp2.substr(pos, strSize);
						}
						if (result->addSLOC(strLSLOCBak, lineNumber, trunc_flag))
							result->exec_lines[LOG]++;
						found_forifwhile = false;

						// skip trailing ';'
						tmp = CUtil::TrimString(line.substr(i + 1));
						if (tmp.length() > 0 && tmp[0] == ';')
							i++;
					}
					else
					{
						strSize = CUtil::TruncateLine(i + 1 - start, strLSLOC.length(), this->lsloc_truncate, trunc_flag);
						if (strSize > 0)
						{
							strLSLOC += line.substr(start, strSize);
							strLSLOCBak += lineBak.substr(start, strSize);
						}
						tmp = strLSLOC;
						if (result->addSLOC(strLSLOCBak, lineNumber, trunc_flag))
							result->exec_lines[LOG]++;
						found_forifwhile = true;
					}
					strLSLOC = "";
					strLSLOCBak = "";
					phys_exec_lines = temp_lines;
					temp_lines = 0;
					start = i + 1; 
					forflag = false;
				}
			}
		}

		if (line[i] != ' ' && line[i] != '\t')
		{
			// if ;}}} --> don't count }}} at all
			// also, if {}}} --> don't count }}} at all
			if (!(line[i] == '}' && (prev_char == ';' || prev_char == '{'))) // see case '}' above
				prev_char = line[i];

			// change to not found if a char appears before
			if (line[i] != ')' && found_forifwhile)
				found_forifwhile = false;

			if (CUtil::FindKeyword(line, "or", i, i + 2, true) == i)
			{
				strSize = CUtil::TruncateLine(i + 1 - start, strLSLOC.length(), this->lsloc_truncate, trunc_flag);
				if (strSize > 0)
				{
					strLSLOC += line.substr(start, strSize);
					strLSLOCBak += lineBak.substr(start, strSize);
				}
				tmp = strLSLOC;
				if (result->addSLOC(strLSLOCBak, lineNumber, trunc_flag))
					result->exec_lines[LOG]++;
				phys_exec_lines = temp_lines;
				temp_lines = 0;
				strLSLOC = "";
				strLSLOCBak = "";
				start = i;
			}
		}
		i++;
	}

	tmp2 = CUtil::TrimString(line.substr(start, i - start));
	strSize = CUtil::TruncateLine(tmp2.length(), strLSLOC.length(), this->lsloc_truncate, trunc_flag);
	if (strSize > 0)
	{
		strLSLOC += tmp2.substr(0, strSize);
		tmp2 = CUtil::TrimString(lineBak.substr(start, i - start));
		strLSLOCBak += tmp2.substr(0, strSize);
	}
	if (tmp == "")
		found_forifwhile = found_while = false;

	// make sure that we are not beginning to process a new data line
	cnt = 0;
	CUtil::CountTally(strLSLOC, data_name_list, cnt, 1, exclude, "", "", NULL);

	if (cnt > 0)
		data_continue = true;
	if (data_continue)
		temp_lines++;
	if (temp_lines == 0 && phys_data_lines == 0 && phys_exec_lines == 0)
		phys_exec_lines = 1;
}