示例#1
0
int main(int argc, char* argv[])
{
  llvm::cl::ParseCommandLineOptions(argc, argv, " globalcollect\n"
      "  This collects and prints global variables found in C programs.");

  if (!IgnoredParams.empty()) {
    cerr << "Ignoring the following parameters:";
    copy(IgnoredParams.begin(), IgnoredParams.end(),
        ostream_iterator<string>(cerr, " "));
  }

  // Create Preprocessor object
  PPContext context;

  // Add header search directories (C only, no C++ or ObjC)
  InitHeaderSearch init(context.headers);
  // user headers
  for (int i = 0; i < I_dirs.size(); ++i) {
    cerr << "adding " << I_dirs[i] << endl;
    init.AddPath(I_dirs[i], InitHeaderSearch::Angled, false, true, false);
  }
  init.AddDefaultSystemIncludePaths(context.opts);
  init.Realize();

  // Add defines passed in through parameters
  vector<char> predefineBuffer;
  for (int i = 0; i < D_macros.size(); ++i) {
    cerr << "defining " << D_macros[i] << endl;
    ::DefineBuiltinMacro(predefineBuffer, D_macros[i].c_str());
  }
  predefineBuffer.push_back('\0');
  context.pp.setPredefines(&predefineBuffer[0]);


  // Add input file
  const FileEntry* File = context.fm.getFile(InputFilename);
  if (!File) {
    cerr << "Failed to open \'" << InputFilename << "\'" << endl;
    return EXIT_FAILURE;
  }
  context.sm.createMainFileID(File, SourceLocation());


  // Parse it
  cout << "<h2><code>" << InputFilename << "</code></h2>" << endl << endl;
  cout << "<pre><code>";

  MyASTConsumer c;
  ParseAST(context.pp, &c);

  cout << "</code></pre>" << endl << endl;

  cout << endl;

  unsigned NumDiagnostics = context.diags.getNumDiagnostics();
  
  if (NumDiagnostics)
    fprintf(stderr, "%d diagnostic%s generated.\n", NumDiagnostics,
            (NumDiagnostics == 1 ? "" : "s"));
}
// Collect file system header files.
// This function scans the file system for header files,
// starting at the directory of the module.map file,
// optionally filtering out all but the files covered by
// the include path options.
// Returns true if no errors.
bool ModuleMapChecker::collectFileSystemHeaders() {

  // Get directory containing the module.map file.
  // Might be relative to current directory, absolute, or empty.
  ModuleMapDirectory = getDirectoryFromPath(ModuleMapPath);

  // If no include paths specified, we do the whole tree starting
  // at the module.map directory.
  if (IncludePaths.size() == 0) {
    if (!collectFileSystemHeaders(StringRef("")))
      return false;
  } else {
    // Otherwise we only look at the sub-trees specified by the
    // include paths.
    for (std::vector<std::string>::const_iterator I = IncludePaths.begin(),
                                                  E = IncludePaths.end();
         I != E; ++I) {
      if (!collectFileSystemHeaders(*I))
        return false;
    }
  }

  // Sort it, because different file systems might order the file differently.
  std::sort(FileSystemHeaders.begin(), FileSystemHeaders.end());

  return true;
}
示例#3
0
int main(int argc, char **argv) {
  llvm::cl::ParseCommandLineOptions(argc, argv, "clang-wpa");
  FileManager FileMgr;
  std::vector<ASTUnit*> ASTUnits;

  if (InputFilenames.empty())
    return 0;

  DiagnosticOptions DiagOpts;
  llvm::IntrusiveRefCntPtr<Diagnostic> Diags
    = CompilerInstance::createDiagnostics(DiagOpts, argc, argv);
  for (unsigned i = 0, e = InputFilenames.size(); i != e; ++i) {
    const std::string &InFile = InputFilenames[i];
    llvm::OwningPtr<ASTUnit> AST(ASTUnit::LoadFromPCHFile(InFile, Diags));
    if (!AST)
      return 1;

    ASTUnits.push_back(AST.take());
  }

  llvm::OwningPtr<CallGraph> CG;
  CG.reset(new CallGraph());

  for (unsigned i = 0, e = ASTUnits.size(); i != e; ++i)
    CG->addTU(ASTUnits[i]->getASTContext());

  CG->ViewCallGraph();
}
示例#4
0
文件: Options.cpp 项目: oclint/oclint
std::vector<std::string> oclint::option::rulesPath()
{
    if (argRulesPath.size() > 0)
    {
        return argRulesPath;
    }
    std::string defaultRulePath = libPath() + "/oclint/rules";
    std::vector<std::string> defaultRulesPath { defaultRulePath };
    return defaultRulesPath;
}
示例#5
0
文件: ygas.cpp 项目: 8l/yasm-nextgen
static void
ConfigureObject(Object& object)
{
    Object::Config& config = object.getConfig();

    // Walk through execstack and noexecstack in parallel, ordering by command
    // line argument position.
    unsigned int exec_pos = 0, exec_num = 0;
    unsigned int noexec_pos = 0, noexec_num = 0;
    for (;;)
    {
        if (exec_num < execstack.size())
            exec_pos = execstack.getPosition(exec_num);
        else
            exec_pos = 0;
        if (noexec_num < noexecstack.size())
            noexec_pos = noexecstack.getPosition(noexec_num);
        else
            noexec_pos = 0;

        if (exec_pos != 0 && (noexec_pos == 0 || exec_pos < noexec_pos))
        {
            // Handle exec option
            ++exec_num;
            config.ExecStack = true;
            config.NoExecStack = false;
        }
        else if (noexec_pos != 0 && (exec_pos == 0 || noexec_pos < exec_pos))
        {
            // Handle noexec option
            ++noexec_num;
            config.ExecStack = false;
            config.NoExecStack = true;
        }
        else
            break; // we're done with the list
    }
}
示例#6
0
文件: ygas.cpp 项目: 8l/yasm-nextgen
static std::string
GetBitsSetting()
{
    std::string bits = YGAS_OBJFMT_BITS;

    // Walk through bits_32 and bits_64 in parallel, ordering by command line
    // argument position.
    unsigned int bits32_pos = 0, bits32_num = 0;
    unsigned int bits64_pos = 0, bits64_num = 0;
    for (;;)
    {
        if (bits32_num < bits_32.size())
            bits32_pos = bits_32.getPosition(bits32_num);
        else
            bits32_pos = 0;
        if (bits64_num < bits_64.size())
            bits64_pos = bits_64.getPosition(bits64_num);
        else
            bits64_pos = 0;

        if (bits32_pos != 0 && (bits64_pos == 0 || bits32_pos < bits64_pos))
        {
            // Handle bits32 option
            ++bits32_num;
            bits = "32";
        }
        else if (bits64_pos != 0 &&
                 (bits32_pos == 0 || bits64_pos < bits32_pos))
        {
            // Handle bits64 option
            ++bits64_num;
            bits = "64";
        }
        else
            break; // we're done with the list
    }
    return bits;
}
示例#7
0
int main(int argc, char** argv) {
  llvm::cl::ParseCommandLineOptions(argc, argv);
  graph.structureFromFile(inputfilename);
  
  for (unsigned i = 0; i != statModeList.size(); ++i) {
    switch (statModeList[i]) {
      case summary: do_summary(); break;
      case degrees: do_degrees(); break;
      default: abort(); break;
    }
  }

  return 0;
}
示例#8
0
文件: Options.cpp 项目: oclint/oclint
void oclint::option::process(const char *argv)
{
    preserveWorkingPath();
    preserveExecutablePath(argv);

    processConfigFiles();
    for (unsigned i = 0; i < argRuleConfiguration.size(); ++i)
    {
        std::string configuration = argRuleConfiguration[i];
        int indexOfSeparator = configuration.find_last_of("=");
        std::string key = configuration.substr(0, indexOfSeparator);
        std::string value = configuration.substr(indexOfSeparator + 1,
            configuration.size() - indexOfSeparator - 1);
        consumeRuleConfiguration(key, value);
    }

    filter.enableRules(argEnabledRules.begin(), argEnabledRules.end());
    filter.disableRules(argDisabledRules.begin(), argDisabledRules.end());
}
示例#9
0
int main(int argc, char** argv) {
  llvm::llvm_shutdown_obj _ShutdownObj;
  llvm::cl::ParseCommandLineOptions(argc, argv, "P-NDK Link Tool");

  llvm::LLVMContext& Ctx = llvm::getGlobalContext();
  std::string ErrMsg;
  llvm::raw_fd_ostream FOS(OutputFilenames[0].c_str(), ErrMsg);
  assert(!FOS.has_error());

  // No need to link (just one file).
  // Output Directly.
  if (InputFilenames.size() == 1) {
    llvm::OwningPtr<llvm::Module> M(getModuleFromFilename(InputFilenames[0],
                                                           Ctx,
                                                           ErrMsg));
    llvm::WriteBitcodeToFile(M.get(), FOS);
    return 0;
  }

  llvm::OwningPtr<llvm::Module> M(linkFilesToModule(InputFilenames, Ctx));
  llvm::WriteBitcodeToFile(M.get(), FOS);
  assert(!FOS.has_error());
  return 0;
}
示例#10
0
文件: ygas.cpp 项目: 8l/yasm-nextgen
static void
ApplyWarningSettings(DiagnosticsEngine& diags)
{
    // Disable init-nobits and uninit-contents by default.
    diags.setDiagnosticGroupMapping("init-nobits", diag::MAP_IGNORE);
    diags.setDiagnosticGroupMapping("uninit-contents", diag::MAP_IGNORE);

    // Walk through inhibit_warnings, fatal_warnings, enable_warnings, and
    // no_signed_overflow in parallel, ordering by command line argument
    // position.
    unsigned int inhibit_pos = 0, inhibit_num = 0;
    unsigned int enable_pos = 0,  enable_num = 0;
    unsigned int fatal_pos = 0,   fatal_num = 0;
    unsigned int signed_pos = 0,  signed_num = 0;
    for (;;)
    {
        if (inhibit_num < inhibit_warnings.size())
            inhibit_pos = inhibit_warnings.getPosition(inhibit_num);
        else
            inhibit_pos = 0;
        if (enable_num < enable_warnings.size())
            enable_pos = enable_warnings.getPosition(enable_num);
        else
            enable_pos = 0;
        if (fatal_num < fatal_warnings.size())
            fatal_pos = fatal_warnings.getPosition(fatal_num);
        else
            fatal_pos = 0;
        if (signed_num < no_signed_overflow.size())
            signed_pos = no_signed_overflow.getPosition(signed_num);
        else
            signed_pos = 0;

        if (inhibit_pos != 0 &&
            (enable_pos == 0 || inhibit_pos < enable_pos) &&
            (fatal_pos == 0 || inhibit_pos < fatal_pos) &&
            (signed_pos == 0 || inhibit_pos < signed_pos))
        {
            // Handle inhibit option
            ++inhibit_num;
            diags.setIgnoreAllWarnings(true);
        }
        else if (enable_pos != 0 &&
                 (inhibit_pos == 0 || enable_pos < inhibit_pos) &&
                 (fatal_pos == 0 || enable_pos < fatal_pos) &&
                 (signed_pos == 0 || enable_pos < signed_pos))
        {
            // Handle enable option
            ++enable_num;
            diags.setIgnoreAllWarnings(false);
            diags.setWarningsAsErrors(false);
            diags.setDiagnosticGroupMapping("signed-overflow",
                                            diag::MAP_WARNING);
        }
        else if (fatal_pos != 0 &&
                 (enable_pos == 0 || fatal_pos < enable_pos) &&
                 (inhibit_pos == 0 || fatal_pos < inhibit_pos) &&
                 (signed_pos == 0 || fatal_pos < signed_pos))
        {
            // Handle fatal option
            ++fatal_num;
            diags.setWarningsAsErrors(true);
        }
        else if (signed_pos != 0 &&
                 (enable_pos == 0 || signed_pos < enable_pos) &&
                 (fatal_pos == 0 || signed_pos < fatal_pos) &&
                 (inhibit_pos == 0 || signed_pos < inhibit_pos))
        {
            // Handle signed option
            ++signed_num;
            diags.setDiagnosticGroupMapping("signed-overflow",
                                            diag::MAP_IGNORE);
        }
        else
            break; // we're done with the list
    }
}
示例#11
0
文件: callgraph.cpp 项目: aaasz/SHP
int main(int argc, char **argv) {
  llvm::cl::ParseCommandLineOptions(argc-2, argv, "callgraph");

  FileManager FileMgr;
  std::vector<ASTUnit*> ASTUnits;

  if (InputFilenames.empty())
    return 0;

  TextDiagnosticBuffer DiagClient;

  for (unsigned i = 0, e = InputFilenames.size(); i != e; ++i) {
    const std::string &InFile = InputFilenames[i];

    std::string ErrMsg;
    llvm::OwningPtr<ASTUnit> AST;
    clang::Diagnostic diagnostic;

    AST.reset(ASTUnit::LoadFromPCHFile(InFile,diagnostic,false,true));

    if (!AST) {
      llvm::errs() << "[" << InFile << "] error: " << ErrMsg << '\n';
      return 1;
    }

    ASTUnits.push_back(AST.take());
  }

  llvm::OwningPtr<CallGraph> CG;
  CG.reset(new CallGraph());

  for (unsigned i = 0, e = ASTUnits.size(); i != e; ++i){
    CG->addTU(ASTUnits[i]->getASTContext());

  }

  //std::cout<<"ajuns aici\n";
  std::cout<<"start = "<<argv[argc-2]<<"\n";
  std::cout<<"end = "<<argv[argc-1]<<"\n";

  std::vector<ProcessGraph *> pg1;
  for (unsigned i = 0, e = InputFilenames.size(); i != e; ++i) {
		const std::string &InFile = InputFilenames[i];
		Splitter splitter(InFile);

		// std::cout << "begin1\n";
		if (!splitter.hasErrors()) {
		//	 std::cout << "begin2\n";
			splitter.splitFiles(i == 0, i == 0 ? "hw" : "sw");
		//	 std::cout << "begin3\n";
			std::vector<ProcessGraph *> *pg = splitter.getConfigs();
			if (pg->size() != 0) {
				if (pg->size() != 1) {
					std::cout << "Error :(too many)/none config functions\n";
					exit(-1);
				}
				pg1 = *pg;
			}
			/*Partitioner p(ProcessGraph *pg, int populationSize, int maxIter,unsigned int maxLUTS,
			 unsigned int maxSLICES);
			 */

		}
		// std::cout << "end1\n";
	}


	GraphDataAppender gda(pg1[0], "/home/Silviu/workspace/big_test");
	Partitioner p(pg1[0], 400, 400,false,argv[argc-2],argv[argc-1]);
	bool *bestSolution = p.getBestSolution();
	ProcessGraph *pgc = pg1[0];
	std::cout<<pgc->getMaxLUTS()<<" "<<pgc->getMaxSLICES()<<"\n";
	for (int i=0; i<pgc->getNumVertices(); i++){
		ProcessGraphNode *pgn = pgc->lookupGraphNode(i);
		std::cout<<pgn->getName()<<":\n";
		VertexData vd = pgn->getVertexData();
		std::cout << vd.hadrwareExecutionTime << "\n";
		std::cout << vd.communicationTime << "\n";
		std::cout << vd.softwareExecutionTime << "\n";
		std::cout << vd.LUTS << "\n";
		std::cout << vd.SLICES << "\n";
	}

	std::cout<<"Solutia partitionarii:\n";
	for (int i=0; i<pgc->getNumVertices(); i++){
		std::cout<<pgc->lookupGraphNode(i)->getName()<<" :"<<(bestSolution[i] == HARDWARE ? "Hardware" : "Software") << "\n";
	}

}
示例#12
0
文件: clang-wpa.cpp 项目: CPFL/guc
int main(int argc, char **argv) {
  llvm::cl::ParseCommandLineOptions(argc, argv, "clang-wpa");
  std::vector<ASTUnit*> ASTUnits;

  Program Prog;
  Indexer Idxer(Prog);

  if (InputFilenames.empty())
    return 0;

  DiagnosticOptions DiagOpts;
  llvm::IntrusiveRefCntPtr<Diagnostic> Diags
    = CompilerInstance::createDiagnostics(DiagOpts, argc, argv);
  for (unsigned i = 0, e = InputFilenames.size(); i != e; ++i) {
    const std::string &InFile = InputFilenames[i];
    llvm::OwningPtr<ASTUnit> AST(ASTUnit::LoadFromASTFile(InFile, Diags));
    if (!AST)
      return 1;

    ASTUnits.push_back(AST.take());
  }

  if (ViewCallGraph) {
    llvm::OwningPtr<CallGraph> CG;
    CG.reset(new CallGraph(Prog));

    for (unsigned i = 0, e = ASTUnits.size(); i != e; ++i)
      CG->addTU(ASTUnits[i]->getASTContext());

    CG->ViewCallGraph();
    return 0;
  }

  if (AnalyzeFunction.empty())
    return 0;

  // Feed all ASTUnits to the Indexer.
  for (unsigned i = 0, e = ASTUnits.size(); i != e; ++i) {
    ASTUnitTU *TU = new ASTUnitTU(ASTUnits[i]);
    Idxer.IndexAST(TU);
  }

  Entity Ent = Entity::get(AnalyzeFunction, Prog);
  FunctionDecl *FD;
  TranslationUnit *TU;
  llvm::tie(FD, TU) = Idxer.getDefinitionFor(Ent);

  if (!FD)
    return 0;

  // Create an analysis engine.
  Preprocessor &PP = TU->getPreprocessor();

  // Hard code options for now.
  AnalysisManager AMgr(TU->getASTContext(), PP.getDiagnostics(),
                       PP.getLangOptions(), /* PathDiagnostic */ 0,
                       CreateRegionStoreManager,
                       CreateRangeConstraintManager, &Idxer,
                       /* MaxNodes */ 300000, /* MaxLoop */ 3,
                       /* VisualizeEG */ false, /* VisualizeEGUbi */ false,
                       /* PurgeDead */ true, /* EagerlyAssume */ false,
                       /* TrimGraph */ false, /* InlineCall */ true, 
                       /* UseUnoptimizedCFG */ false);

  GRTransferFuncs* TF = MakeCFRefCountTF(AMgr.getASTContext(), /*GC*/false,
                                         AMgr.getLangOptions());
  GRExprEngine Eng(AMgr, TF);

  Eng.ExecuteWorkList(AMgr.getStackFrame(FD, TU), AMgr.getMaxNodes());
  
  return 0;
}
示例#13
0
bool clang::ProcessWarningOptions(Diagnostic &Diags) {
  Diags.setSuppressSystemWarnings(true);  // Default to -Wno-system-headers
  Diags.setIgnoreAllWarnings(OptNoWarnings);

  // If -pedantic or -pedantic-errors was specified, then we want to map all
  // extension diagnostics onto WARNING or ERROR unless the user has futz'd
  // around with them explicitly.
  if (OptPedanticErrors)
    Diags.setExtensionHandlingBehavior(Diagnostic::Ext_Error);
  else if (OptPedantic)
    Diags.setExtensionHandlingBehavior(Diagnostic::Ext_Warn);
  else
    Diags.setExtensionHandlingBehavior(Diagnostic::Ext_Ignore);
  
  // FIXME: -Wfatal-errors / -Wfatal-errors=foo

  for (unsigned i = 0, e = OptWarnings.size(); i != e; ++i) {
    const std::string &Opt = OptWarnings[i];
    const char *OptStart = &Opt[0];
    const char *OptEnd = OptStart+Opt.size();
    assert(*OptEnd == 0 && "Expect null termination for lower-bound search");
    
    // Check to see if this warning starts with "no-", if so, this is a negative
    // form of the option.
    bool isPositive = true;
    if (OptEnd-OptStart > 3 && memcmp(OptStart, "no-", 3) == 0) {
      isPositive = false;
      OptStart += 3;
    }

    // Figure out how this option affects the warning.  If -Wfoo, map the
    // diagnostic to a warning, if -Wno-foo, map it to ignore.
    diag::Mapping Mapping = isPositive ? diag::MAP_WARNING : diag::MAP_IGNORE;

    // -Wsystem-headers is a special case, not driven by the option table.  It
    // cannot be controlled with -Werror.
    if (OptEnd-OptStart == 14 && memcmp(OptStart, "system-headers", 14) == 0) {
      Diags.setSuppressSystemWarnings(!isPositive);
      continue;
    }
    
    // -Werror/-Wno-error is a special case, not controlled by the option table.
    // It also has the "specifier" form of -Werror=foo.
    if (OptEnd-OptStart >= 5 && memcmp(OptStart, "error", 5) == 0) {
      const char *Specifier = 0;
      if (OptEnd-OptStart != 5) {  // Specifier must be present.
        if (OptStart[5] != '=' || OptEnd-OptStart == 6) {
          fprintf(stderr, "warning: unknown -Werror warning specifier: -W%s\n",
                  Opt.c_str());
          continue;
        }
        Specifier = OptStart+6;
      }
      
      if (Specifier == 0) {
        Diags.setWarningsAsErrors(true);
        continue;
      }
      
      // -Werror=foo maps foo to Error, -Wno-error=foo maps it to Warning.
      Mapping = isPositive ? diag::MAP_ERROR : diag::MAP_WARNING_NO_WERROR;
      OptStart = Specifier;
    }
    
    WarningOption Key = { OptStart, 0, 0 };
    const WarningOption *Found =
      std::lower_bound(OptionTable, OptionTable + OptionTableSize, Key,
                       WarningOptionCompare);
    if (Found == OptionTable + OptionTableSize ||
        strcmp(Found->Name, OptStart) != 0) {
      fprintf(stderr, "warning: unknown warning option: -W%s\n", Opt.c_str());
      continue;
    }
    
    MapGroupMembers(Found, Mapping, Diags);
  }
  
  return false;
}
示例#14
0
int main(int argc, char* argv[]) {
    CodeHandler::Init(argc,argv);

    // First check if the report file exists and if not create the table header
    fstream report_file;
    const char * report_file_name = (ReportFilename.size()) ? ReportFilename[0].c_str() : "report.out";
    report_file.open(report_file_name,ios::in);
    bool file_exists = report_file.is_open();
    report_file.close();

    report_file.open(report_file_name,ofstream::out | ofstream::app);
    if ( !file_exists )
        report_file << "| " << setw(15) << "Filename" << " | " <<
        setw(10) << "Domain" << " | " <<
        setw(12) << "CanonPoint" << " | " <<
        setw(15) << "CanonStrategy" << " | " <<
        setw(6) << "#Added" << " | " <<
        setw(8) << "#Deleted" << " | " <<
        setw(12) << "#DiffPoints" << " | " <<
        setw(6) << "#Diffs" << " | " <<
        setw(15) << "Optimal #Diffs" << "|\n";

    report_file << "| "<< setw(15) << InputFilename << 
    " | " << setw(10) << string(ManagerType[0]) << 
    " | " << setw(12) << string((PartitionPoint.size() > 0) ? PartitionPoint[0] : "none") << 
    " | " << setw(15) << string((PartitionStrategy.size() > 0) ? PartitionStrategy[0] : "equiv") <<
    " | ";

    string filename = InputFilename, patched_filname = PatchedFilename[0];
    // Start by guarding both files

    GuardFilename.addValue(filename);
    cout << "GuardFilename = " << GuardFilename[0] << endl;
    InputFilename = GuardFilename[0];
    UnionCompiler().GuardedInstructionsTransform();
    // Ignore this option from now own (the condition is size() == 1)
    GuardFilename.addValue("");

    GuardTaggedFilename.addValue(patched_filname);
    cout << "GuardTaggedFilename = " << GuardTaggedFilename[0] << endl;
    InputFilename = GuardTaggedFilename[0];
    UnionCompiler().GuardedInstructionsTransform();
    // Ignore this option from now own (the condition is size() == 1)
    GuardTaggedFilename.addValue("");

    // Now tag the patched file
    TagFilename.addValue(Defines::kGuardedFilenamePrefix + patched_filname);
    cout << "TagFilename = " << TagFilename[0] << endl;
    InputFilename = TagFilename[0];
    UnionCompiler().TagInstructionsTransform();
    // Ignore this option from now own (the condition is size() == 1)
    TagFilename.addValue("");

    // Now union the files
    InputFilename.setValue(Defines::kGuardedFilenamePrefix + filename);
    PatchedFilename[0] = Defines::kTaggedFilenamePrefix + Defines::kGuardedFilenamePrefix + patched_filname;
    cout << "InputFilename = " << InputFilename << ",PatchedFilename = " << PatchedFilename[0] << endl;
    UnionCompiler().UnionTransform(report_file);
    // Ignore this option from now own (the condition is size() == 1)
    PatchedFilename.addValue("");

    // Now analyze it
    InputFilename.setValue(Defines::kUnionedFilenamePrefix + filename);
    cout << "InputFilename = " << InputFilename << endl;
    Analyzer().RunAnalysis(report_file);

    report_file << setw(15) <<" |\n";
    report_file.close();

    return 0;

}