bool makeCoverageBuildProject() { std::string origProjFilePath = Project::getProjectFilePath(); std::string origCompTypesFilePath = Project::getComponentTypesFilePath(); std::string origPackagesFilePath = Project::getPackagesFilePath(); std::string covSrcDir = Project::getCoverageSourceDirectory(); std::string covProjDir = Project::getCoverageProjectDirectory(); bool success = true; OovStatus status = FileEnsurePathExists(covProjDir); if(status.ok()) { Project::setProjectDirectory(covProjDir); std::string newProjFilePath = Project::getProjectFilePath(); success = makeCoverageProjectFile(origProjFilePath, newProjFilePath, covSrcDir); if(success) { success = makeCoverageComponentTypesFile(origCompTypesFilePath, Project::getComponentTypesFilePath()); } if(success) { success = copyPackageFileIfNeeded(origPackagesFilePath, Project::getPackagesFilePath()); } } return status.ok() && success; }
/// Copy a single source file and make a comment that contains the hit count /// for each instrumented line. static void updateCovSourceCounts(OovStringRef const relSrcFn, std::vector<int> &counts) { FilePath srcFn(Project::getCoverageSourceDirectory(), FP_Dir); srcFn.appendFile(relSrcFn); FilePath dstFn(Project::getCoverageProjectDirectory(), FP_Dir); dstFn.appendFile(relSrcFn); File srcFile; OovStatus status = srcFile.open(srcFn, "r"); if(status.ok()) { status = FileEnsurePathExists(dstFn); if(status.ok()) { File dstFile; status = dstFile.open(dstFn, "w"); if(status.ok()) { char buf[1000]; size_t instrCount = 0; while(srcFile.getString(buf, sizeof(buf), status)) { if(strstr(buf, "COV_IN(")) { if(instrCount < counts.size()) { OovString countStr = " // "; countStr.appendInt(counts[instrCount]); OovString newStr = buf; size_t pos = newStr.find('\n'); newStr.insert(pos, countStr); if(newStr.length() < sizeof(buf)-1) { strcpy(buf, newStr.getStr()); } } instrCount++; } status = dstFile.putString(buf); if(!status.ok()) { break; } } } } } if(status.needReport()) { OovString err = "Unable to transfer coverage "; err += srcFn; err += " "; err += dstFn; status.report(ET_Error, err); } }
FilePath Project::getOutputDir() { FilePath fp(Project::getProjectDirectory(), FP_Dir); fp.appendDir("output"); OovStatus status = FileEnsurePathExists(fp); if(status.needReport()) { OovString err = "Unable to create directory "; err += fp; status.report(ET_Error, fp); } return fp; }
/// The package file is only copied if it doesn't exist or is old. If it was /// always copied, then the date would be updated which would cause a full /// rebuild of all analysis and build files. static bool copyPackageFileIfNeeded(OovStringRef const srcFn, OovStringRef const dstFn) { OovStatus status(true, SC_File); if(FileStat::isOutputOld(dstFn, srcFn, status)) { File srcFile; status = srcFile.open(srcFn, "r"); if(status.ok()) { if(FileIsFileOnDisk(srcFn, status)) { if(srcFile.isOpen()) { status = FileEnsurePathExists(dstFn); if(status.ok()) { File dstFile; status = dstFile.open(dstFn, "w"); if(status.ok()) { char buf[10000]; while(srcFile.getString(buf, sizeof(buf), status)) { status = dstFile.putString(buf); if(!status.ok()) { break; } } } } } } } if(status.needReport()) { OovString err = "Unable to copy package file "; err += srcFn; status.report(ET_Error, err); } } return status.ok(); }
/* class OovMonitorWriter { public: OovMonitorWriter(): mFp(0) {} ~OovMonitorWriter() { fclose(mFp); } void append(int fileIndex, int instrIndex) { if(!mFp) { mFp = fopen("OovMonitor.txt", "a"); } { // std::lock_guard<std::mutex> writeMutexLock(mWriteMutex); std::stringstream id; id << std::this_thread::get_id(); fprintf(mFp, "%s %d %d\n", id.str().c_str(), fileIndex, instrIndex); fflush(mFp); } } private: FILE *mFp; // std::mutex mWriteMutex; }; OovMonitorWriter sOovMonitor; void OovMonitor(int fileIndex, int instrIndex) { sOovMonitor.append(fileIndex, instrIndex); } */ void CppInstr::updateCoverageSource(OovStringRef const /*fn*/, OovStringRef const covDir) { FilePath outFn(covDir, FP_Dir); outFn.appendDir("covLib"); OovStatus status = FileEnsurePathExists(outFn); if(status.ok()) { outFn.appendFile("OovCoverage.cpp"); if(!FileIsFileOnDisk(outFn, status)) { File file; status = file.open(outFn, "w"); static char const *lines[] = { "// Automatically generated file by OovCovInstr\n", "// This appends coverage data to either a new or existing file,\n" "// although the number of instrumented lines in the project must match.\n" "// This file must be compiled and linked into the project.\n", "#include <stdio.h>\n", "#include \"OovCoverage.h\"\n", "\n", "unsigned short gCoverage[COV_TOTAL_INSTRS];\n", "\n", "class cCoverageOutput\n", " {\n", " public:\n", " cCoverageOutput()\n", " {\n", " // Initialize because some compilers may not initialize statics (TI)\n", " for(int i=0; i<COV_TOTAL_INSTRS; i++)\n", " gCoverage[i] = 0;\n", " }\n", " ~cCoverageOutput()\n", " {\n", " update();\n", " }\n", " void update()\n", " {\n", " read();\n", " write();\n", " }\n", "\n", " private:\n", " int getFirstIntFromLine(FILE *fp)\n", " {\n", " char buf[80];\n", " fgets(buf, sizeof(buf), fp);\n", " unsigned int tempInt = 0;\n", " sscanf(buf, \"%u\", &tempInt);\n", " return tempInt;\n", " }\n", " void read()\n", " {\n", " FILE *fp = fopen(\"OovCoverageCounts.txt\", \"r\");\n", " if(fp)\n", " {\n", " int numInstrs = getFirstIntFromLine(fp);\n", " if(numInstrs == COV_TOTAL_INSTRS)\n", " {\n", " for(int i=0; i<COV_TOTAL_INSTRS; i++)\n", " {\n", " gCoverage[i] += getFirstIntFromLine(fp);\n", " }\n", " }\n", " fclose(fp);\n", " }\n", " }\n", " void write()\n", " {\n", " FILE *fp = fopen(\"OovCoverageCounts.txt\", \"w\");\n", " if(fp)\n", " {\n", " fprintf(fp, \"%d # Number of instrumented lines\\n\", COV_TOTAL_INSTRS);\n", " for(int i=0; i<COV_TOTAL_INSTRS; i++)\n", " {\n", " fprintf(fp, \"%u\", gCoverage[i]);\n", " gCoverage[i] = 0;\n", " fprintf(fp, \"\\n\");\n", " }\n", " fclose(fp);\n", " }\n", " }\n", " };\n", "\n", "cCoverageOutput coverageOutput;\n" "\n", "void updateCoverage()\n", " { coverageOutput.update(); }\n" }; for(size_t i=0; i<sizeof(lines)/sizeof(lines[0]) && status.ok(); i++) { status = file.putString(lines[i]); if(!status.ok()) { break; } } } } if(!status.ok()) { OovString err = "Unable to update coverage source "; err += outFn; status.report(ET_Error, err); } }
bool ProjectSettingsDialog::runDialog() { GtkEntry *projDirEntry = GTK_ENTRY(Builder::getBuilder()->getWidget( "OovaideProjectDirEntry")); GtkTextView *excDirsTextView = GTK_TEXT_VIEW(Builder::getBuilder()->getWidget( "ExcludeDirsTextview")); GtkEntry *srcDirEntry = GTK_ENTRY(Builder::getBuilder()->getWidget( "RootSourceDirEntry")); OovString origSourceDir = Project::getSourceRootDirectory(); if(mEditStyle == PS_NewProject) { Gui::clear(projDirEntry); Gui::clear(srcDirEntry); Gui::clear(excDirsTextView); } else { Gui::setText(projDirEntry, Project::getProjectDirectory()); Gui::setText(srcDirEntry, Project::getSourceRootDirectory()); CompoundValue excDirs(mProjectOptions.getValue(OptProjectExcludeDirs), ';'); Gui::setText(excDirsTextView, excDirs.getAsString('\n')); } bool editSrc = (mEditStyle == PS_NewProject || mEditStyle == PS_OpenProjectEditSource); Gui::setEnabled(srcDirEntry, editSrc); Gui::setEnabled(GTK_BUTTON(Builder::getBuilder()->getWidget( "RootSourceDirButton")), editSrc); Gui::setEnabled(GTK_BUTTON(Builder::getBuilder()->getWidget( "OovaideProjectDirButton")), mEditStyle == PS_NewProject); Gui::setEnabled(projDirEntry, mEditStyle == PS_NewProject); bool ok = run(true); if(ok) { OovStatus status(true, SC_File); if(!FileIsDirOnDisk(getRootSrcDir(), status)) { ok = Gui::messageBox("The source directory does not exist. " "Do you want to create it?", GTK_MESSAGE_QUESTION, GTK_BUTTONS_YES_NO); if(ok) { FilePath dir(getRootSrcDir(), FP_Dir); status = FileEnsurePathExists(dir); } } if(status.needReport()) { ok = false; status.report(ET_Error, "Unable to access directory"); } } if(ok) { mExcludeDirs.parseString(Gui::getText(excDirsTextView), '\n'); mExcludeDirs.deleteEmptyStrings(); Project::setSourceRootDirectory(getRootSrcDir()); // Update the project options. if(mEditStyle == PS_NewProject) { // The project dir is used by setDefaultOptions. OovString projectDir = getProjectDir(); Project::setProjectDirectory(projectDir); FilePathEnsureLastPathSep(projectDir); OovStatus status = FileEnsurePathExists(projectDir); OptionsDefaults optionDefaults(getProjectOptions()); optionDefaults.setDefaultOptions(); sProjectSettingsDialog->getGuiOptions().setDefaultOptions(); } FilePath rootSrcText(getRootSrcDir(), FP_Dir); getProjectOptions().setNameValue(OptSourceRootDir, rootSrcText); } return ok; }
int main(int argc, char * argv[]) { int ret = 1; bool verbose = false; bool writeToProject = false; const char *projDir = nullptr; const char *projName = "PROJNAME"; for(int argi=1; argi<argc; argi++) { if(argv[argi][0] == '-') { switch(argv[argi][1]) { case 'v': verbose = true; break; case 'w': writeToProject = true; break; case 'n': projName = &argv[argi][2]; break; } } else projDir = argv[argi]; } if(projDir) { Project::setProjectDirectory(projDir); CMaker maker(projName, verbose); FilePath outDir; if(writeToProject) { outDir.setPath(Project::getSrcRootDirectory(), FP_Dir); } else { outDir.setPath(Project::getBuildOutputDir("CMake"), FP_Dir); FileEnsurePathExists(outDir); if(maker.mVerbose) printf("Output directory %s\n", outDir.getStr()); } if(maker.mCompTypes.read()) { maker.makeToolchainFiles(outDir); maker.makeTopLevelFiles(outDir); maker.mBuildPkgs.read(); FilePath topMlFp(outDir, FP_File); topMlFp.appendFile("CMakeLists.txt"); maker.makeTopMakelistsFile(topMlFp); OovStringVec compNames = maker.mCompTypes.getComponentNames(true); if(compNames.size() > 0) { maker.makeComponentFiles(writeToProject, outDir, compNames); ret = 0; } else fprintf(stderr, "Components must be defined\n"); } else fprintf(stderr, "Unable to read project files\n"); } else { fprintf(stderr, "OovCMaker version %s\n", OOV_VERSION); fprintf(stderr, " OovCMaker projectDirectory [switches]\n"); fprintf(stderr, " switches -v=verbose, -w=write to project, -nProjName\n"); } return ret; }