From 7955e995ec400fb063529064b6232ca0eedfe5e0 Mon Sep 17 00:00:00 2001 From: Bill Hoffman Date: Tue, 1 May 2012 17:00:43 -0400 Subject: [PATCH] Add support for Cache coverage. This adds support for Cache coverage parsing. A test is added that does a basic run of the coverage on a small bit of data. --- Source/CMakeLists.txt | 1 + Source/CTest/cmCTestCoverageHandler.cxx | 25 +- Source/CTest/cmCTestCoverageHandler.h | 4 +- Source/CTest/cmParseCacheCoverage.cxx | 187 +++++++++++ Source/CTest/cmParseCacheCoverage.h | 40 +++ Source/CTest/cmParseGTMCoverage.cxx | 28 +- Source/CTest/cmParseMumpsCoverage.cxx | 28 ++ Source/CTest/cmParseMumpsCoverage.h | 3 + Tests/CMakeLists.txt | 16 + .../Accounts_ReceivableTest.cmcov | 304 ++++++++++++++++++ .../DartConfiguration.cache.tcl.in | 8 + Tests/MumpsCoverage/cache_coverage.cmcov.in | 2 + 12 files changed, 616 insertions(+), 30 deletions(-) create mode 100644 Source/CTest/cmParseCacheCoverage.cxx create mode 100644 Source/CTest/cmParseCacheCoverage.h create mode 100644 Tests/MumpsCoverage/Accounts_ReceivableTest.cmcov create mode 100644 Tests/MumpsCoverage/DartConfiguration.cache.tcl.in create mode 100644 Tests/MumpsCoverage/cache_coverage.cmcov.in diff --git a/Source/CMakeLists.txt b/Source/CMakeLists.txt index 081cf65f0..dcb56d4f8 100644 --- a/Source/CMakeLists.txt +++ b/Source/CMakeLists.txt @@ -424,6 +424,7 @@ SET(CTEST_SRCS cmCTest.cxx CTest/cmCTestCoverageCommand.cxx CTest/cmCTestCoverageHandler.cxx CTest/cmParseMumpsCoverage.cxx + CTest/cmParseCacheCoverage.cxx CTest/cmParseGTMCoverage.cxx CTest/cmParsePHPCoverage.cxx CTest/cmCTestEmptyBinaryDirectoryCommand.cxx diff --git a/Source/CTest/cmCTestCoverageHandler.cxx b/Source/CTest/cmCTestCoverageHandler.cxx index e7fa2f15a..48bea6433 100644 --- a/Source/CTest/cmCTestCoverageHandler.cxx +++ b/Source/CTest/cmCTestCoverageHandler.cxx @@ -12,6 +12,7 @@ #include "cmCTestCoverageHandler.h" #include "cmParsePHPCoverage.h" #include "cmParseGTMCoverage.h" +#include "cmParseCacheCoverage.h" #include "cmCTest.h" #include "cmake.h" #include "cmMakefile.h" @@ -391,7 +392,7 @@ int cmCTestCoverageHandler::ProcessHandler() { return error; } - file_count += this->HandleGTMCoverage(&cont); + file_count += this->HandleMumpsCoverage(&cont); error = cont.Error; if ( file_count < 0 ) { @@ -761,20 +762,38 @@ int cmCTestCoverageHandler::HandlePHPCoverage( return static_cast(cont->TotalCoverage.size()); } //---------------------------------------------------------------------- -int cmCTestCoverageHandler::HandleGTMCoverage( +int cmCTestCoverageHandler::HandleMumpsCoverage( cmCTestCoverageHandlerContainer* cont) { + // try gtm coverage cmParseGTMCoverage cov(*cont, this->CTest); std::string coverageFile = this->CTest->GetBinaryDir() + "/gtm_coverage.mcov"; if(cmSystemTools::FileExists(coverageFile.c_str())) { cov.ReadCoverageFile(coverageFile.c_str()); + return static_cast(cont->TotalCoverage.size()); } else { cmCTestLog(this->CTest, HANDLER_VERBOSE_OUTPUT, - " Cannot find GTM coverage file: " << coverageFile + " Cannot find foobar GTM coverage file: " << coverageFile + << std::endl); + } + cmParseCacheCoverage ccov(*cont, this->CTest); + coverageFile = this->CTest->GetBinaryDir() + + "/cache_coverage.cmcov"; + if(cmSystemTools::FileExists(coverageFile.c_str())) + { + cmCTestLog(this->CTest, HANDLER_VERBOSE_OUTPUT, + "Parsing Cache Coverage: " << coverageFile + << std::endl); + ccov.ReadCoverageFile(coverageFile.c_str()); + } + else + { + cmCTestLog(this->CTest, HANDLER_VERBOSE_OUTPUT, + " Cannot find Cache coverage file: " << coverageFile << std::endl); } return static_cast(cont->TotalCoverage.size()); diff --git a/Source/CTest/cmCTestCoverageHandler.h b/Source/CTest/cmCTestCoverageHandler.h index f4c275fc0..92b0b2285 100644 --- a/Source/CTest/cmCTestCoverageHandler.h +++ b/Source/CTest/cmCTestCoverageHandler.h @@ -70,8 +70,8 @@ private: //! Handle coverage using xdebug php coverage int HandlePHPCoverage(cmCTestCoverageHandlerContainer* cont); - //! Handle coverage using GTM - int HandleGTMCoverage(cmCTestCoverageHandlerContainer* cont); + //! Handle coverage for mumps + int HandleMumpsCoverage(cmCTestCoverageHandlerContainer* cont); //! Handle coverage using Bullseye int HandleBullseyeCoverage(cmCTestCoverageHandlerContainer* cont); diff --git a/Source/CTest/cmParseCacheCoverage.cxx b/Source/CTest/cmParseCacheCoverage.cxx new file mode 100644 index 000000000..d2ff4040a --- /dev/null +++ b/Source/CTest/cmParseCacheCoverage.cxx @@ -0,0 +1,187 @@ +#include "cmStandardIncludes.h" +#include +#include +#include "cmSystemTools.h" +#include "cmParseCacheCoverage.h" +#include +#include + + +cmParseCacheCoverage::cmParseCacheCoverage(cmCTestCoverageHandlerContainer& cont, + cmCTest* ctest) + :cmParseMumpsCoverage(cont, ctest) +{ +} + + +bool cmParseCacheCoverage::LoadCoverageData(const char* d) +{ + // load all the .mcov files in the specified directory + cmsys::Directory dir; + if(!dir.Load(d)) + { + return false; + } + size_t numf; + unsigned int i; + numf = dir.GetNumberOfFiles(); + for (i = 0; i < numf; i++) + { + std::string file = dir.GetFile(i); + if(file != "." && file != ".." + && !cmSystemTools::FileIsDirectory(file.c_str())) + { + std::string path = d; + path += "/"; + path += file; + if(cmSystemTools::GetFilenameLastExtension(path) == ".cmcov") + { + if(!this->ReadCMCovFile(path.c_str())) + { + return false; + } + } + } + } + return true; +} + +bool cmParseCacheCoverage::SplitString(std::vector& args, + std::string const& line) +{ + std::string::size_type pos1 = 0; + std::string::size_type pos2 = line.find(',', 0); + if(pos2 == std::string::npos) + { + return false; + } + std::string arg; + while(pos2 != std::string::npos) + { + arg = line.substr(pos1, pos2-pos1); + args.push_back(arg); + pos1 = pos2+1; + pos2 = line.find(',',pos1); + } + arg = line.substr(pos1); + args.push_back(arg); + return true; +} + +bool cmParseCacheCoverage::ReadCMCovFile(const char* file) +{ + std::ifstream in(file); + if(!in) + { + cmCTestLog(this->CTest, ERROR_MESSAGE, + "Can not open : " + << file << "\n"); + return false; + } + std::string line; + std::vector separateLine; + if(!cmSystemTools::GetLineFromStream(in, line)) + { + cmCTestLog(this->CTest, ERROR_MESSAGE, + "Empty file : " + << file << " referenced in this line of cmcov data:\n" + "[" << line << "]\n"); + return false; + } + separateLine.clear(); + this->SplitString(separateLine, line); + if(separateLine.size() !=4 || separateLine[0] != "Routine" + || separateLine[1] != "Line" || separateLine[2] != "RtnLine" + || separateLine[3] != "Code") + { + cmCTestLog(this->CTest, ERROR_MESSAGE, + "Bad first line of cmcov file : " + << file << " line:\n" + "[" << line << "]\n"); + } + std::string routine; + std::string filepath; + bool foundFile = false; + while(cmSystemTools::GetLineFromStream(in, line)) + { + // clear out line argument vector + separateLine.clear(); + // parse the comma separated line + this->SplitString(separateLine, line); + // might have more because code could have a quoted , in it + // but we only care about the first 3 args anyway + if(separateLine.size() < 4) + { + cmCTestLog(this->CTest, ERROR_MESSAGE, + "Bad line of cmcov file expected at least 4 found: " + << separateLine.size() << " " + << file << " line:\n" + "[" << line << "]\n"); + for(std::string::size_type i = 0; i < separateLine.size(); ++i) + { + cmCTestLog(this->CTest, ERROR_MESSAGE,"" + << separateLine[1] << " "); + } + cmCTestLog(this->CTest, ERROR_MESSAGE, "\n"); + return false; + } + // if we do not have a routine yet, then it should be + // the first argument in the vector + if(routine.size() == 0) + { + routine = separateLine[0]; + // Find the full path to the file + if(!this->FindMumpsFile(routine, filepath)) + { + cmCTestLog(this->CTest, ERROR_MESSAGE, + "Could not find mumps file for routine: " + << routine << "\n"); + filepath = ""; + continue; // move to next line + } + } + // if we have a routine name, check for end of routine + else + { + // Totals in arg 0 marks the end of a routine + if(separateLine[0].substr(0, 6) == "Totals") + { + routine = ""; // at the end of this routine + filepath = ""; + continue; // move to next line + } + } + // if the file path was not found for the routine + // move to next line. We should have already warned + // after the call to FindMumpsFile that we did not find + // it, so don't report again to cut down on output + if(filepath.size() == 0) + { + continue; + } + // routine and filepath should be set at this point. + // see if we have visited this file before, and if not + // call InitializeMumpsFile + if( this->Coverage.TotalCoverage[filepath].size() == 0) + { + // hack, this should be done on every file, but for now + // just do it on the ones that have coverage at all + this->InitializeMumpsFile(filepath); + } + // now we are ready to set the coverage from the line of data + cmCTestCoverageHandlerContainer::SingleFileCoverageVector& + coverageVector = this->Coverage.TotalCoverage[filepath]; + std::string::size_type linenumber = atoi(separateLine[1].c_str()) -1; + int count = atoi(separateLine[2].c_str()); + if(linenumber > coverageVector.size()) + { + cmCTestLog(this->CTest, ERROR_MESSAGE, + "Parse error line is greater than number of lines in file: " + << linenumber << " " << filepath << "\n"); + continue; // skip setting count to avoid crash + } + // now add to count for linenumber + coverageVector[linenumber] += count; + } + return true; +} diff --git a/Source/CTest/cmParseCacheCoverage.h b/Source/CTest/cmParseCacheCoverage.h new file mode 100644 index 000000000..f377567cc --- /dev/null +++ b/Source/CTest/cmParseCacheCoverage.h @@ -0,0 +1,40 @@ +/*============================================================================ + CMake - Cross Platform Makefile Generator + Copyright 2000-2009 Kitware, Inc. + + Distributed under the OSI-approved BSD License (the "License"); + see accompanying file Copyright.txt for details. + + This software is distributed WITHOUT ANY WARRANTY; without even the + implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + See the License for more information. +============================================================================*/ + +#ifndef cmParseCacheCoverage_h +#define cmParseCacheCoverage_h + +#include "cmParseMumpsCoverage.h" + +/** \class cmParseCacheCoverage + * \brief Parse Cache coverage information + * + * This class is used to parse Cache coverage information for + * mumps. + */ +class cmParseCacheCoverage : public cmParseMumpsCoverage +{ +public: + cmParseCacheCoverage(cmCTestCoverageHandlerContainer& cont, + cmCTest* ctest); +protected: + // implement virtual from parent + bool LoadCoverageData(const char* dir); + // Read a single mcov file + bool ReadCMCovFile(const char* f); + // split a string based on , + bool SplitString(std::vector& args, + std::string const& line); +}; + + +#endif diff --git a/Source/CTest/cmParseGTMCoverage.cxx b/Source/CTest/cmParseGTMCoverage.cxx index 90d047b5a..f850c3cce 100644 --- a/Source/CTest/cmParseGTMCoverage.cxx +++ b/Source/CTest/cmParseGTMCoverage.cxx @@ -88,36 +88,14 @@ bool cmParseGTMCoverage::ReadMCovFile(const char* file) { cmCTestLog(this->CTest, ERROR_MESSAGE, "Can not find mumps file : " - << lastroutine << " referenced in this line of mcov data:\n" + << lastroutine << + " referenced in this line of mcov data:\n" "[" << line << "]\n"); } continue; } // Find the full path to the file - std::map::iterator i = - this->RoutineToDirectory.find(routine); - bool found = false; - if(i != this->RoutineToDirectory.end()) - { - filepath = i->second; - found = true; - } - else - { - // try some alternate names - const char* tryname[] = {"GUX", "GTM", "ONT", 0}; - for(int k=0; tryname[k] != 0; k++) - { - std::string routine2 = routine + tryname[k]; - i = this->RoutineToDirectory.find(routine2); - if(i != this->RoutineToDirectory.end()) - { - found = true; - filepath = i->second; - break; // break out of tryname loop if found - } - } - } + bool found = this->FindMumpsFile(routine, filepath); if(found) { int lineoffset; diff --git a/Source/CTest/cmParseMumpsCoverage.cxx b/Source/CTest/cmParseMumpsCoverage.cxx index 761139f28..ed263a4ce 100644 --- a/Source/CTest/cmParseMumpsCoverage.cxx +++ b/Source/CTest/cmParseMumpsCoverage.cxx @@ -127,3 +127,31 @@ bool cmParseMumpsCoverage::LoadPackages(const char* d) } return true; } + +bool cmParseMumpsCoverage::FindMumpsFile(std::string const& routine, + std::string& filepath) +{ + std::map::iterator i = + this->RoutineToDirectory.find(routine); + if(i != this->RoutineToDirectory.end()) + { + filepath = i->second; + return true; + } + else + { + // try some alternate names + const char* tryname[] = {"GUX", "GTM", "ONT", 0}; + for(int k=0; tryname[k] != 0; k++) + { + std::string routine2 = routine + tryname[k]; + i = this->RoutineToDirectory.find(routine2); + if(i != this->RoutineToDirectory.end()) + { + filepath = i->second; + return true; + } + } + } + return false; +} diff --git a/Source/CTest/cmParseMumpsCoverage.h b/Source/CTest/cmParseMumpsCoverage.h index 81180eecd..c1effa79b 100644 --- a/Source/CTest/cmParseMumpsCoverage.h +++ b/Source/CTest/cmParseMumpsCoverage.h @@ -40,6 +40,9 @@ protected: bool LoadPackages(const char* dir); // initialize the coverage information for a single mumps file void InitializeMumpsFile(std::string& file); + // Find mumps file for routine + bool FindMumpsFile(std::string const& routine, + std::string& filepath); protected: std::map RoutineToDirectory; cmCTestCoverageHandlerContainer& Coverage; diff --git a/Tests/CMakeLists.txt b/Tests/CMakeLists.txt index 9a088e43b..2cab6959f 100644 --- a/Tests/CMakeLists.txt +++ b/Tests/CMakeLists.txt @@ -1726,6 +1726,22 @@ ${CMake_BINARY_DIR}/bin/cmake -DVERSION=master -P ${CMake_SOURCE_DIR}/Utilities/ set_tests_properties(CTestGTMCoverage PROPERTIES PASS_REGULAR_EXPRESSION "Process file.*XINDEX.m.*Total LOC:.*127.*Percentage Coverage: 85.83.*") + + configure_file( + "${CMake_SOURCE_DIR}/Tests/MumpsCoverage/DartConfiguration.cache.tcl.in" + "${CMake_BINARY_DIR}/Testing/MumpsCacheCoverage/DartConfiguration.tcl") + configure_file( + "${CMake_SOURCE_DIR}/Tests/MumpsCoverage/cache_coverage.cmcov.in" + "${CMake_BINARY_DIR}/Testing/MumpsCacheCoverage/cache_coverage.cmcov") + file(COPY "${CMake_SOURCE_DIR}/Tests/MumpsCoverage/VistA-FOIA" + DESTINATION "${CMake_BINARY_DIR}/Testing/MumpsCacheCoverage") + add_test(NAME CTestCacheCoverage + WORKING_DIRECTORY "${CMake_BINARY_DIR}/Testing/MumpsCacheCoverage" + COMMAND + ${CMAKE_CTEST_COMMAND} -T Coverage --debug) + set_tests_properties(CTestCacheCoverage PROPERTIES + PASS_REGULAR_EXPRESSION + "Process file.*XINDEX.m.*Total LOC:.*125.*Percentage Coverage: 85.60.*") # Use macro, not function so that build can still be driven by CMake 2.4. # After 2.6 is required, this could be a function without the extra 'set' # calls. diff --git a/Tests/MumpsCoverage/Accounts_ReceivableTest.cmcov b/Tests/MumpsCoverage/Accounts_ReceivableTest.cmcov new file mode 100644 index 000000000..c3b3342ab --- /dev/null +++ b/Tests/MumpsCoverage/Accounts_ReceivableTest.cmcov @@ -0,0 +1,304 @@ +Routine,Line,RtnLine,Code +DDIOL,1,0,"DDIOL ;SFISC/MKO-THE LOADER ;1:53 PM 12 Sep 1995" +,2,0," ;;22.0;VA FileMan;;Mar 30, 1999" +,3,0," ;Per VHA Directive 10-93-142, this routine should not be modified." +,4,0," ;" +,5,0,"EN(A,G,FMT) ;Write the text contained in local array A or global array G" +,6,0," ;If one string passed, use format FMT" +,7,0," N %,Y,DINAKED" +,8,0," S DINAKED=$$LGR^%ZOSV" +,9,0," ;" +,10,0," S:'$D(A) A=""""" +,11,0," I $G(A)="""",$D(A)<9,$G(FMT)="""",$G(G)'?1""^""1A.7AN,$G(G)'?1""^""1A.7AN1""("".E1"")"" Q" +,12,0," ;" +,13,0," G:$D(DDS) SM" +,14,0," G:$D(DIQUIET) LD" +,15,0," ;" +,16,0," N F,I,S" +,17,0," I $D(A)=1,$G(G)="""" D" +,18,0," . S F=$S($G(FMT)]"""":FMT,1:""!"")" +,19,0," . W @F,A" +,20,0," ;" +,21,0," E I $D(A)>9 S I=0 F S I=$O(A(I)) Q:I'=+$P(I,""E"") D" +,22,0," . S F=$G(A(I,""F""),""!"") S:F="""" F=""?0""" +,23,0," . W @F,$G(A(I))" +,24,0," ;" +,25,0," E S I=0 F S I=$O(@G@(I)) Q:I'=+$P(I,""E"") D" +,26,0," . S S=$G(@G@(I,0),$G(@G@(I)))" +,27,0," . S F=$G(@G@(I,""F""),""!"") S:F="""" F=""?0""" +,28,0," . W @F,S" +,29,0," ;" +,30,0," I DINAKED]"""" S DINAKED=$S(DINAKED["""""""""""":$O(@DINAKED),1:$D(@DINAKED))" +,31,0," Q" +,32,0," ;" +,33,0,"LD ;Load text into ^TMP" +,34,0," N I,N,T" +,35,0," S T=$S($G(DDIOLFLG)[""H"":""DIHELP"",1:""DIMSG"")" +,36,0," S N=$O(^TMP(T,$J,"" ""),-1)" +,37,0," ;" +,38,0," I $D(A)=1,$G(G)="""" D" +,39,0," . D LD1(A,$S($G(FMT)]"""":FMT,1:""!""))" +,40,0," ;" +,41,0," E I $D(A)>9 S I=0 F S I=$O(A(I)) Q:I'=+$P(I,""E"") D" +,42,0," . D LD1($G(A(I)),$G(A(I,""F""),""!""))" +,43,0," ;" +,44,0," E S I=0 F S I=$O(@G@(I)) Q:I'=+$P(I,""E"") D" +,45,0," . D LD1($G(@G@(I),$G(@G@(I,0))),$G(@G@(I,""F""),""!""))" +,46,0," ;" +,47,0," K:'N @T S:N @T=N" +,48,0," I DINAKED]"""" S DINAKED=$S(DINAKED["""""""""""":$O(@DINAKED),1:$D(@DINAKED))" +,49,0," Q" +,50,0," ;" +,51,0,"LD1(S,F) ;Load string S, with format F" +,52,0," ;In: N and T" +,53,0," N C,J,L" +,54,0," S:S[$C(7) S=$TR(S,$C(7),"""")" +,55,0," F J=1:1:$L(F,""!"")-1 S N=N+1,^TMP(T,$J,N)=""""" +,56,0," S:'N N=1" +,57,0," S:F[""?"" @(""C=""_$P(F,""?"",2))" +,58,0," S L=$G(^TMP(T,$J,N))" +,59,0," S ^TMP(T,$J,N)=L_$J("""",$G(C)-$L(L))_S" +,60,0," Q" +,61,0," ;" +,62,0,"SM ;Print text in ScreenMan's Command Area" +,63,0," I $D(DDSID),$D(DTOUT)!$D(DUOUT) G SMQ" +,64,0," N DDIOL" +,65,0," S DDIOL=1" +,66,0," ;" +,67,0," I $D(A)=1&($G(G)="""")!($D(A)>9) D" +,68,0," . D MSG^DDSMSG(.A,"""",$G(FMT))" +,69,0," E I $D(@G@(+$O(@G@(0)),0))#2 D" +,70,0," . D WP^DDSMSG(G)" +,71,0," E D HLP^DDSMSG(G)" +,72,0," ;" +,73,0,"SMQ I DINAKED]"""" S DINAKED=$S(DINAKED["""""""""""":$O(@DINAKED),1:$D(@DINAKED))" +,74,0," Q" +Totals for DDIOL,,0, +XINDEX,1,0,"XINDEX ;ISC/REL,GFT,GRK,RWF - INDEX & CROSS-REFERENCE ;08/04/08 13:19" +,2,1," ;;7.3;TOOLKIT;**20,27,48,61,66,68,110,121,128**;Apr 25, 1995;Build 1" +,3,0," ; Per VHA Directive 2004-038, this routine should not be modified." +,4,1," G ^XINDX6" +,5,107216,"SEP F I=1:1 S CH=$E(LIN,I) D QUOTE:CH=Q Q:"" ""[CH" +,6,107216," S ARG=$E(LIN,1,I-1) S:CH="" "" I=I+1 S LIN=$E(LIN,I,999) Q" +,7,36371,"QUOTE F I=I+1:1 S CH=$E(LIN,I) Q:CH=""""!(CH=Q)" +,8,36371," Q:CH]"""" S ERR=6 G ^XINDX1" +,9,0,"ALIVE ;enter here from taskman" +,10,1," D SETUP^XINDX7 ;Get ready to process" +,11,468,"A2 S RTN=$O(^UTILITY($J,RTN)) G ^XINDX5:RTN=""""" +,12,467," S INDLC=(RTN?1""|""1.4L.NP) D LOAD:'INDLC" +,13,467," I $D(ZTQUEUED),$$S^%ZTLOAD S RTN=""~"",IND(""QUIT"")=1,ZTSTOP=1 G A2" +,14,467," I 'INDDS,INDLC W !!?10,""Data Dictionaries"",! S INDDS=1" +,15,467," D BEG" +,16,467," G A2" +,17,0," ;" +,18,467,"LOAD S X=RTN,XCNP=0,DIF=""^UTILITY(""_$J_"",1,RTN,0,"" X ^%ZOSF(""TEST"") Q:'$T X ^%ZOSF(""LOAD"") S ^UTILITY($J,1,RTN,0,0)=XCNP-1" +,19,467," I $D(^UTILITY($J,1,RTN,0,0)) S ^UTILITY($J,1,RTN,""RSUM"")=""B""_$$SUMB^XPDRSUM($NA(^UTILITY($J,1,RTN,0)))" +,20,467," Q" +,21,0,"BEG ;" +,22,467," S %=INDLC*5 W:$X+10+%>IOM ! W RTN,$J("""",10+%-$L(RTN))" +,23,467," S (IND(""DO""),IND(""SZT""),IND(""SZC""),LABO)=0,LC=$G(^UTILITY($J,1,RTN,0,0))" +,24,467," I LC="""" W !,"">>>Routine '"",RTN,""' not found <<<"",! Q" +,25,467," S TXT="""",LAB=$P(^UTILITY($J,1,RTN,0,1,0),"" "") I RTN'=$P(LAB,""("") D E^XINDX1(17)" +,26,467," I 'INDLC,LAB[""("" D E^XINDX1(55) S LAB=$P(LAB,""("")" +,27,0," ;if M routine(not compiled template or DD) and has more than 2 lines, check lines 1 & 2" +,28,467," I 'INDLC,LC>2 D" +,29,467," . N LABO S LABO=1" +,30,467," . S LIN=$G(^UTILITY($J,1,RTN,0,1,0)),TXT=1" +,31,0," . ;check 1st line (site/dev - ) patch 128" +,32,467," . I $P(LIN,"";"",2,4)'?.E1""/"".E.1""-"".E D E^XINDX1(62)" +,33,467," . S LIN=$G(^UTILITY($J,1,RTN,0,2,0)),TXT=2" +,34,0," . ;check 2nd line (;;nn.nn[TV]nn;package;.anything)" +,35,467," . I $P(LIN,"";"",3,99)'?1.2N1"".""1.2N.1(1""T"",1""V"").2N1"";""1A.AP1"";"".E D E^XINDX1(44) ;patch 121" +,36,467," . I $L(INP(11)) X INP(11) ;Version number check" +,37,467," . I $L(INP(12)) X INP(12) ;Patch number check" +,38,467,"B5 F TXT=1:1:LC S LIN=^UTILITY($J,1,RTN,0,TXT,0),LN=$L(LIN),IND(""SZT"")=IND(""SZT"")+LN+2 D LN,ST ;Process Line" +,39,467," S LAB="""",LABO=0,TXT=0,^UTILITY($J,1,RTN,0)=IND(""SZT"")_""^""_LC_""^""_IND(""SZC"")" +,40,467," I IND(""SZT"")>INP(""MAX""),'INDLC S ERR=35,ERR(1)=IND(""SZT"") D ^XINDX1" +,41,467," I IND(""SZT"")-IND(""SZC"")>INP(""CMAX""),'INDLC S ERR=58,ERR(1)=IND(""SZT"")-IND(""SZC"") D ^XINDX1" +,42,467," D POSTRTN" +,43,467," Q" +,44,0," ;Proccess one line, LN = Length, LIN = Line." +,45,44620,"LN K V S (ARG,GRB,IND(""COM""),IND(""DOL""),IND(""F""))="""",X=$P(LIN,"" "")" +,46,44620," I '$L(X) S LABO=LABO+1 G CD" +,47,5073," S (IND(""COM""),LAB)=$P(X,""(""),ARG=$P($P(X,""("",2),"")""),LABO=0,IND(""PP"")=X?1.8E1""("".E1"")""" +,48,5073," D:$L(ARG) NE^XINDX3 ;Process formal parameters as New list." +,49,5073," I 'INDLC,'$$VT^XINDX2(LAB) D E^XINDX1($S(LAB=$$CASE^XINDX52(LAB):37,1:55)) ;Check for bad labels" +,50,5073," I $D(^UTILITY($J,1,RTN,""T"",LAB)) D E^XINDX1(15) G CD ;DUP label" +,51,5073," S ^UTILITY($J,1,RTN,""T"",LAB)=""""" +,52,44620,"CD I LN>245 D:'(LN=246&($E(RTN,1,3)=""|dd"")) E^XINDX1(19) ;patch 119" +,53,44620," D:LIN'?1.ANP E^XINDX1(18)" +,54,44620," S LIN=$P(LIN,"" "",2,999),IND(""LCC"")=1" +,55,44620," I LIN="""" D E^XINDX1(42) Q ;Blank line ;p110" +,56,44620," S I=0 ;Watch the scope of I, counts dots" +,57,44620," I "" .""[$E(LIN) D S X=$L($E(LIN,1,I),""."")-1,LIN=$E(LIN,I,999)" +,58,10770," . F I=1:1:245 Q:"". ""'[$E(LIN,I)" +,59,10770," . Q" +,60,0," ;check dots against Do level IND(""DO""), IND(""DOL"")=dot level" +,61,44620," D:'I&$G(IND(""DO1"")) E^XINDX1(51) S IND(""DO1"")=0 S:'I IND(""DO"")=0" +,62,44620," I I D:X>IND(""DO"") E^XINDX1(51) S (IND(""DO""),IND(""DOL""))=X" +,63,0," ;Count Comment lines, skip ;; lines" +,64,44620," I $E(LIN)="";"",$E(LIN,2)'="";"" S IND(""SZC"")=IND(""SZC"")+$L(LIN) ;p110" +,65,0," ;Process commands on line." +,66,116081,"EE I LIN="""" D ^XINDX2 Q" +,67,71461," S COM=$E(LIN),GK="""",ARG=""""" +,68,71461," I COM="";"" S LIN="""" G EE ;p110" +,69,54870," I COM="" "" S ERR=$S(LIN?1."" "":13,1:0),LIN=$S(ERR:"""",1:$E(LIN,2,999)) D:ERR ^XINDX1 G EE" +,70,53608," D SEP" +,71,53608," S CM=$P(ARG,"":"",1),POST=$P(ARG,"":"",2,999),IND(""COM"")=IND(""COM"")_$C(9)_COM,ERR=48" +,72,53608," D:ARG["":""&(POST']"""") ^XINDX1 S:POST]"""" GRB=GRB_$C(9)_POST,IND(""COM"")=IND(""COM"")_"":""" +,73,0," ;SAC now allows lowercase commands" +,74,53608," I CM?.E1L.E S CM=$$CASE^XINDX52(CM),COM=$E(CM) ;I IND(""LCC"") S IND(""LCC"")=0 D E^XINDX1(47)" +,75,53608," I CM="""" D E^XINDX1(21) G EE ;Missing command" +,76,53608," S CX=$G(IND(""CMD"",CM)) I CX="""" D G:CX="""" EE" +,77,0," . I $E(CM)=""Z"" S CX=""^Z"" Q ;Proccess Z commands" +,78,0," . D E^XINDX1(1) S LIN="""" Q" +,79,53608," S CX=$P(CX,""^"",2,9)" +,80,53608," D SEP I '$L(LIN),CH="" "" D E^XINDX1(13) ;trailing space" +,81,53608," I ARG="""",""CGJMORSUWX""[COM S ERR=49 G ^XINDX1" +,82,53608," I CX>0 D E^XINDX1(CX) S CX=""""" +,83,53608," D:$L(CX) @CX S:ARG'="""" GRB=GRB_$C(9)_ARG G EE" +,84,0,"B S ERR=25 G ^XINDX1" +,85,0,"C S ERR=29 G ^XINDX1" +,86,0,"D G DG1^XINDX4" +,87,0,"E Q:ARG="""" S ERR=7 G ^XINDX1" +,88,1559,"F G:ARG]"""" FR^XINDX4 S IND(""F"")=1 Q" +,89,1932,"G G DG^XINDX4" +,90,11,"H Q:ARG'="""" S ERR=32 G ^XINDX1" +,91,0,"J S ERR=36,ARG="""" G ^XINDX1" +,92,2218,"K S ERR=$S(ARG?1""("".E:22,ARG?."" "":23,1:0) D:ERR ^XINDX1" +,93,2218," G KL^XINDX3" +,94,259,"L G LO^XINDX4" +,95,30,"M G S^XINDX3" +,96,1721,"N G NE^XINDX3" +,97,0,"O S ERR=34 D ^XINDX1,O^XINDX3 Q" +,98,7762,"Q Q:ARG="""" G Q^XINDX4" +,99,85,"R S RDTIME=0 G RD^XINDX3" +,100,17549,"S G S^XINDX3" +,101,0,"TR Q ;What to process. p110" +,102,72,"U S ARG=$P(ARG,"":"") Q" +,103,0,"V S ARG="""",ERR=20 G ^XINDX1" +,104,4584,"W G WR^XINDX4" +,105,220,"X G XE^XINDX4" +,106,0,"Z S ERR=2 D ^XINDX1 G ZC^XINDX4" +,107,0," ;" +,108,0," ;Save off items from line." +,109,44620,"ST S R=LAB_$S(LABO:""+""_LABO,1:"""")" +,110,0," ;Local variable, Global, Marked Items, Naked global, Internal ref, eXternal ref., Tag ref." +,111,44620," S LOC="""" F S LOC=$O(V(LOC)),S="""" Q:LOC="""" F S S=$O(V(LOC,S)) Q:S="""" D SET" +,112,44620," S ^UTILITY($J,1,RTN,""COM"",TXT)=IND(""COM"")" +,113,44620," Q" +,114,0," ;" +,115,85079,"SET I V(LOC,S)]"""" F %=""!"",""~"" I V(LOC,S)[%,$G(^UTILITY($J,1,RTN,LOC,S))'[% S ^(S)=$G(^(S))_%" +,116,85079," S %=0" +,117,86891,"SE2 S ARG=$G(^UTILITY($J,1,RTN,LOC,S,%)) I $L(ARG)>230 S %=%+1 G SE2" +,118,85079," S ^UTILITY($J,1,RTN,LOC,S,%)=ARG_R_V(LOC,S)_"",""" +,119,85079," Q" +,120,0," ;" +,121,0,"POSTRTN ;Do more overall checking" +,122,467," N V,E,T,T1,T2" +,123,467," S T="""" ;Check for missing Labels" +,124,467," F S T=$O(^UTILITY($J,1,RTN,""I"",T)),T2=T Q:T="""" S T1=$G(^(T,0)) D" +,125,2091," . Q:$E(T2,1,2)=""@(""" +,126,2044," . S:$E(T2,1,2)=""$$"" T2=$E(T2,3,99)" +,127,2044," . I T2]"""",'$D(^UTILITY($J,1,RTN,""T"",$P(T2,""+"",1))) D" +,128,0," . . F I=1:1:$L(T1,"","")-1 S LAB=$P(T1,"","",I),LABO=+$P(LAB,""+"",2),LAB=$P(LAB,""+""),E=14,E(1)=T D E^XINDX1(.E)" +,129,0," . . Q" +,130,2044," . Q" +,131,467," S LAB="""",LABO=0 ;Check for valid label names" +,132,467," I 'INDLC F S LAB=$O(^UTILITY($J,1,RTN,""T"",LAB)) Q:LAB="""" D" +,133,5073," . I '$$VA^XINDX2(LAB) D E^XINDX1(55) Q" +,134,5073," . D:'$$VT^XINDX2(LAB) E^XINDX1(37)" +,135,5073," . Q" +,136,467," S LAB="""",LABO=0 ;Check for valid variable names." +,137,467," F S LAB=$O(^UTILITY($J,1,RTN,""L"",LAB)) Q:LAB="""" D" +,138,15909," . D VLNF^XINDX3($P(LAB,""(""))" +,139,15909," . Q" +,140,467," Q" +,141,0," ;" +,142,0,"QUICK ;Quick, Just get a routine an print the results" +,143,0," D QUICK^XINDX6()" +,144,0," Q" +Totals for XINDEX,,2446443, +XINDX1,1,0,"XINDX1 ;ISC/REL,GRK,RWF - ERROR ROUTINE ;08/05/08 13:59" +,2,2," ;;7.3;TOOLKIT;**20,61,66,68,110,121,128**;Apr 25, 1995;Build 1" +,3,0," ; Per VHA Directive 2004-038, this routine should not be modified." +,4,2," G A" +,5,0,"E(ERR) ;" +,6,75,"A N %,%1 ;TXT is the line of the error." +,7,75," S ERTX=LAB_$S(LABO:""+""_LABO,1:"""")_$C(9),%1=$T(ERROR+ERR),ERTX=ERTX_$S(ERR:$P(%1,"";"",4,9),1:ERR) ;p110" +,8,75," I ERTX[""|"" F %=1:1 S ERTX=$P(ERTX,""|"")_$S($D(ERR(%)):ERR(%),1:""??"")_$P(ERTX,""|"",%+1,99) Q:ERTX'[""|""" +,9,75,"B I $P(%1,"";"",3)]"""" D Q:%1]"""" ;Don't flag kernel doing kernel." +,10,0," . S %1=$P(%1,"";"",3)" +,11,0," . F Q:RTN[$P(%1,"","") S %1=$P(%1,"","",2,99) ;quit if RTN[%1 or null." +,12,0," . Q" +,13,75," I ERR=17,$E(RTN)'=""%"",$E(LAB)=""%"" Q ;Don't flag %RTN w/o %." +,14,0," ;Global is Error Line,tab,error tag,tab,error text" +,15,75," S %=$G(^UTILITY($J,1,RTN,""E"",0))+1,^(0)=%,^(%)=TXT_$C(9)_ERTX" +,16,75," Q" +,17,0," ;" +,18,0," ;F = Fatal, S = Standard, W = Warning, I = Info" +,19,0,"ERROR ;" +,20,0,"1 ;;;F - UNDEFINED COMMAND (rest of line not checked)." +,21,0,"2 ;;;F - Non-standard (Undefined) 'Z' command." +,22,0,"3 ;;XTRMON;F - Undefined Function." +,23,0,"4 ;;;F - Undefined Special Variable." +,24,0,"5 ;;;F - Unmatched Parenthesis." +,25,0,"6 ;;;F - Unmatched Quotation Marks." +,26,0,"7 ;;;F - ELSE Command followed by only one space." +,27,0,"8 ;;;F - FOR Command did not contain '='." +,28,0,"9 ;;;I - QUIT Command followed by only one space." +,29,0,"10 ;;;F - Unrecognized argument in SET command." +,30,0,"11 ;;;W - Invalid local variable name." +,31,0,"12 ;;;W - Invalid global variable name." +,32,0,"13 ;;;W - Blank(s) at end of line." +,33,0,"14 ;;;F - Call to missing label '|' in this routine." +,34,0,"15 ;;;W - Duplicate label. (M57)" +,35,0,"16 ;;;F - Error in pattern code." +,36,0,"17 ;;;W - First line label NOT routine name." +,37,0,"18 ;;;W - Line contains a CONTROL (non-graphic) character." +,38,0,"19 ;;;S - Line is longer than 245 bytes." +,39,0,"20 ;;;S - View command used." +,40,0,"21 ;;;F - General Syntax Error." +,41,0,"22 ;;;S - Exclusive Kill." +,42,0,"23 ;;;S - Unargumented Kill." +,43,0,"24 ;;;S - Kill of an unsubscripted global." +,44,0,"25 ;;;S - Break command used." +,45,0,"26 ;;;S - Exclusive or Unargumented NEW command." +,46,0,"27 ;;;S - $View function used." +,47,0,"28 ;;ZOSV,ZIS,ZT;S - Non-standard $Z special variable used." +,48,0,"29 ;;ZIS,ZTM;S - 'Close' command should be invoked through 'D ^%ZISC'." +,49,0,"30 ;;;S - LABEL+OFFSET syntax." +,50,0,"31 ;;ZOSV,ZIS,ZT;S - Non-standard $Z function used." +,51,0,"32 ;;;S - 'HALT' command should be invoked through 'G ^XUSCLEAN'." +,52,0,"33 ;;;S - Read command doesn't have a timeout." +,53,0,"34 ;;ZIS;S - 'OPEN' command should be invoked through ^%ZIS." +,54,0,"35 ;;;S - Routine exceeds SACC maximum size of 20000 (|)." +,55,0,"36 ;;ZTM;S - Should use 'TASKMAN' instead of 'JOB' command." +,56,0,"37 ;;;F - Label is not valid." +,57,0,"38 ;;;F - Call to this |" +,58,0,"39 ;;ZIS,XUS,XUP;S - Kill of a protected variable (|)." +,59,0,"40 ;;;S - Space where a command should be." +,60,0,"41 ;;;I - Star or pound READ used." +,61,0,"42 ;;;W - Null line (no commands or comment)." +,62,0,"43 ;;;F - Invalid or wrong number of arguments to a function." +,63,0,"44 ;;;S - 2nd line of routine violates the SAC." +,64,0,"45 ;;ZT,ZIS,XUTM,XTER;S - Set to a '%' global." +,65,0,"46 ;;;F - Quoted string not followed by a separator." +,66,0,"47 ;;;S - Lowercase command(s) used in line." +,67,0,"48 ;;;F - Missing argument to a command post-conditional." +,68,0,"49 ;;;F - Command missing an argument." +,69,0,"50 ;;ZTM;S - Extended reference." +,70,0,"51 ;;;F - Block structure mismatch." +,71,0,"52 ;;;F - Reference to routine '^|'. That isn't in this UCI." +,72,0,"53 ;;;F - Bad Number." +,73,0,"54 ;;XG;S - Access to SSVN's restricted to Kernel." +,74,0,"55 ;;;S - Violates VA programming standards." +,75,0,"56 ;;;S - Patch number '|' missing from second line." +,76,0,"57 ;;;S - Lower/Mixed case Variable name used." +,77,0,"58 ;;;S - Routine code exceeds SACC maximum size of 15000 (|)." +,78,0,"59 ;;;F - Bad WRITE syntax." +,79,0,"60 ;;;S - Lock missing Timeout." +,80,0,"61 ;;;S - Non-Incremental Lock." +,81,0,"62 ;;;S - First line of routine violates the SAC." +,82,0,"63 ;;;F - GO or DO mismatch from block structure (M45)." +Totals for XINDX1,,529, diff --git a/Tests/MumpsCoverage/DartConfiguration.cache.tcl.in b/Tests/MumpsCoverage/DartConfiguration.cache.tcl.in new file mode 100644 index 000000000..a1c6b17f6 --- /dev/null +++ b/Tests/MumpsCoverage/DartConfiguration.cache.tcl.in @@ -0,0 +1,8 @@ +# This file is configured by CMake automatically as DartConfiguration.tcl +# If you choose not to use CMake, this file may be hand configured, by +# filling in the required variables. + + +# Configuration directories and files +SourceDirectory: ${CMake_SOURCE_DIR}/Testing/MumpsCoverage +BuildDirectory: ${CMake_BINARY_DIR}/Testing/MumpsCacheCoverage diff --git a/Tests/MumpsCoverage/cache_coverage.cmcov.in b/Tests/MumpsCoverage/cache_coverage.cmcov.in new file mode 100644 index 000000000..b431dbdc1 --- /dev/null +++ b/Tests/MumpsCoverage/cache_coverage.cmcov.in @@ -0,0 +1,2 @@ +packages:${CMake_BINARY_DIR}/Testing/MumpsCoverage/VistA-FOIA/Packages +coverage_dir:${CMake_SOURCE_DIR}/Tests/MumpsCoverage