/*! * 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; }
std::string getParentNameFromGroupPath(std::string groupPath) { std::string result = ""; // Default = root node StringVector groupPathComponents = stringSplit(groupPath,"/", false); if (groupPathComponents.size() > 0) { result = groupPathComponents.back(); } return result; }
bool RegExp::captureAll(const char* str, StringVector& outResults, uint start) { if (_peer == NULL) return false; SQRex* rex = (SQRex*)_peer; bool found = sqstd_rex_search(rex, str+start, NULL, NULL); if (!found) return false; SQInteger n = sqstd_rex_getsubexpcount(rex); for (SQInteger i=0; i < n; ++i) { SQRexMatch match; sqstd_rex_getsubexp(rex, i, &match); outResults.push_back(String()); outResults.back().assign(match.begin, match.begin + match.len); } return true; }
std::string parseVocationString(StringVector vocStringVec) { std::string str = ""; if(!vocStringVec.empty()) { for(StringVector::iterator it = vocStringVec.begin(); it != vocStringVec.end(); ++it) { if((*it) != vocStringVec.front()) { if((*it) != vocStringVec.back()) str += ", "; else str += " and "; } str += (*it); str += "s"; } } return str; }
static int luaFuncExeDirs(lua_State* l) { Block* b = mbGetActiveContext()->ActiveBlock(); if (!b) { MB_LOGERROR("must be within a block"); mbExitError(); } luaL_checktype(l, 1, LUA_TTABLE); int tableLen = luaL_len(l, 1); StringVector strings; for (int i = 1; i <= tableLen; ++i) { lua_rawgeti(l, 1, i); strings.push_back(std::string()); mbLuaToStringExpandMacros(&strings.back(), b, l, -1); } b->AddExeDirs(strings); return 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; }
/*! * 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; }
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; }
/*! * 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 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 found_for found for loop * \param loopLevel nested loop level */ void CPhpCounter::LSLOC(results* result, string line, 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, bool &found_for, StringVector &loopLevel) { size_t start = 0; size_t i = 0, strSize; bool found_do, found_try, found_else, found_declare, trunc_flag = false; string exclude = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789_$:"; unsigned int cnt = 0; string tmp = CUtil::TrimString(strLSLOC); // do, try found_do = (CUtil::FindKeyword(tmp, "do") != string::npos); found_try = (CUtil::FindKeyword(tmp, "try") != string::npos); // else, declare are treated differently, else and declare are included in SLOC, do and try are not found_else = (CUtil::FindKeyword(tmp, "else") != string::npos); found_declare = (CUtil::FindKeyword(tmp, "declare") != string::npos); while (i < line.length()) // there may be more than 1 logical SLOC in this line { switch (line[i]) { case ';': case '{': case ':': // LSLOC terminators // ';' for normal executable or declaration statement // '{' or ':' 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 // check for excluded loop keywords for alternate control syntax if (print_cmplx) { cnt = 0; CUtil::CountTally(line, exclude_loop, cnt, 1, exclude, "", ""); if (cnt > 0) { if ((unsigned int)loopLevel.size() > 0) loopLevel.pop_back(); } else if (line[i] == '{') loopLevel.push_back(""); else if (line[i] == ';') { if ((unsigned int)loopLevel.size() > 0 && loopLevel.back() != "") { tmp = loopLevel.back(); if (tmp[tmp.length()-1] != ':') loopLevel.pop_back(); } } else if (line[i] == ':') { if ((unsigned int)loopLevel.size() > 0 && loopLevel.back() != "") { tmp = CUtil::TrimString(line.substr(0, i)); if (CUtil::FindKeyword(tmp, loopLevel.back()) != string::npos) { tmp = loopLevel.back() + ":"; loopLevel.pop_back(); loopLevel.push_back(tmp); } } } } // check for excluded keywords for alternate control syntax (don't count as LSLOC) cnt = 0; CUtil::CountTally(line, exclude_keywords, cnt, 1, exclude, "", ""); if (cnt > 0) { start = i + 1; break; } // case 'if(...):', 'while(...):, for(...):, foreach(...):, switch(...):' // this case is handled in case ')' // skip other ':' if (line[i] == ':') { if (found_forifwhile) { found_forifwhile = false; start = i + 1; } break; } // case 'while(...);', 'while(...) {', '} 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] == '{' || line[i] == ':') { if (prev_char == '=') inArrayDec = true; // continue until seeing ';' if (inArrayDec) break; // case for(...);, if (...) {, and if (...):, elseif (...) {, and elseif (...): // these specials are handled if (found_forifwhile) { found_forifwhile = false; start = i + 1; break; } // check if 'do' precedes '{' or ':' if (!found_do && !found_try && !found_else && !found_declare) { // find '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 found_else = (tmp == "else"); // found 'else' statement found_declare = (CUtil::FindKeyword(tmp, "declare") != string::npos); // found 'declare' 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 '{' or ':' 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, 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 { if (found_declare) { result->directive_lines[PHY] += temp_lines; result->directive_lines[LOG]++; } else { result->exec_lines[LOG]++; phys_exec_lines = temp_lines; } } } } else if (data_continue == true && line[i] == ';') phys_data_lines = temp_lines; else if (found_declare) result->directive_lines[PHY] += 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; found_declare = false; 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 || CUtil::FindKeyword(tmp, "elseif") != string::npos || CUtil::FindKeyword(tmp, "switch") != string::npos) { forflag = true; paren_cnt++; if (CUtil::FindKeyword(tmp, "for") != string::npos) { if (print_cmplx) loopLevel.push_back("for"); found_for = true; } else if (CUtil::FindKeyword(tmp, "while")!= string::npos) { if (print_cmplx) loopLevel.push_back("while"); found_while = true; } else if (CUtil::FindKeyword(tmp, "foreach") != string::npos) loopLevel.push_back("foreach"); else if (print_cmplx && CUtil::FindKeyword(tmp, "foreach") != string::npos) loopLevel.push_back("foreach"); // record nested loop level if (print_cmplx) { if (CUtil::FindKeyword(tmp, "if") == string::npos && CUtil::FindKeyword(tmp, "elseif") == string::npos && CUtil::FindKeyword(tmp, "switch") == 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]++; } } } } break; case ')': if (forflag) { if (paren_cnt > 0) paren_cnt--; if (paren_cnt == 0) { // handle 'for', 'foreach', 'while', 'if', 'elseif', 'switch' 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, 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; } } 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 ((unsigned int)loopLevel.size() > 0) loopLevel.pop_back(); if ((unsigned int)loopLevel.size() > 0 && loopLevel.back() != "") { tmp = loopLevel.back(); if (tmp[tmp.length()-1] != ':') 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; }
/*! * 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 = ""; } } }