<commit_before>#include "part_data.hpp"
#include "cosmology.hpp"
#include "power.hpp"
#include "displacement.hpp"
#include "read_param.hpp"
#include "thermalvel.hpp"
#include "save.hpp"
#include <stdexcept>
#include <cassert>

int main(int argc, char **argv)
{
  if(argc < 2)
    {
	  fprintf(stdout, "\nParameters are missing.\n");
	  fprintf(stdout, "Call with <ParameterFile>\n\n");
      exit(0);
    }
  /*Make sure stdout is line buffered even when not
   * printing to a terminal but, eg, perl*/
  setlinebuf(stdout);
  //May throw std::runtime_error
  try {
  //Read the config file
  SpbConfigParser config(argv[1]);
  //Cosmological parameters
  const auto Omega = config.PopValue<double>("Omega");
  const auto OmegaLambda = config.PopValue<double>("OmegaLambda");
  const auto OmegaBaryon = config.PopValue<double>("OmegaBaryon");
  const auto HubbleParam = config.PopValue<double>("HubbleParam");
  //Which output format should we use. 4 is bigfile, 3 is HDF5, 2 is Gadget 2. Default to 3.
  const auto ICFormat = config.PopValue<int>("ICFormat", 3);
  //How many output files to use in the set
  const auto NumFiles = config.PopValue<int>("NumFiles");
  //Parameters of the simulation box
  const auto Box = config.PopValue<double>("Box");
  const auto Redshift = config.PopValue<double>("Redshift");
  const double InitTime = 1 / (1 + Redshift);
  //Size of FFT
  const size_t Nmesh = config.PopValue<int>("Nmesh");
  //Unused unless CAMB spectrum
  const auto FileWithInputSpectrum = config.PopValue<std::string>("FileWithInputSpectrum");
  const auto FileWithTransfer = config.PopValue<std::string>("FileWithTransfer");
  const auto InputSpectrum_UnitLength_in_cm = config.PopValue<double>("InputSpectrum_UnitLength_in_cm", 3.085678e24);
  //Output filenames
  const auto OutputDir = config.PopValue<std::string>("OutputDir");
  const auto FileBase = config.PopValue<std::string>("FileBase");
  //Random number seed
  const auto Seed = config.PopValue<int>("Seed");
  //Various boolean flags
  const auto ReNormalizeInputSpectrum = config.PopValue<bool>("ReNormalizeInputSpectrum", false);
  const auto RayleighScatter = config.PopValue<bool>("RayleighScatter", true);
  //Power spectrum to use. Default to CAMB
  const auto WhichSpectrum = config.PopValue<int>("WhichSpectrum", 2);
  //Is twolpt on?
  const auto twolpt = config.PopValue<bool>("TWOLPT",true);
  //Unit system
  const auto UnitLength_in_cm = config.PopValue<double>("UnitLength_in_cm", 3.085678e21);
  const auto UnitVelocity_in_cm_per_s = config.PopValue<double>("UnitVelocity_in_cm_per_s", 1e5);
  const auto UnitMass_in_g = config.PopValue<double>("UnitMass_in_g", 1.989e43);
  const double UnitTime_in_s = UnitLength_in_cm / UnitVelocity_in_cm_per_s;
  //WDM options
  bool WDM_Vtherm_On = config.PopValue<bool>("WDM_Vtherm_On",false);
  const auto WDM_PartMass_in_kev = config.PopValue<double>("WDM_PartMass_in_kev", 0);
  //Neutrino options
  //Add thermal velocities to type 2 particles
  bool NU_Vtherm_On = config.PopValue<bool>("NU_Vtherm_On",true);
  //This triggers the use of neutrinos via an altered transfer function
  //Should be on only if you are faking neutrinos by combining them with the dark matter,
  //and changing the transfer function, which is a terrible way of simulating neutrinos. So leave it off.
  const auto combined_neutrinos = config.PopValue<bool>("NU_in_DM",false);
  //Changes whether we have two heavy and one light neutrino or one heavy two light.
  //0 is 3 degenerate species, 1 is normal (two light species) and -1 is inverted (two heavy)
  const auto Hierarchy = config.PopValue<int>("Hierarchy",0);
  //If enabled, turn off radiation in the initial velocities
  const auto NoRadiation = config.PopValue<bool>("NoRadiation",false);
  //Total neutrino mass
  const auto NU_PartMass_in_ev = config.PopValue<double>("NU_PartMass_in_ev",0);
  //Parameter for the Efstathiou power spectrum. Generally does nothing.
  const auto ShapeGamma = config.PopValue<double>("ShapeGamma",0.201);
  //Needed if ReNormaliseInputSpectrum is on. Otherwise unused
  const auto PrimordialIndex = config.PopValue<double>("PrimordialIndex",1.);
  const auto Sigma8 = config.PopValue<double>("Sigma8",0.8);
  //Number of particles desired
  std::valarray<int64_t> npart((int64_t)0,(size_t)N_TYPE);
  int64_t CbRtNpart[6] = {0};
  CbRtNpart[BARYON_TYPE] = config.PopValue<int>("NBaryon", 0);
  CbRtNpart[DM_TYPE] = config.PopValue<int>("NCDM", 0);
  CbRtNpart[NEUTRINO_TYPE] = config.PopValue<int>("NNeutrino", 0);
  for(int type=0; type<N_TYPES; ++type)
      npart[type] = static_cast<int64_t>(CbRtNpart[type])*CbRtNpart[type]*CbRtNpart[type];

  printf("Particle numbers: %ld %ld %ld\n",npart[BARYON_TYPE], npart[DM_TYPE], npart[NEUTRINO_TYPE]);
  assert(npart[BARYON_TYPE] > 0 || npart[DM_TYPE] > 0 || npart[NEUTRINO_TYPE] > 0);

  if (Nmesh % 2 != 0){
    printf("Nmesh must be even or correct output is not guaranteed.\n");
    exit(1);
  }

  std::vector<std::string> unexpected = config.GetRemainingKeys();
  if(unexpected.size() > 0){
    std::cerr<<"Config file contained the following unexpected keys:"<<std::endl;
    for(auto unex: unexpected)
        std::cerr<<unex<<std::endl;
    exit(1);
  }
  DisplacementFields displace(Nmesh, Seed, Box, twolpt);
  /*Set particle numbers*/
  if(npart.sum() == 0)
          exit(1);
  //Make a cosmology
  Cosmology cosmo(HubbleParam, Omega, OmegaLambda, NU_PartMass_in_ev, Hierarchy, NoRadiation);
  //Initialise a power spectrum
  PowerSpec * PSpec;
  switch(WhichSpectrum)
  {
      case 1:
            PSpec = new PowerSpec_EH(HubbleParam, Omega, OmegaBaryon, UnitLength_in_cm);
            break;
      case 2:
            PSpec = new PowerSpec_Tabulated(FileWithTransfer, FileWithInputSpectrum, Omega, OmegaLambda, OmegaBaryon, cosmo.OmegaNu(1),InputSpectrum_UnitLength_in_cm, UnitLength_in_cm, !npart[BARYON_TYPE], combined_neutrinos);
            break;
      default:
            PSpec = new PowerSpec_Efstathiou(ShapeGamma, UnitLength_in_cm);
  }

  //If normalisation or WDM are on, decorate the base power spectrum
  //to do that
  if (ReNormalizeInputSpectrum) {
      double Dplus = cosmo.GrowthFactor(InitTime, 1.0);
      printf("Growth factor to z=0: %g \n", Dplus);
      PSpec = new NormalizedPowerSpec(PSpec, Sigma8, PrimordialIndex, Dplus, UnitLength_in_cm);
  }
  if(WDM_Vtherm_On)
      PSpec = new WDMPowerSpec(PSpec, WDM_PartMass_in_kev, Omega, OmegaBaryon, HubbleParam, UnitLength_in_cm);

  std::string extension("");
  if (ICFormat > 4 || ICFormat < 2) {
          fprintf(stderr, "Supported ICFormats:\n 2: Gadget 2 format files\n 3: HDF5\n 4: BigFile\n");
          exit(1);
  }
  if (ICFormat == 3){
      printf("Outputting HDF5 ICs\n");
      extension=".hdf5";
  }
  GadgetWriter::GWriteBaseSnap *osnap;
#ifdef HAVE_BGFL
  if(ICFormat == 4) {
     osnap = new GadgetWriter::GWriteBigSnap(OutputDir+std::string("/")+FileBase+extension, npart, NumFiles);
  }
  else
#endif
  osnap = new GadgetWriter::GWriteSnap(OutputDir+std::string("/")+FileBase+extension, npart,NumFiles, sizeof(id_type));
  assert(osnap);
  /*Write headers*/
  gadget_header header = generate_header(npart, Omega, OmegaBaryon, cosmo.OmegaNu(1), OmegaLambda, HubbleParam, Box, InitTime, UnitMass_in_g, UnitLength_in_cm, UnitVelocity_in_cm_per_s, combined_neutrinos);

  //Generate regular particle grid
  part_grid Pgrid(CbRtNpart, header.mass, Box);

  if(osnap->WriteHeaders(header)) {
      fprintf(stderr, "Could not write headers to snapshot\n");
      exit(1);
  }

  int64_t FirstId=1;
  //Compute the factors to go from velocity to displacement
  const double hubble_a = cosmo.Hubble(InitTime)*UnitTime_in_s;
  const double vel_prefac = InitTime * hubble_a * cosmo.F_Omega(InitTime) /sqrt(InitTime);
  //Only used if twolpt is on
  //This is slightly approximate: we are assuming that D2 ~ -3/7 Da^2 Omega_m^{-1/143} (Bouchet, F 1995, A&A 296)
  const double vel_prefac2 = -3./7.*pow(Omega, -1./143)*InitTime * hubble_a * cosmo.F2_Omega(InitTime) /sqrt(InitTime);
  printf("vel_prefac= %g  hubble_a=%g fom=%g Omega=%g \n", vel_prefac, hubble_a, cosmo.F_Omega(InitTime), Omega);

  for(int type=0; type<N_TYPE;type++){
      if(npart[type] == 0)
              continue;
      FermiDiracVel * therm_vels = NULL;
      //For WDM thermal velocities
      if(WDM_Vtherm_On && type == 1){
        const double wdm_vth = WDM_V0(Redshift, WDM_PartMass_in_kev, Omega-OmegaBaryon, HubbleParam, UnitVelocity_in_cm_per_s);
        therm_vels = new FermiDiracVel (wdm_vth);
        printf("\nWarm dark matter rms velocity dispersion at starting redshift = %g km/sec\n\n",3.59714 * wdm_vth);
      }
      //Neutrino thermal velocities
      if(NU_Vtherm_On && type == 2) {
          //Init structure for neutrino velocities
          const double v_th = NU_V0(Redshift, NU_PartMass_in_ev, UnitVelocity_in_cm_per_s);
          therm_vels = new FermiDiracVel (v_th);
          printf("\nNeutrino rms vel. dispersion %g (km/s)\n\n",v_th/sqrt(1+Redshift));
      }
      lpt_data outdata = displace.displacement_fields(type, Pgrid, PSpec, RayleighScatter);
      outdata.SetVelPrefac(vel_prefac, vel_prefac2);
      FirstId = write_particle_data(*osnap, type,&outdata, Pgrid, therm_vels, FirstId);
      delete therm_vels;
  }

    delete PSpec;
  printf("Initial scale factor = %g\n", InitTime);

  }
  catch(std::ios_base::failure& e) {
      std::cerr<<e.what();
      return 4;
  }
  catch(std::runtime_error& e) {
      std::cerr<<e.what();
      return 1;
  }
  catch(std::invalid_argument& e) {
      std::cerr<<e.what();
      return 2;
  }
  catch(std::domain_error& e) {
      std::cerr<<e.what();
      return 3;
  }
  return 0;
}
<commit_msg>Free memory to prevent leak<commit_after>#include "part_data.hpp"
#include "cosmology.hpp"
#include "power.hpp"
#include "displacement.hpp"
#include "read_param.hpp"
#include "thermalvel.hpp"
#include "save.hpp"
#include <stdexcept>
#include <cassert>

int main(int argc, char **argv)
{
  if(argc < 2)
    {
	  fprintf(stdout, "\nParameters are missing.\n");
	  fprintf(stdout, "Call with <ParameterFile>\n\n");
      exit(0);
    }
  /*Make sure stdout is line buffered even when not
   * printing to a terminal but, eg, perl*/
  setlinebuf(stdout);
  //May throw std::runtime_error
  try {
  //Read the config file
  SpbConfigParser config(argv[1]);
  //Cosmological parameters
  const auto Omega = config.PopValue<double>("Omega");
  const auto OmegaLambda = config.PopValue<double>("OmegaLambda");
  const auto OmegaBaryon = config.PopValue<double>("OmegaBaryon");
  const auto HubbleParam = config.PopValue<double>("HubbleParam");
  //Which output format should we use. 4 is bigfile, 3 is HDF5, 2 is Gadget 2. Default to 3.
  const auto ICFormat = config.PopValue<int>("ICFormat", 3);
  //How many output files to use in the set
  const auto NumFiles = config.PopValue<int>("NumFiles");
  //Parameters of the simulation box
  const auto Box = config.PopValue<double>("Box");
  const auto Redshift = config.PopValue<double>("Redshift");
  const double InitTime = 1 / (1 + Redshift);
  //Size of FFT
  const size_t Nmesh = config.PopValue<int>("Nmesh");
  //Unused unless CAMB spectrum
  const auto FileWithInputSpectrum = config.PopValue<std::string>("FileWithInputSpectrum");
  const auto FileWithTransfer = config.PopValue<std::string>("FileWithTransfer");
  const auto InputSpectrum_UnitLength_in_cm = config.PopValue<double>("InputSpectrum_UnitLength_in_cm", 3.085678e24);
  //Output filenames
  const auto OutputDir = config.PopValue<std::string>("OutputDir");
  const auto FileBase = config.PopValue<std::string>("FileBase");
  //Random number seed
  const auto Seed = config.PopValue<int>("Seed");
  //Various boolean flags
  const auto ReNormalizeInputSpectrum = config.PopValue<bool>("ReNormalizeInputSpectrum", false);
  const auto RayleighScatter = config.PopValue<bool>("RayleighScatter", true);
  //Power spectrum to use. Default to CAMB
  const auto WhichSpectrum = config.PopValue<int>("WhichSpectrum", 2);
  //Is twolpt on?
  const auto twolpt = config.PopValue<bool>("TWOLPT",true);
  //Unit system
  const auto UnitLength_in_cm = config.PopValue<double>("UnitLength_in_cm", 3.085678e21);
  const auto UnitVelocity_in_cm_per_s = config.PopValue<double>("UnitVelocity_in_cm_per_s", 1e5);
  const auto UnitMass_in_g = config.PopValue<double>("UnitMass_in_g", 1.989e43);
  const double UnitTime_in_s = UnitLength_in_cm / UnitVelocity_in_cm_per_s;
  //WDM options
  bool WDM_Vtherm_On = config.PopValue<bool>("WDM_Vtherm_On",false);
  const auto WDM_PartMass_in_kev = config.PopValue<double>("WDM_PartMass_in_kev", 0);
  //Neutrino options
  //Add thermal velocities to type 2 particles
  bool NU_Vtherm_On = config.PopValue<bool>("NU_Vtherm_On",true);
  //This triggers the use of neutrinos via an altered transfer function
  //Should be on only if you are faking neutrinos by combining them with the dark matter,
  //and changing the transfer function, which is a terrible way of simulating neutrinos. So leave it off.
  const auto combined_neutrinos = config.PopValue<bool>("NU_in_DM",false);
  //Changes whether we have two heavy and one light neutrino or one heavy two light.
  //0 is 3 degenerate species, 1 is normal (two light species) and -1 is inverted (two heavy)
  const auto Hierarchy = config.PopValue<int>("Hierarchy",0);
  //If enabled, turn off radiation in the initial velocities
  const auto NoRadiation = config.PopValue<bool>("NoRadiation",false);
  //Total neutrino mass
  const auto NU_PartMass_in_ev = config.PopValue<double>("NU_PartMass_in_ev",0);
  //Parameter for the Efstathiou power spectrum. Generally does nothing.
  const auto ShapeGamma = config.PopValue<double>("ShapeGamma",0.201);
  //Needed if ReNormaliseInputSpectrum is on. Otherwise unused
  const auto PrimordialIndex = config.PopValue<double>("PrimordialIndex",1.);
  const auto Sigma8 = config.PopValue<double>("Sigma8",0.8);
  //Number of particles desired
  std::valarray<int64_t> npart((int64_t)0,(size_t)N_TYPE);
  int64_t CbRtNpart[6] = {0};
  CbRtNpart[BARYON_TYPE] = config.PopValue<int>("NBaryon", 0);
  CbRtNpart[DM_TYPE] = config.PopValue<int>("NCDM", 0);
  CbRtNpart[NEUTRINO_TYPE] = config.PopValue<int>("NNeutrino", 0);
  for(int type=0; type<N_TYPES; ++type)
      npart[type] = static_cast<int64_t>(CbRtNpart[type])*CbRtNpart[type]*CbRtNpart[type];

  printf("Particle numbers: %ld %ld %ld\n",npart[BARYON_TYPE], npart[DM_TYPE], npart[NEUTRINO_TYPE]);
  assert(npart[BARYON_TYPE] > 0 || npart[DM_TYPE] > 0 || npart[NEUTRINO_TYPE] > 0);

  if (Nmesh % 2 != 0){
    printf("Nmesh must be even or correct output is not guaranteed.\n");
    exit(1);
  }

  std::vector<std::string> unexpected = config.GetRemainingKeys();
  if(unexpected.size() > 0){
    std::cerr<<"Config file contained the following unexpected keys:"<<std::endl;
    for(auto unex: unexpected)
        std::cerr<<unex<<std::endl;
    exit(1);
  }
  DisplacementFields displace(Nmesh, Seed, Box, twolpt);
  /*Set particle numbers*/
  if(npart.sum() == 0)
          exit(1);
  //Make a cosmology
  Cosmology cosmo(HubbleParam, Omega, OmegaLambda, NU_PartMass_in_ev, Hierarchy, NoRadiation);
  //Initialise a power spectrum
  PowerSpec * PSpec;
  switch(WhichSpectrum)
  {
      case 1:
            PSpec = new PowerSpec_EH(HubbleParam, Omega, OmegaBaryon, UnitLength_in_cm);
            break;
      case 2:
            PSpec = new PowerSpec_Tabulated(FileWithTransfer, FileWithInputSpectrum, Omega, OmegaLambda, OmegaBaryon, cosmo.OmegaNu(1),InputSpectrum_UnitLength_in_cm, UnitLength_in_cm, !npart[BARYON_TYPE], combined_neutrinos);
            break;
      default:
            PSpec = new PowerSpec_Efstathiou(ShapeGamma, UnitLength_in_cm);
  }

  //If normalisation or WDM are on, decorate the base power spectrum
  //to do that
  if (ReNormalizeInputSpectrum) {
      double Dplus = cosmo.GrowthFactor(InitTime, 1.0);
      printf("Growth factor to z=0: %g \n", Dplus);
      PSpec = new NormalizedPowerSpec(PSpec, Sigma8, PrimordialIndex, Dplus, UnitLength_in_cm);
  }
  if(WDM_Vtherm_On)
      PSpec = new WDMPowerSpec(PSpec, WDM_PartMass_in_kev, Omega, OmegaBaryon, HubbleParam, UnitLength_in_cm);

  std::string extension("");
  if (ICFormat > 4 || ICFormat < 2) {
          fprintf(stderr, "Supported ICFormats:\n 2: Gadget 2 format files\n 3: HDF5\n 4: BigFile\n");
          exit(1);
  }
  if (ICFormat == 3){
      printf("Outputting HDF5 ICs\n");
      extension=".hdf5";
  }
  GadgetWriter::GWriteBaseSnap *osnap;
#ifdef HAVE_BGFL
  if(ICFormat == 4) {
     osnap = new GadgetWriter::GWriteBigSnap(OutputDir+std::string("/")+FileBase+extension, npart, NumFiles);
  }
  else
#endif
  osnap = new GadgetWriter::GWriteSnap(OutputDir+std::string("/")+FileBase+extension, npart,NumFiles, sizeof(id_type));
  assert(osnap);
  /*Write headers*/
  gadget_header header = generate_header(npart, Omega, OmegaBaryon, cosmo.OmegaNu(1), OmegaLambda, HubbleParam, Box, InitTime, UnitMass_in_g, UnitLength_in_cm, UnitVelocity_in_cm_per_s, combined_neutrinos);

  //Generate regular particle grid
  part_grid Pgrid(CbRtNpart, header.mass, Box);

  if(osnap->WriteHeaders(header)) {
      fprintf(stderr, "Could not write headers to snapshot\n");
      exit(1);
  }

  int64_t FirstId=1;
  //Compute the factors to go from velocity to displacement
  const double hubble_a = cosmo.Hubble(InitTime)*UnitTime_in_s;
  const double vel_prefac = InitTime * hubble_a * cosmo.F_Omega(InitTime) /sqrt(InitTime);
  //Only used if twolpt is on
  //This is slightly approximate: we are assuming that D2 ~ -3/7 Da^2 Omega_m^{-1/143} (Bouchet, F 1995, A&A 296)
  const double vel_prefac2 = -3./7.*pow(Omega, -1./143)*InitTime * hubble_a * cosmo.F2_Omega(InitTime) /sqrt(InitTime);
  printf("vel_prefac= %g  hubble_a=%g fom=%g Omega=%g \n", vel_prefac, hubble_a, cosmo.F_Omega(InitTime), Omega);

  for(int type=0; type<N_TYPE;type++){
      if(npart[type] == 0)
              continue;
      FermiDiracVel * therm_vels = NULL;
      //For WDM thermal velocities
      if(WDM_Vtherm_On && type == 1){
        const double wdm_vth = WDM_V0(Redshift, WDM_PartMass_in_kev, Omega-OmegaBaryon, HubbleParam, UnitVelocity_in_cm_per_s);
        therm_vels = new FermiDiracVel (wdm_vth);
        printf("\nWarm dark matter rms velocity dispersion at starting redshift = %g km/sec\n\n",3.59714 * wdm_vth);
      }
      //Neutrino thermal velocities
      if(NU_Vtherm_On && type == 2) {
          //Init structure for neutrino velocities
          const double v_th = NU_V0(Redshift, NU_PartMass_in_ev, UnitVelocity_in_cm_per_s);
          therm_vels = new FermiDiracVel (v_th);
          printf("\nNeutrino rms vel. dispersion %g (km/s)\n\n",v_th/sqrt(1+Redshift));
      }
      lpt_data outdata = displace.displacement_fields(type, Pgrid, PSpec, RayleighScatter);
      outdata.SetVelPrefac(vel_prefac, vel_prefac2);
      FirstId = write_particle_data(*osnap, type,&outdata, Pgrid, therm_vels, FirstId);
      delete therm_vels;
  }

    delete osnap;
    delete PSpec;
  printf("Initial scale factor = %g\n", InitTime);

  }
  catch(std::ios_base::failure& e) {
      std::cerr<<e.what();
      return 4;
  }
  catch(std::runtime_error& e) {
      std::cerr<<e.what();
      return 1;
  }
  catch(std::invalid_argument& e) {
      std::cerr<<e.what();
      return 2;
  }
  catch(std::domain_error& e) {
      std::cerr<<e.what();
      return 3;
  }
  return 0;
}
<|endoftext|>


<commit_before>//使用链表存储相应所有正在计算的task，按用户分队列计算，每0.1s进行一次检查操作，如果发现任务已完成，则调用下一任务，如如发现任务如果发现请求资源不够，则调用扩展资源函数，如果发现当前资源利用率小于50%,调用资源减少函数

#include <iostream>
#include </usr/include/mysql/mysql.h>
//#include <sql/mysql.h>
#include <cstdio>
#include <cstdlib>
#include <unistd.h>
#include <ctime>
#include <list>

using namespace std;
int totalcores;
int cores_available;
class calc_task;
list<calc_task> task_list;
int user_list[2048];//to simplify, as a demo, we think that our user amount won't be more than 2048
int user_numb;
std::list<calc_task>::iterator it1;

#define MTASK_WAITTING  0
#define MTASK_RUNNING   1
#define MTASK_KILLED    3
#define MTASK_ABORTED  -1
#define MTASK_FINISHED  2
#define MTASK_AHEADED   5
#define MTASK_HANGUP    6

#define MPROG_RUN       1
#define MPROG_KILL      2
#define MPROG_PACK      3
#define MPROG_FINISH    4

#define enlarge() cores_available=totalcores;//improve later
#define reduce();//cores_availabe=( (cores_available/2) > totalcores)? cores_available/2 :totalcores;

class calc_task{

    pid_t pid;
    int start_time;
    int finish_time;
    FILE *nutdf;
public:
    int status;//构造时设为MTASK_WAITTING
    int serial;
    int task_mark;
    //int predict_time;
    int cores;
    int time;
    int type;
    char name[1024];
    int user;

#define paraset(a) user_list[this->user] a 1;totalcores a this->cores;
    int change_task_status(int i)
    {
        //this requires sql;!!!!
    }
    int getcmd(int type,char *cmd)
    {
        //this program will run another programs(not the qe itself),the program will detect if the qe normally exited or not.
        //char ...;//system settings...
        switch(type)
        {
            case MPROG_RUN:     ;break;
            case MPROG_KILL:    ;break;
            case MPROG_PACK:    ;break;
            case MPROG_FINISH:  ;break;
        }
    }
    int start()
    {
        char cmd[1024];
        nutdf=popen("/usr/bin/nut","w");
        //submit message to the nut deamon.
        fprintf(nutdf,"%ld%ld%ld%ld\n",this->type,this->cores,this->serial);
        fflush(nutdf);
        //
       // this->start_time=time(0);
        paraset(+=);
        if(cores_available<totalcores)
        {
            enlarge();
        }
        this->change_task_status(MTASK_RUNNING);
    //attention:finish function is runing in the main program!
    }
    int kill()
    {
        char cmd[1024];
        //submit
        fprintf(nutdf,"c\n");
        fflush(nutdf);
        //
        paraset(-=);
        this->change_task_status(MTASK_KILLED);
        this->clean();
    }
    int unexpectabort()
    {
        paraset(-=);
        this->change_task_status(MTASK_ABORTED);
    }
    int finish()
    {
        this->clean();
        this->pack();

        this->time=this->finish_time-this->start_time;
        this->change_task_status(MTASK_FINISHED);
    }
    int pack()
    {
        //nutdeamon will finish the first step of package
        char cmd[1024];
        this->getcmd(MPROG_PACK,cmd);
        //popen("");//unfinished
    }
    int clean()
    {
        ;//this function will be written later.
    }
};

//this requires sql;
//check_finished should be earlier running than this function.
//check the current user mount, and how many users requires the calculating now.
//build a chain list for each "live" user's current task and insert the current possible task for each user,then running it.
//attention! there may will be a delay between the database server and the calculating server.
//if resources are limited, expand,or, if current resources available is 50% percent more than the resources used, call reduce function.
int get_current_task(MYSQL *mysqldb)
{
    int i;
    char sql_cmd[2048];
    list<calc_task> task_require;
    calc_task ttask;
    MYSQL_RES *sql_result;
    MYSQL_ROW *sql_result_row;
    MYSQL_FIELD *sql_result_field;
    //std::list<calc_task>::iterator it2;
    //...
    //first, any user should have at least one task running immediately after submit,
    //and it should follow the submit order.
    //second, if their is any extra cores, first, we should finish the works. if their is no extra work(all work finished, be careful), call the reduce function.
    //首先，轮询当前任务已完成的用户（user_list[i]=0）
        ///add into task_require;
        for(i=1;i<user_numb;i++)
        {
            if(user_list[i])
                continue;
            sprintf(sql_cmd,"SELECT TOP 0 * FROM task_list where user=%ld\
 and cancel_state=0 and (running_state=%ld or running_state=%ld)",i,MTASK_WAITTING,MTASK_HANGUP);
            mysql_query(mysqldb,sql_cmd);
            sql_result=mysql_store_result(mysqldb);
            sql_result_row=mysql_fetch_row(sql_result);
            ///...
            sscanf(sql_result_row[1],"%ld%ld%ld%ld",&(ttask.serial),&(ttask.user),&ttask.cores);//this has some problem
            ttask.type=1;
            ttask.start();
            task_list.push_back(task);
            mysql_free_result(sql_result);
        }
        //有机会的话重构这一段
        //for(it1=task_require.begin();it1!=task_require.end();it1++)
       // {
        //    it1->start();
       //     task_list.push_back(*it1);
       // }
       // task_require.clear();
        //--
    if(totalcores<cores_available)
    {
        while(totalcores<cores_available)
        {
                //int task_added=0;
                sprintf(sql_cmd,"SELECT * FROM task_list where\
 and cancel_state=0 and (running_state=%ld or running_state=%ld)\
 and cores<%ld",i,MTASK_WAITTING,MTASK_HANGUP,cores_available-totalcores);
                mysql_query(mysqldb,sql_cmd);
                sql_result=mysql_store_result(mysqldb);
                sql_result_row=mysql_fetch_row(sql_result);

                sscanf(sql_result_row[1],"%ld%ld%ld%ld",&(ttask.serial),&(ttask.user),&ttask.cores);//this has some problem
                ttask.type=1;
                ttask.start();
                task_list.push_back(task);
                mysql_free_result(sql_result);

                //如有空余资源，首先轮询所有可能任务并加入
                //有机会的话重构这一段
               // for(it1=task_require.begin();it1!=task_require.end();it1++)
                {
                  //  it1->start();
                   // task_list.push_back(*it1);
                   // task_added++;
                }
                task_require.clear();
                //--
        }
            while(totalcores<cores_available)
            {
                sprintf(sql_cmd,"SELECT TOP 10 * FROM task_list where user=%ld and cancel_state=0 and running_state=%ld",i,MTASK_WAITTING);
                mysql_query(mysqldb,sql_cmd);
                sql_result=mysql_store_result(mysqldb);
                int i;
                while(sql_result_row=mysql_fetch_row(sql_result)&&totalcores<cores_available)
                {
                    sscanf(sql_result_ro2w[1],"%ld%ld%ld%ld",&(ttask.serial),&(ttask.user),&ttask.cores);//this has some problem;
                    ttask.start();
                    task_list.push_back(task);
                }
                mysql_free_result(sql_result);
        //如有空余资源，首先轮询所有可能任务并加入
            //有机会的话重构这一段
            }
            //--
        //如发现无任务可加入，检查是否需要缩减资源开销
        if(cores_available/2>totalcores)
        {
            reduce();
            break;
        }
    }

}

//check if there is a finished/aborted/wait_to_be_killed(!this is different with MTASK_KILLED state) program.(the aborted program will have a "failed" file)
//finish all the things should do, after that, the get_current_task() will wipe out the task variables.
int check_if_finished(MYSQL &mysqldb)
{

    //task_list *tp,*tpp;
   char s[2048],cmd[2048];
    FILE *t;
    int i,finish_type,leaf=0;
    //std::list<calc_task>::iterator it2;

    for(it1=task_list.begin();it1!=task_list.end();it1++)
   // tpp=&task_list_header;//header(the first guy in the list) will not storage the real task. because it sould not be changed.
   // while(tp=enum_task(tpp))
    {
        sprintf(s,"//tmp//nutd//%ld.finish",it1->serial);
        if(t=fopen(s,"r"))

        {
            leaf=1;
            //it means that the nut has already finished
            fscanf(t,"%d",&finish_type);
            fclose(t);
            switch(finish_type)
            {
                case MTASK_ABORTED:it1->unexpectabort();break;
                case MTASK_FINISHED:it1->finish();break;
            }
            it1->finish();
            task_list.erase(it1);
        }
      //  else tpp=tp;
    }

    //停止所有waitting_to_be_cancelled 任务。首先检测任务是否已经开始，是否已经结束，然后...
    //wait_to_be_cancelled 与运行状态属于两个字段，不阻塞
    //
    //查出所有已经运行了的需要取消的任务
     sprintf(sql_cmd,"SELECT * FROM task_list where\
 and cancel_state=1 and running_state=%ld or running_state=%ld)"
 ,i,MTASK_WAITTING,MTASK_HANGUP);
    mysql_query(mysqldb,sql_cmd);
    sql_result=mysql_store_result(mysqldb);
    sql_result_row=mysql_fetch_row(sql_result);
    ///...

    //查出所有未运行需要取消的任务
    sprintf(sql_cmd,"SELECT * FROM task_list where\
 and cancel_state=1 and running_state=%ld or running_state=%ld)"
 ,i,MTASK_WAITTING,MTASK_HANGUP);
    mysql_query(mysqldb,sql_cmd);
    sql_result=mysql_store_result(mysqldb);
    sql_result_row=mysql_fetch_row(sql_result);
    //...

    return leaf;
}

int main(int argc, char **argv)
{
    int i;

    const char *host = "localhost";
    const char *user = "root";
    const char *pass = "123456";
    const char *db   = "test";

    MYSQL mysqldb;
    MYSQL_RES *result;
    MYSQL_ROW sql_row;
    MYSQL_FIELD *fd;

    mysql_init(&mysqldb);

    if (!mysql_real_connect(&mysqldb, host, user, pass, db, 0, NULL, 0))
    {
        printf("%s", mysql_error(&mysqldb));
    }
    while(1)
    {
        sleep(1000);
        if(check_if_finished(&mysqldb))
            get_current_task(&mysqldb);
    }
   // printf("HelloWorld!");
    return 0;
}

<commit_msg>change the dir in the string of main<commit_after>//使用链表存储相应所有正在计算的task，按用户分队列计算，每0.1s进行一次检查操作，如果发现任务已完成，则调用下一任务，如如发现任务如果发现请求资源不够，则调用扩展资源函数，如果发现当前资源利用率小于50%,调用资源减少函数

#include <iostream>
#include </usr/include/mysql/mysql.h>
//#include <sql/mysql.h>
#include <cstdio>
#include <cstdlib>
#include <unistd.h>
#include <ctime>
#include <list>

using namespace std;
int totalcores;
int cores_available;
class calc_task;
list<calc_task> task_list;
int user_list[2048];//to simplify, as a demo, we think that our user amount won't be more than 2048
int user_numb;
std::list<calc_task>::iterator it1;

#define MTASK_WAITTING  0
#define MTASK_RUNNING   1
#define MTASK_KILLED    3
#define MTASK_ABORTED  -1
#define MTASK_FINISHED  2
#define MTASK_AHEADED   5
#define MTASK_HANGUP    6

#define MPROG_RUN       1
#define MPROG_KILL      2
#define MPROG_PACK      3
#define MPROG_FINISH    4

#define enlarge() cores_available=totalcores;//improve later
#define reduce();//cores_availabe=( (cores_available/2) > totalcores)? cores_available/2 :totalcores;

class calc_task{

    pid_t pid;
    int start_time;
    int finish_time;
    FILE *nutdf;
public:
    int status;//构造时设为MTASK_WAITTING
    int serial;
    int task_mark;
    //int predict_time;
    int cores;
    int time;
    int type;
    char name[1024];
    int user;

#define paraset(a) user_list[this->user] a 1;totalcores a this->cores;
    int change_task_status(int i)
    {
        //this requires sql;!!!!
    }
    int getcmd(int type,char *cmd)
    {
        //this program will run another programs(not the qe itself),the program will detect if the qe normally exited or not.
        //char ...;//system settings...
        switch(type)
        {
            case MPROG_RUN:     ;break;
            case MPROG_KILL:    ;break;
            case MPROG_PACK:    ;break;
            case MPROG_FINISH:  ;break;
        }
    }
    int start()
    {
        char cmd[1024];
        nutdf=popen("/usr/bin/nut","w");
        //submit message to the nut deamon.
        fprintf(nutdf,"%ld%ld%ld%ld\n",this->type,this->cores,this->serial);
        fflush(nutdf);
        //
       // this->start_time=time(0);
        paraset(+=);
        if(cores_available<totalcores)
        {
            enlarge();
        }
        this->change_task_status(MTASK_RUNNING);
    //attention:finish function is runing in the main program!
    }
    int kill()
    {
        char cmd[1024];
        //submit
        fprintf(nutdf,"c\n");
        fflush(nutdf);
        //
        paraset(-=);
        this->change_task_status(MTASK_KILLED);
        this->clean();
    }
    int unexpectabort()
    {
        paraset(-=);
        this->change_task_status(MTASK_ABORTED);
    }
    int finish()
    {
        this->clean();
        this->pack();

        this->time=this->finish_time-this->start_time;
        this->change_task_status(MTASK_FINISHED);
    }
    int pack()
    {
        //nutdeamon will finish the first step of package
        char cmd[1024];
        this->getcmd(MPROG_PACK,cmd);
        //popen("");//unfinished
    }
    int clean()
    {
        ;//this function will be written later.
    }
};

//this requires sql;
//check_finished should be earlier running than this function.
//check the current user mount, and how many users requires the calculating now.
//build a chain list for each "live" user's current task and insert the current possible task for each user,then running it.
//attention! there may will be a delay between the database server and the calculating server.
//if resources are limited, expand,or, if current resources available is 50% percent more than the resources used, call reduce function.
int get_current_task(MYSQL *mysqldb)
{
    int i;
    char sql_cmd[2048];
    list<calc_task> task_require;
    calc_task ttask;
    MYSQL_RES *sql_result;
    MYSQL_ROW *sql_result_row;
    MYSQL_FIELD *sql_result_field;
    //std::list<calc_task>::iterator it2;
    //...
    //first, any user should have at least one task running immediately after submit,
    //and it should follow the submit order.
    //second, if their is any extra cores, first, we should finish the works. if their is no extra work(all work finished, be careful), call the reduce function.
    //首先，轮询当前任务已完成的用户（user_list[i]=0）
        ///add into task_require;
        for(i=1;i<user_numb;i++)
        {
            if(user_list[i])
                continue;
            sprintf(sql_cmd,"SELECT TOP 0 * FROM task_list where user=%ld\
 and cancel_state=0 and (running_state=%ld or running_state=%ld)",i,MTASK_WAITTING,MTASK_HANGUP);
            mysql_query(mysqldb,sql_cmd);
            sql_result=mysql_store_result(mysqldb);
            sql_result_row=mysql_fetch_row(sql_result);
            ///...
            sscanf(sql_result_row[1],"%ld%ld%ld%ld",&(ttask.serial),&(ttask.user),&ttask.cores);//this has some problem
            ttask.type=1;
            ttask.start();
            task_list.push_back(task);
            mysql_free_result(sql_result);
        }
        //有机会的话重构这一段
        //for(it1=task_require.begin();it1!=task_require.end();it1++)
       // {
        //    it1->start();
       //     task_list.push_back(*it1);
       // }
       // task_require.clear();
        //--
    if(totalcores<cores_available)
    {
        while(totalcores<cores_available)
        {
                //int task_added=0;
                sprintf(sql_cmd,"SELECT * FROM task_list where\
 and cancel_state=0 and (running_state=%ld or running_state=%ld)\
 and cores<%ld",i,MTASK_WAITTING,MTASK_HANGUP,cores_available-totalcores);
                mysql_query(mysqldb,sql_cmd);
                sql_result=mysql_store_result(mysqldb);
                sql_result_row=mysql_fetch_row(sql_result);

                sscanf(sql_result_row[1],"%ld%ld%ld%ld",&(ttask.serial),&(ttask.user),&ttask.cores);//this has some problem
                ttask.type=1;
                ttask.start();
                task_list.push_back(task);
                mysql_free_result(sql_result);

                //如有空余资源，首先轮询所有可能任务并加入
                //有机会的话重构这一段
               // for(it1=task_require.begin();it1!=task_require.end();it1++)
                {
                  //  it1->start();
                   // task_list.push_back(*it1);
                   // task_added++;
                }
                task_require.clear();
                //--
        }
            while(totalcores<cores_available)
            {
                sprintf(sql_cmd,"SELECT TOP 10 * FROM task_list where user=%ld and cancel_state=0 and running_state=%ld",i,MTASK_WAITTING);
                mysql_query(mysqldb,sql_cmd);
                sql_result=mysql_store_result(mysqldb);
                int i;
                while(sql_result_row=mysql_fetch_row(sql_result)&&totalcores<cores_available)
                {
                    sscanf(sql_result_ro2w[1],"%ld%ld%ld%ld",&(ttask.serial),&(ttask.user),&ttask.cores);//this has some problem;
                    ttask.start();
                    task_list.push_back(task);
                }
                mysql_free_result(sql_result);
        //如有空余资源，首先轮询所有可能任务并加入
            //有机会的话重构这一段
            }
            //--
        //如发现无任务可加入，检查是否需要缩减资源开销
        if(cores_available/2>totalcores)
        {
            reduce();
            break;
        }
    }

}

//check if there is a finished/aborted/wait_to_be_killed(!this is different with MTASK_KILLED state) program.(the aborted program will have a "failed" file)
//finish all the things should do, after that, the get_current_task() will wipe out the task variables.
int check_if_finished(MYSQL &mysqldb)
{

    //task_list *tp,*tpp;
   char s[2048],cmd[2048];
    FILE *t;
    int i,finish_type,leaf=0;
    //std::list<calc_task>::iterator it2;

    for(it1=task_list.begin();it1!=task_list.end();it1++)
   // tpp=&task_list_header;//header(the first guy in the list) will not storage the real task. because it sould not be changed.
   // while(tp=enum_task(tpp))
    {
        sprintf(s,"/tmp/nutd/%ld.finish",it1->serial);
        if(t=fopen(s,"r"))

        {
            leaf=1;
            //it means that the nut has already finished
            fscanf(t,"%d",&finish_type);
            fclose(t);
            switch(finish_type)
            {
                case MTASK_ABORTED:it1->unexpectabort();break;
                case MTASK_FINISHED:it1->finish();break;
            }
            it1->finish();
            task_list.erase(it1);
        }
      //  else tpp=tp;
    }

    //停止所有waitting_to_be_cancelled 任务。首先检测任务是否已经开始，是否已经结束，然后...
    //wait_to_be_cancelled 与运行状态属于两个字段，不阻塞
    //
    //查出所有已经运行了的需要取消的任务
     sprintf(sql_cmd,"SELECT * FROM task_list where\
 and cancel_state=1 and running_state=%ld or running_state=%ld)"
 ,i,MTASK_WAITTING,MTASK_HANGUP);
    mysql_query(mysqldb,sql_cmd);
    sql_result=mysql_store_result(mysqldb);
    sql_result_row=mysql_fetch_row(sql_result);
    ///...

    //查出所有未运行需要取消的任务
    sprintf(sql_cmd,"SELECT * FROM task_list where\
 and cancel_state=1 and running_state=%ld or running_state=%ld)"
 ,i,MTASK_WAITTING,MTASK_HANGUP);
    mysql_query(mysqldb,sql_cmd);
    sql_result=mysql_store_result(mysqldb);
    sql_result_row=mysql_fetch_row(sql_result);
    //...

    return leaf;
}

int main(int argc, char **argv)
{
    int i;

    const char *host = "localhost";
    const char *user = "root";
    const char *pass = "123456";
    const char *db   = "test";

    MYSQL mysqldb;
    MYSQL_RES *result;
    MYSQL_ROW sql_row;
    MYSQL_FIELD *fd;

    mysql_init(&mysqldb);

    if (!mysql_real_connect(&mysqldb, host, user, pass, db, 0, NULL, 0))
    {
        printf("%s", mysql_error(&mysqldb));
    }
    while(1)
    {
        sleep(1000);
        if(check_if_finished(&mysqldb))
            get_current_task(&mysqldb);
    }
   // printf("HelloWorld!");
    return 0;
}

<|endoftext|>


<commit_before>/* Copyright (c) 2009, Simeon Bird <spb41@cam.ac.uk>
 *               Based on code (c) 2005 by J. Bolton
 *
 * Permission to use, copy, modify, and/or distribute this software for any
 * purpose with or without fee is hereby granted, provided that the above
 * copyright notice and this permission notice appear in all copies.
 *
 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */

#include <math.h>
#include <stdio.h>
#include <stdlib.h>
//For getopt
#include <unistd.h>
//For strerror
#include <errno.h>
#include <string.h>
#include "global_vars.h"
#include "parameters.h"
#include "index_table.h"
#include <string>
#include <sstream>
#include <iostream>
#ifdef HDF5
#include <hdf5.h>

std::string find_first_hdf_file(const std::string& infname)
{
  /*Switch off error handling so that we can check whether a
   * file is HDF5 */
  /* Save old error handler */
  hid_t error_stack=0;
  herr_t (*old_func)(hid_t, void*);
  void *old_client_data;
  H5Eget_auto(error_stack, &old_func, &old_client_data);
  /* Turn off error handling */
  H5Eset_auto(error_stack, NULL, NULL);
  std::string fname = infname;

  /*Were we handed an HDF5 file?*/
  if(H5Fis_hdf5(fname.c_str()) <= 0){
     /*If we weren't, were we handed an HDF5 file without the suffix?*/
     fname = infname+std::string(".0.hdf5");
     if (H5Fis_hdf5(fname.c_str()) <= 0)
        fname = std::string();
  }

  /* Restore previous error handler */
  H5Eset_auto(error_stack, old_func, old_client_data);
  return fname;
}
#endif
#ifdef HELIUM
  #error "Helium no longer supported like this: Use the python module"
#endif

/*Open a file for reading to check it exists*/
int file_readable(const char * filename)
{
     FILE * file;
     if ((file = fopen(filename, "r"))){
          fclose(file);
          return 1;
     }
     return 0;
}

int main(int argc, char **argv)
{
  int64_t Npart;
  int NumLos=0;
  int64_t MaxRead=256*256*256,StartPart=0;

  FILE *output;
  los *los_table=NULL;
  char *ext_table=NULL;
  std::string outname;
  std::string indir;
  char c;
  int i;
#ifndef NO_HEADER
  int pad[32]={0};
#endif
  double  atime, redshift, Hz, box100, h100, omegab;
  struct particle_data P;
  double * rhoker_H=NULL;
  double * tau_H1=NULL;
  interp H1;
  const int nspecies = 1;
  /*Make sure stdout is line buffered even when not
   * printing to a terminal but, eg, perl*/
  setlinebuf(stdout);
  while((c = getopt(argc, argv, "o:i:t:n:h")) !=-1)
  {
    switch(c)
      {
        case 'o':
           outname=std::string(optarg)+std::string("_spectra.dat");
           break;
        case 'i':
           indir=std::string(optarg);
           break;
        case 'n':
           NumLos=atoi(optarg);
           break;
        case 't':
           ext_table=optarg;
           break;
        case 'h':
        case '?':
           help();
        default:
           exit(1);
      }
  }
  if(NumLos <=0) {
          std::cerr<<"Need NUMLOS >0"<<std::endl;
          help();
          exit(99);
  }
  if(indir.empty()) {
         std::cerr<<"Specify input ("<<indir<<") directory."<<std::endl;
         help();
         exit(99);
  }
  los_table=(los *) malloc(NumLos*sizeof(los));
  if(!los_table){
          std::cerr<<"Error allocating memory for sightline table"<<std::endl;
          exit(2);
  }
  if(InitLOSMemory(&H1, NumLos, nspecies*NBINS) ||
      !(rhoker_H = (double *) calloc((NumLos * NBINS) , sizeof(double)))){
                  std::cerr<<"Error allocating LOS memory\n"<<std::endl;
                  exit(2);
  }
  #ifdef HDF5
    /*ffname is a copy of input filename for extension*/
    /*First open first file to get header properties*/
    std::string fname = find_first_hdf_file(indir);
    std::string ffname = fname;
    unsigned i_fileno=0;
    int fileno=0;
    if ( !fname.empty() && load_hdf5_header(fname.c_str(), &atime, &redshift, &Hz, &box100, &h100) == 0 ){
            /*See if we have been handed the first file of a set:
             * our method for dealing with this closely mirrors
             * HDF5s family mode, but we cannot use this, because
             * our files may not all be the same size.*/
	    i_fileno = fname.find(".0.hdf5")+1;
    }
    /*If not an HDF5 file, try opening as a gadget file*/
    else
#endif
     if(load_header(indir.c_str(),&atime, &redshift, &Hz, &box100, &h100) < 0){
                std::cerr<<"No data loaded\n";
                exit(2);
    }
    /*Setup the los tables*/
    populate_los_table(los_table,NumLos, ext_table, box100);
    IndexTable sort_los_table(los_table, NumLos, box100);
  if(!(output=fopen(outname.c_str(),"w")))
  {
          fprintf(stderr, "Error opening %s: %s\n",outname.c_str(), strerror(errno));
          exit(1);
  }
        /*Loop over files. Keep going until we run out, skipping over broken files.
         * The call to file_readable is an easy way to shut up HDF5's error message.*/
    while(1){
          /* P is allocated inside load_snapshot*/
#ifdef HDF5
          if(i_fileno){
            /*If we ran out of files, we're done*/
            if(!(file_readable(ffname.c_str()) && H5Fis_hdf5(ffname.c_str()) > 0))
                    break;
              Npart=load_hdf5_snapshot(ffname.c_str(), &P,&omegab,fileno);
          }
          else
#endif
              Npart=load_snapshot(indir.c_str(), StartPart,MaxRead,&P, &omegab);
          if(Npart > 0){
             /*Rescale neutral fraction to take account of hydrogen fraction*/
              for(int ii = 0; ii< Npart; ii++)
                P.fraction[ii]*=XH;
             /*Do the hard SPH interpolation*/
             SPH_Interpolation(rhoker_H,&H1, 1, NBINS, Npart, NumLos,box100, los_table,sort_los_table, &P);
          }
          /*Free the particle list once we don't need it*/
          if(Npart >= 0)
            free_parts(&P);
#ifdef HDF5
          if(i_fileno){
                fileno++;
                if(i_fileno != std::string::npos){
		  std::ostringstream convert;
		  convert<<fileno;
                  ffname = fname.replace(i_fileno, 1, convert.str());
		}
                else
                 break;
          }
          else
#endif
                StartPart+=Npart;
          /*If we haven't been able to read the maximum number of particles,
           * signals we have reached the end of the snapshot set*/
          if(!i_fileno && (Npart != MaxRead))
                  break;
  }
  free(los_table);
  if(!(tau_H1 = (double *) calloc((NumLos * NBINS) , sizeof(double)))
                  ){
                  fprintf(stderr, "Error allocating memory for tau\n");
                  exit(2);
  }
  printf("Done interpolating, now calculating absorption\n");
#pragma omp parallel
  {
     #pragma omp for
     for(i=0; i<NumLos; i++){
       /*Make a bunch of pointers to the quantities for THIS LOS*/
       Rescale_Units(H1.rho+i*NBINS, H1.veloc+i*NBINS, H1.temp+i*NBINS, NBINS, h100, atime);
       Compute_Absorption(tau_H1+(i*NBINS), H1.rho+i*NBINS, H1.veloc+i*NBINS, H1.temp+i*NBINS,NBINS, Hz,h100, box100,atime, LAMBDA_LYA_H1, GAMMA_LYA_H1,FOSC_LYA,HMASS);
       Convert_Density(rhoker_H+(i*NBINS), H1.rho+i*NBINS, h100, atime, omegab);
     }
  }
  fwrite(&redshift,sizeof(double),1,output);
#ifndef NO_HEADER
  /*Write a bit of a header. */
  i=NBINS;
  fwrite(&box100,sizeof(double),1,output);
  fwrite(&i,sizeof(int),1,output);
  fwrite(&NumLos,sizeof(int),1,output);
  /*Write some space for future header data: total header size is
   * 128 bytes, with 24 full.*/
  fwrite(&pad,sizeof(int),32-6,output);
#endif
  fwrite(rhoker_H,sizeof(double),NBINS*NumLos,output);     /* gas overdensity */
  if(WriteLOSData(&H1, tau_H1,NumLos, output)){
     fprintf(stderr, "Error writing spectra to disk!\n");
  }
  fclose(output);
  /*Free other memory*/
  free(tau_H1);
  free(rhoker_H);
  FreeLOSMemory(&H1);
  return 0;
}
/**********************************************************************/

void help()
{
           fprintf(stderr, "Usage: ./extract -n NUMLOS -i filename (ie, without the .0) -o output_file (_flux_power.txt or _spectra.dat will be appended)\n"
                  "-t table_file will read line of sight coordinates from a table.\n");
           return;
}

int WriteLOSData(interp* species,double * tau, int NumLos,FILE * output)
{
  int items=0;
  items+=fwrite((*species).rho,sizeof(double),NBINS*NumLos,output);      /* n_HI/n_H */
  items+=fwrite((*species).temp,sizeof(double),NBINS*NumLos,output);   /* T [K], HI weighted */
  items+=fwrite((*species).veloc,sizeof(double),NBINS*NumLos,output);  /* v_pec [km s^-1], HI weighted */
  items+=fwrite(tau,sizeof(double),NBINS*NumLos,output);    /* HI optical depth */
  if(items !=4*NBINS*NumLos)
          return 1;
  return 0;
}

<commit_msg>Fix compilation without HDF5<commit_after>/* Copyright (c) 2009, Simeon Bird <spb41@cam.ac.uk>
 *               Based on code (c) 2005 by J. Bolton
 *
 * Permission to use, copy, modify, and/or distribute this software for any
 * purpose with or without fee is hereby granted, provided that the above
 * copyright notice and this permission notice appear in all copies.
 *
 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */

#include <math.h>
#include <stdio.h>
#include <stdlib.h>
//For getopt
#include <unistd.h>
//For strerror
#include <errno.h>
#include <string.h>
#include "global_vars.h"
#include "parameters.h"
#include "index_table.h"
#include <string>
#include <sstream>
#include <iostream>
#ifdef HDF5
#include <hdf5.h>

std::string find_first_hdf_file(const std::string& infname)
{
  /*Switch off error handling so that we can check whether a
   * file is HDF5 */
  /* Save old error handler */
  hid_t error_stack=0;
  herr_t (*old_func)(hid_t, void*);
  void *old_client_data;
  H5Eget_auto(error_stack, &old_func, &old_client_data);
  /* Turn off error handling */
  H5Eset_auto(error_stack, NULL, NULL);
  std::string fname = infname;

  /*Were we handed an HDF5 file?*/
  if(H5Fis_hdf5(fname.c_str()) <= 0){
     /*If we weren't, were we handed an HDF5 file without the suffix?*/
     fname = infname+std::string(".0.hdf5");
     if (H5Fis_hdf5(fname.c_str()) <= 0)
        fname = std::string();
  }

  /* Restore previous error handler */
  H5Eset_auto(error_stack, old_func, old_client_data);
  return fname;
}
#endif
#ifdef HELIUM
  #error "Helium no longer supported like this: Use the python module"
#endif

/*Open a file for reading to check it exists*/
int file_readable(const char * filename)
{
     FILE * file;
     if ((file = fopen(filename, "r"))){
          fclose(file);
          return 1;
     }
     return 0;
}

int main(int argc, char **argv)
{
  int64_t Npart;
  int NumLos=0;
  int64_t MaxRead=256*256*256,StartPart=0;

  FILE *output;
  los *los_table=NULL;
  char *ext_table=NULL;
  std::string outname;
  std::string indir;
  char c;
  int i;
#ifndef NO_HEADER
  int pad[32]={0};
#endif
  double  atime, redshift, Hz, box100, h100, omegab;
  struct particle_data P;
  double * rhoker_H=NULL;
  double * tau_H1=NULL;
  interp H1;
  const int nspecies = 1;
  /*Make sure stdout is line buffered even when not
   * printing to a terminal but, eg, perl*/
  setlinebuf(stdout);
  while((c = getopt(argc, argv, "o:i:t:n:h")) !=-1)
  {
    switch(c)
      {
        case 'o':
           outname=std::string(optarg)+std::string("_spectra.dat");
           break;
        case 'i':
           indir=std::string(optarg);
           break;
        case 'n':
           NumLos=atoi(optarg);
           break;
        case 't':
           ext_table=optarg;
           break;
        case 'h':
        case '?':
           help();
        default:
           exit(1);
      }
  }
  if(NumLos <=0) {
          std::cerr<<"Need NUMLOS >0"<<std::endl;
          help();
          exit(99);
  }
  if(indir.empty()) {
         std::cerr<<"Specify input ("<<indir<<") directory."<<std::endl;
         help();
         exit(99);
  }
  los_table=(los *) malloc(NumLos*sizeof(los));
  if(!los_table){
          std::cerr<<"Error allocating memory for sightline table"<<std::endl;
          exit(2);
  }
  if(InitLOSMemory(&H1, NumLos, nspecies*NBINS) ||
      !(rhoker_H = (double *) calloc((NumLos * NBINS) , sizeof(double)))){
                  std::cerr<<"Error allocating LOS memory\n"<<std::endl;
                  exit(2);
  }
  #ifdef HDF5
    /*ffname is a copy of input filename for extension*/
    /*First open first file to get header properties*/
    std::string fname = find_first_hdf_file(indir);
    std::string ffname = fname;
    unsigned i_fileno=0;
    int fileno=0;
    if ( !fname.empty() && load_hdf5_header(fname.c_str(), &atime, &redshift, &Hz, &box100, &h100) == 0 ){
            /*See if we have been handed the first file of a set:
             * our method for dealing with this closely mirrors
             * HDF5s family mode, but we cannot use this, because
             * our files may not all be the same size.*/
	    i_fileno = fname.find(".0.hdf5")+1;
    }
    /*If not an HDF5 file, try opening as a gadget file*/
    else
#endif
     if(load_header(indir.c_str(),&atime, &redshift, &Hz, &box100, &h100) < 0){
                std::cerr<<"No data loaded\n";
                exit(2);
    }
    /*Setup the los tables*/
    populate_los_table(los_table,NumLos, ext_table, box100);
    IndexTable sort_los_table(los_table, NumLos, box100);
  if(!(output=fopen(outname.c_str(),"w")))
  {
          fprintf(stderr, "Error opening %s: %s\n",outname.c_str(), strerror(errno));
          exit(1);
  }
        /*Loop over files. Keep going until we run out, skipping over broken files.
         * The call to file_readable is an easy way to shut up HDF5's error message.*/
    while(1){
          /* P is allocated inside load_snapshot*/
#ifdef HDF5
          if(i_fileno){
            /*If we ran out of files, we're done*/
            if(!(file_readable(ffname.c_str()) && H5Fis_hdf5(ffname.c_str()) > 0))
                    break;
              Npart=load_hdf5_snapshot(ffname.c_str(), &P,&omegab,fileno);
          }
          else
#endif
              Npart=load_snapshot(indir.c_str(), StartPart,MaxRead,&P, &omegab);
          if(Npart > 0){
             /*Rescale neutral fraction to take account of hydrogen fraction*/
              for(int ii = 0; ii< Npart; ii++)
                P.fraction[ii]*=XH;
             /*Do the hard SPH interpolation*/
             SPH_Interpolation(rhoker_H,&H1, 1, NBINS, Npart, NumLos,box100, los_table,sort_los_table, &P);
          }
          /*Free the particle list once we don't need it*/
          if(Npart >= 0)
            free_parts(&P);
#ifdef HDF5
          if(i_fileno){
                fileno++;
                if(i_fileno != std::string::npos){
		  std::ostringstream convert;
		  convert<<fileno;
                  ffname = fname.replace(i_fileno, 1, convert.str());
		}
                else
                 break;
          }
          else
#endif
                StartPart+=Npart;
          /*If we haven't been able to read the maximum number of particles,
           * signals we have reached the end of the snapshot set*/
	#ifdef HDF5
	  if(!i_fileno)
	#endif
          if(Npart != MaxRead)
                  break;
  }
  free(los_table);
  if(!(tau_H1 = (double *) calloc((NumLos * NBINS) , sizeof(double)))
                  ){
                  fprintf(stderr, "Error allocating memory for tau\n");
                  exit(2);
  }
  printf("Done interpolating, now calculating absorption\n");
#pragma omp parallel
  {
     #pragma omp for
     for(i=0; i<NumLos; i++){
       /*Make a bunch of pointers to the quantities for THIS LOS*/
       Rescale_Units(H1.rho+i*NBINS, H1.veloc+i*NBINS, H1.temp+i*NBINS, NBINS, h100, atime);
       Compute_Absorption(tau_H1+(i*NBINS), H1.rho+i*NBINS, H1.veloc+i*NBINS, H1.temp+i*NBINS,NBINS, Hz,h100, box100,atime, LAMBDA_LYA_H1, GAMMA_LYA_H1,FOSC_LYA,HMASS);
       Convert_Density(rhoker_H+(i*NBINS), H1.rho+i*NBINS, h100, atime, omegab);
     }
  }
  fwrite(&redshift,sizeof(double),1,output);
#ifndef NO_HEADER
  /*Write a bit of a header. */
  i=NBINS;
  fwrite(&box100,sizeof(double),1,output);
  fwrite(&i,sizeof(int),1,output);
  fwrite(&NumLos,sizeof(int),1,output);
  /*Write some space for future header data: total header size is
   * 128 bytes, with 24 full.*/
  fwrite(&pad,sizeof(int),32-6,output);
#endif
  fwrite(rhoker_H,sizeof(double),NBINS*NumLos,output);     /* gas overdensity */
  if(WriteLOSData(&H1, tau_H1,NumLos, output)){
     fprintf(stderr, "Error writing spectra to disk!\n");
  }
  fclose(output);
  /*Free other memory*/
  free(tau_H1);
  free(rhoker_H);
  FreeLOSMemory(&H1);
  return 0;
}
/**********************************************************************/

void help()
{
           fprintf(stderr, "Usage: ./extract -n NUMLOS -i filename (ie, without the .0) -o output_file (_flux_power.txt or _spectra.dat will be appended)\n"
                  "-t table_file will read line of sight coordinates from a table.\n");
           return;
}

int WriteLOSData(interp* species,double * tau, int NumLos,FILE * output)
{
  int items=0;
  items+=fwrite((*species).rho,sizeof(double),NBINS*NumLos,output);      /* n_HI/n_H */
  items+=fwrite((*species).temp,sizeof(double),NBINS*NumLos,output);   /* T [K], HI weighted */
  items+=fwrite((*species).veloc,sizeof(double),NBINS*NumLos,output);  /* v_pec [km s^-1], HI weighted */
  items+=fwrite(tau,sizeof(double),NBINS*NumLos,output);    /* HI optical depth */
  if(items !=4*NBINS*NumLos)
          return 1;
  return 0;
}

<|endoftext|>


<commit_before>31716423-2748-11e6-abd0-e0f84713e7b8<commit_msg>GOD DAMNED IT!<commit_after>317c61ba-2748-11e6-8c8c-e0f84713e7b8<|endoftext|>


<commit_before>#include "ioput.h"

using namespace std;

template <class T>
void print(T data, bool endline = false){
	if (endline){
		cout << data << endl;
	}
	else{
		cout << data;
	}
}

int main(){

	IOput<double> a("TESTING");

	double x[5] = {0.1,0.2,0.3,0.4,0.5};
	double y[5] = {0.01,0.02,0.03,0.04,0.05};
	double z = 0.1;
	string fname("file");
	a.format_out_data("scientific", 7);
	a.save_x(z,z,fname);

//	double x[5] = {0.1,0.2,0.3,0.4,0.5};
//	string fname("file");
//	a.save_x(x,5,fname,"\t",-1,-1,false,false);

//	double x = 1.0e-3;
//	string fname("file");
//	a.format_out_data("scientific", 7);
//	a.save_x(x,fname,1,1,true,true);
//	a.format_out_data("fixed", 7);
//	a.save_x(x,fname+"2",1,4,true,true);

//	print("This is my test folder: ");
//	print(a.cwd(),true);

//	a.change_cwd("TESTING02");
//	print("This is my NEW test folder: ");
//	print(a.cwd(),true);

//	print(a.lzeros(4,1),true);

}
<commit_msg>1.0/10.03.2014:1450<commit_after>#include "ioput.h"

using namespace std;

template <class T>
void print(T data, bool endline = true){
	if (endline){
		cout << data << endl;
	}
	else{
		cout << data;
	}
}

int main(){

	IOput<double> a("TESTING");

	double x = 0.03;
	a.save_x(x,"test",-1,-1,false,true);

//	double x[5] = {0.1,0.2,0.3,0.4,0.5};
//	double y[5] = {0.01,0.02,0.03,0.04,0.05};
//	double z[5] = {1.0,2.0,3.0,4.0,5.0};
//	string fname("filexy");
//	a.save_xy(x,y,5,fname);
//	fname = "filexyz";
//	a.format_out_data("fixed",3);
//	a.save_xyz(x,y,z,5,fname);

//	double x[5] = {0.1,0.2,0.3,0.4,0.5};
//	string fname("file");
//	a.save_x(x,5,fname,"\t",-1,-1,false,false);

//	double x = 1.0e-3;
//	string fname("file");
//	a.format_out_data("scientific", 7);
//	a.save_x(x,fname,1,1,true,true);
//	a.format_out_data("fixed", 7);
//	a.save_x(x,fname+"2",1,4,true,true);

//	print("This is my test folder: ");
//	print(a.cwd(),true);

//	a.change_cwd("TESTING02");
//	print("This is my NEW test folder: ",false);
//	print(a.cwd());

//	print(a.lzeros(4,1));

}
<|endoftext|>


<commit_before>b133304c-2747-11e6-bcc7-e0f84713e7b8<commit_msg>update testing<commit_after>b14b0bb0-2747-11e6-bedc-e0f84713e7b8<|endoftext|>


<commit_before>584c1d51-2748-11e6-98cb-e0f84713e7b8<commit_msg>Introduced random NullPointerException bug<commit_after>58591f8c-2748-11e6-b3d7-e0f84713e7b8<|endoftext|>


<commit_before>/* Boar - Boar is a toolkit to modify text files.
 * Copyright (C) 2017 Katsuya Iida. All rights reserved.
 */

#include "stdafx.h"

#include "boar.h"
#include "taskqueue.h"
#include "filesource.h"

namespace boar
{
    size_t LineCount(const boost::filesystem::path& fileName)
    {
        // 1059203072      2068549
        // 36,762,348,544 bytes.
        // AMD E2-7110
        size_t lineCount;
        auto taskFunc = [](void* addr, size_t n)
        {
            size_t c = 0;
            const char* p = reinterpret_cast<const char*>(addr);
            for (auto cur = p; cur < p + n; ++cur)
            {
                if (*cur == '\n') ++c;
            }
            return c;
        };
        auto reduceFunc = [&lineCount](size_t count, void* addr, size_t n)
        {
            lineCount += count;
        };
        TaskQueue queue(taskFunc, reduceFunc);
        queue.Start();
        lineCount = 0;
        FileSourceWithMemoryMapping(fileName, [&queue](const void* addr, size_t n) {
            queue.Dispatch(addr, n);
        });
        queue.Stop();
        return lineCount;
    }

    size_t LineCountRef(const boost::filesystem::path fileName)
    {
        // 1059203072      1720807
        // 36,762,348,544 bytes.
        // AMD E2-7110
        size_t lineCount;
        FileSourceWithMemoryMapping(fileName, [&lineCount](const void *_addr, size_t n) {
            const char* first = reinterpret_cast<const char*>(_addr);
            const char* end = reinterpret_cast<const char*>(_addr) + n;
            size_t c = 0;
            for (auto cur = first; cur != end; ++cur)
            {
                if (*cur == '\n') c++;
            }
            lineCount = c;
        });
        return lineCount;
    }

    size_t LineCountRef3(const boost::filesystem::path fileName)
    {
        // 1059203070      463179
        // 36,762,348,544 bytes.
        // AMD E2-7110
        size_t lineCount = 0;
        FileSourceWithFileRead(fileName, [&lineCount](const void *addr, size_t n) {
            const char* p = reinterpret_cast<const char*>(addr);
            size_t c = 0;
            for (size_t i = 0; i < n; i++)
            {
                if (p[i] == '\n') c++;
            }
            lineCount += c;
        });
        return lineCount;
    }

    size_t LineCountRef4(const boost::filesystem::path fileName)
    {
        // 1059203072      414019
        // 36,762,348,544 bytes.
        // AMD E2-7110
        size_t lineCount = 0;
        FileSourceWithOverlapRead(fileName, [&lineCount](const void *addr, size_t n) {
            const char* p = reinterpret_cast<const char*>(addr);
            size_t c = 0;
            for (size_t i = 0; i < n; i++)
            {
                if (p[i] == '\n') c++;
            }
            lineCount += c;
        });
        return lineCount;
    }

    int DumpProfile(std::function<size_t()> func)
    {
        clock_t startTime = clock();
        size_t lineCount = func();
        clock_t endTime = clock();
        clock_t t = endTime - startTime;
        std::cout << lineCount << '\t' << t << std::endl;
        return 0;
    }

    int Main(const std::vector<std::wstring>& args)
    {
        int status;
        if (args.size() == 2)
        {
            const boost::filesystem::path fileName(args[1].c_str());
            if (args[0] == L"1")
            {
                status = DumpProfile([&fileName]() { return LineCount(fileName); });
            }
            else if (args[0] == L"2")
            {
                status = DumpProfile([&fileName]() { return LineCountRef(fileName); });
            }
            else if (args[0] == L"3")
            {
                status = DumpProfile([&fileName]() { return LineCountRef3(fileName); });
            }
        }
        else if (args.size() == 1)
        {
            const boost::filesystem::path fileName(args[0].c_str());
            status = DumpProfile([&fileName]() { return LineCountRef4(fileName); });
        }
        else
        {
            status = 1;
        }
        return 0;
    }
}
<commit_msg>Added Usage.<commit_after>/* Boar - Boar is a toolkit to modify text files.
 * Copyright (C) 2017 Katsuya Iida. All rights reserved.
 */

#include "stdafx.h"

#include "boar.h"
#include "taskqueue.h"
#include "filesource.h"

namespace boar
{
    size_t LineCount(const boost::filesystem::path& fileName)
    {
        // 1059203072      2068549
        // 36,762,348,544 bytes.
        // AMD E2-7110
        size_t lineCount;
        auto taskFunc = [](void* addr, size_t n)
        {
            size_t c = 0;
            const char* p = reinterpret_cast<const char*>(addr);
            for (auto cur = p; cur < p + n; ++cur)
            {
                if (*cur == '\n') ++c;
            }
            return c;
        };
        auto reduceFunc = [&lineCount](size_t count, void* addr, size_t n)
        {
            lineCount += count;
        };
        TaskQueue queue(taskFunc, reduceFunc);
        queue.Start();
        lineCount = 0;
        FileSourceWithMemoryMapping(fileName, [&queue](const void* addr, size_t n) {
            queue.Dispatch(addr, n);
        });
        queue.Stop();
        return lineCount;
    }

    size_t LineCountRef(const boost::filesystem::path fileName)
    {
        // 1059203072      1720807
        // 36,762,348,544 bytes.
        // AMD E2-7110
        size_t lineCount;
        FileSourceWithMemoryMapping(fileName, [&lineCount](const void *_addr, size_t n) {
            const char* first = reinterpret_cast<const char*>(_addr);
            const char* end = reinterpret_cast<const char*>(_addr) + n;
            size_t c = 0;
            for (auto cur = first; cur != end; ++cur)
            {
                if (*cur == '\n') c++;
            }
            lineCount = c;
        });
        return lineCount;
    }

    size_t LineCountRef3(const boost::filesystem::path fileName)
    {
        // 1059203070      463179
        // 36,762,348,544 bytes.
        // AMD E2-7110
        size_t lineCount = 0;
        FileSourceWithFileRead(fileName, [&lineCount](const void *addr, size_t n) {
            const char* p = reinterpret_cast<const char*>(addr);
            size_t c = 0;
            for (size_t i = 0; i < n; i++)
            {
                if (p[i] == '\n') c++;
            }
            lineCount += c;
        });
        return lineCount;
    }

    size_t LineCountRef4(const boost::filesystem::path fileName)
    {
        // 1059203072      414019
        // 36,762,348,544 bytes.
        // AMD E2-7110
        size_t lineCount = 0;
        FileSourceWithOverlapRead(fileName, [&lineCount](const void *addr, size_t n) {
            const char* p = reinterpret_cast<const char*>(addr);
            size_t c = 0;
            for (size_t i = 0; i < n; i++)
            {
                if (p[i] == '\n') c++;
            }
            lineCount += c;
        });
        return lineCount;
    }

    template <typename charT>
    size_t DropLines(const boost::filesystem::path fileName)
    {
        size_t lineCount = 0;
        FileSourceWithOverlapRead(fileName, [&lineCount](const void *addr, size_t n) {
            intptr_t addrValue = reinterpret_cast<intptr_t>(addr);
            const charT* first = reinterpret_cast<const charT*>(addrValue);
            const charT* last = reinterpret_cast<const charT*>(addrValue + n);
            size_t c = 0;
            const charT* lineStart = first;
            for (const charT* p = first; p != last; p++)
            {
                if (*p == '\n')
                {
                    const std::basic_string<charT> s(lineStart, p);
                    std::cout << s << std::endl;
                    lineStart = p + 1;
                    c++;
                }
            }
            lineCount += c;
        });
        return lineCount;
    }

    int DumpProfile(std::function<size_t()> func)
    {
        clock_t startTime = clock();
        size_t lineCount = func();
        clock_t endTime = clock();
        clock_t t = endTime - startTime;
        std::cout << lineCount << '\t' << t << std::endl;
        return 0;
    }

    int Usage()
    {
        std::cout <<
            "usage: boar <command> [<args>]\n"
            "\n"
            "Boar is a toolkit to process text files.\n"
            "\n"
            "List of commands:\n"
            "\n"
            "   lc      Count the number of lines.\n"
            << std::endl;
        return 1;
    }

    int Main(const std::vector<std::wstring>& args)
    {
        int status;
        if (args.size() == 1)
        {
            return Usage();
        }
        else if (args.size() == 2)
        {
            const boost::filesystem::path fileName(args[1].c_str());
            if (args[0] == L"1")
            {
                status = DumpProfile([&fileName]() { return LineCount(fileName); });
            }
            else if (args[0] == L"2")
            {
                status = DumpProfile([&fileName]() { return LineCountRef(fileName); });
            }
            else if (args[0] == L"3")
            {
                status = DumpProfile([&fileName]() { return LineCountRef3(fileName); });
            }
            else if (args[0] == L"drop")
            {
                status = DumpProfile([&fileName]() { return DropLines<char>(fileName); });
            }
            else if (args[0] == L"lc")
            {
                status = DumpProfile([&fileName]() { return LineCountRef4(fileName); });
            }
        }
        else
        {
            return Usage();
        }
        return 0;
    }
}
<|endoftext|>


<commit_before>/*****************************************************************************
 *
 * YEXTEND: Help for YARA users.
 * This file is part of yextend.
 *
 * Copyright (c) 2104-2016, Bayshore Networks, Inc.
 * All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without modification, are permitted provided that
 * the following conditions are met:
 *
 * 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the
 * following disclaimer.
 *
 * 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the
 * following disclaimer in the documentation and/or other materials provided with the distribution.
 *
 * 3. Neither the name of the copyright holder nor the names of its contributors may be used to endorse or promote
 * products derived from this software without specific prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
 * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
 * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
 * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 *****************************************************************************/

#include <iostream>
#include <list>

#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <signal.h>
#include <syslog.h>
#include <unistd.h>
#include <sys/stat.h>
#include <stdint.h>
#include <dirent.h>
#include <openssl/md5.h>

#include "bayshore_content_scan.h"

#ifdef __cplusplus
extern "C" {
#endif

#include "bayshore_yara_wrapper.h"

#ifdef __cplusplus
}
#endif

// Get the size of a file
long get_file_size(FILE *file)
{
	long lCurPos, lEndPos;
	lCurPos = ftell(file);
	fseek(file, 0, 2);
	lEndPos = ftell(file);
	fseek(file, lCurPos, 0);
	return lEndPos;
}

char *str_to_md5(const char *str, int length)
{
	int n;
	MD5_CTX c;
	unsigned char digest[16];
	char *out = (char*)malloc(33);

	MD5_Init(&c);

	while (length > 0) {
		if (length > 512) {
			MD5_Update(&c, str, 512);
		} else {
			MD5_Update(&c, str, length);
		}
		length -= 512;
		str += 512;
	}

	MD5_Final(digest, &c);

	for (n = 0; n < 16; ++n) {
		snprintf(&(out[n*2]), 16*2, "%02x", (unsigned int)digest[n]);
	}

	return out;
}

bool is_directory(const char* path)
{
	struct stat st;

	if (stat(path,&st) == 0)
		return S_ISDIR(st.st_mode);

	return false;
}

bool does_this_file_exist(const char *fn)
{
	struct stat st;
	return ( fn && *fn && (stat (fn, &st) == 0) && (S_ISREG(st.st_mode)) );
}

double get_yara_version()
{
    FILE *fp;
    int tok_cnt = 0;
    double yara_version = 0.0;
    char yver[10];
    const char t[2] = " ";
    char *token;

    fp = popen("yara -v", "r");
    /*
    if (fp == NULL) {
        printf("Failed to run command\n" );
        exit;
    }
	*/
    if (fp != NULL) {
		fgets(yver, sizeof(yver)-1, fp);
		if (yver != NULL) {
			token = strtok(yver, t);
			while( token != NULL )
			{
				if (tok_cnt == 1) {
					yara_version = strtod(token, NULL);
				}
				token = strtok(NULL, t);
				tok_cnt++;
			}
		}
    }
    pclose(fp);

    return yara_version;
}

static const char *output_labels[] = {
		"File Name: ",
		"File Size: ",
		"Yara Result(s): ",
		"Scan Type: ",
		"File Signature (MD5): ",
		"Non-Archive File Name: ",
		"Parent File Name: ",
		"Child File Name: ",
		"Ruleset File Name: "
};

static const char *alpha = "===============================ALPHA===================================";
static const char *midline = "=======================================================================";
static const char *omega = "===============================OMEGA===================================";

/****
main
****/

int main(int argc, char* argv[])
{

	if (argc != 3) {
		std::cout << std::endl << "usage: ./yextend RULES_FILE [FILE|DIR]" << std::endl << std::endl;
		exit(0);
	}

	// get yara runtime version
	double yara_version = get_yara_version();
	// version checks
	if (YEXTEND_VERSION >= 1.2 && yara_version < 3.4) {
		std::cout << std::endl << "Version issue: yextend version " << YEXTEND_VERSION << "+ will not run with yara versions below 3.4" << std::endl << std::endl;
		std::cout << "Your env has yextend version ";
		printf("%.1f\n", YEXTEND_VERSION);
		std::cout << "Your env has yara version ";
		printf("%.1f", yara_version);
		std::cout << std::endl << std::endl;
		exit(0);
	}
	const char *yara_ruleset_file_name = argv[1];
	const char *target_resource = argv[2];
	char fs[300];

	/*
	 * pre-process yara rules and then we can use the
	 * pointer to "rules" as an optimized entity.
	 * this is a requirement so that performance
	 * is optimal
	 */
	YR_RULES* rules = NULL;
	rules = bayshore_yara_preprocess_rules(yara_ruleset_file_name);
	if (!rules) {
		if (!does_this_file_exist(yara_ruleset_file_name)) {
			std::cout << std::endl << "Yara Ruleset file: \"" << yara_ruleset_file_name << "\" does not exist, exiting ..." << std::endl << std::endl;
			exit(0);
		}
		std::cout << std::endl << "Problem compiling Yara Ruleset file: \"" << yara_ruleset_file_name << "\", continuing with regular ruleset file ..." << std::endl << std::endl;
	}

	if (is_directory(target_resource)) {

		DIR *dpdf;
		struct dirent *epdf;

		dpdf = opendir(target_resource);
		if (dpdf != NULL) {
			while (epdf = readdir(dpdf)){

				uint8_t *c;
				FILE *file = NULL;

				strncpy (fs, target_resource, strlen(target_resource));
				fs[strlen(target_resource)] = '\0';

				if (epdf->d_name[0] != '.') {

					strncat (fs, epdf->d_name, strlen(epdf->d_name));
					fs[strlen(fs)] = '\0';

					if (is_directory(fs)) {
						// We do not recurse into directories yet
						continue;
					}

					if ((file = fopen(fs, "rb")) != NULL) {
						// Get the size of the file in bytes
						long fileSize = get_file_size(file);

						// Allocate space in the buffer for the whole file
						c = new uint8_t[fileSize];
						// Read the file in to the buffer
						fread(c, fileSize, 1, file);

						std::cout << std::endl << alpha << std::endl;
						std::cout << output_labels[8] << yara_ruleset_file_name << std::endl;
						std::cout << output_labels[0] << fs << std::endl;
						std::cout << output_labels[1] << fileSize << std::endl;

						char *output = str_to_md5((const char *)c, fileSize);
						if (output) {
							std::cout << output_labels[4] << output << std::endl;
							free(output);
						}

						std::list<security_scan_results_t> ssr_list;

						if (rules) {

							scan_content (
									c,
									fileSize,
									rules,
									&ssr_list,
									fs,
									yara_cb,
									1);

						} else {
							scan_content (
									c,
									fileSize,
									yara_ruleset_file_name,
									&ssr_list,
									fs,
									yara_cb,
									1);
						}

						if (!ssr_list.empty()) {

							std::cout << std::endl << midline << std::endl;
							for (std::list<security_scan_results_t>::const_iterator v = ssr_list.begin();
									v != ssr_list.end();
									v++)
							{
								std::cout << std::endl;
								std::cout << output_labels[2] << v->file_scan_result << std::endl;
								std::cout << output_labels[3] << v->file_scan_type << std::endl;
								if (v->parent_file_name.size()) {
									if (v->child_file_name.size())
										std::cout << output_labels[6] << v->parent_file_name << std::endl << output_labels[7] << v->child_file_name << std::endl;
									else
										std::cout << output_labels[5] << v->parent_file_name << std::endl;
								}
								std::cout << output_labels[4] << v->file_signature_md5 << std::endl;
								std::cout << std::endl;
							}
							std::cout << std::endl << omega << std::endl;
						} else {
							std::cout << std::endl << omega << std::endl;
						}

						delete[] c;
						fclose(file);
					}
				}
			}
			closedir(dpdf);
		}
	} else if(does_this_file_exist(target_resource)) {

		uint8_t *c;
		FILE *file = NULL;
		strncpy (fs, target_resource, strlen(target_resource));
		fs[strlen(target_resource)] = '\0';

		if (fs[0] != '.') {

			if ((file = fopen(fs, "rb")) != NULL) {
				// Get the size of the file in bytes
				long fileSize = get_file_size(file);

				// Allocate space in the buffer for the whole file
				c = new uint8_t[fileSize];

				// Read the file in to the buffer
				fread(c, fileSize, 1, file);

				std::cout << std::endl << alpha << std::endl;
				std::cout << output_labels[0] << fs << std::endl;
				std::cout << output_labels[1] << fileSize << std::endl;

				char *output = str_to_md5((const char *)c, fileSize);
				if (output) {
					// XXX fixme
					std::cout << output_labels[4] << output << std::endl;
					free(output);
				}

				std::list<security_scan_results_t> ssr_list;

				if (rules) {

					scan_content (
							c,
							fileSize,
							rules,
							&ssr_list,
							fs,
							yara_cb,
							1);
				} else {
					scan_content (
							c,
							fileSize,
							yara_ruleset_file_name,
							&ssr_list,
							fs,
							yara_cb,
							1);
				}

				if (!ssr_list.empty()) {
					std::cout << std::endl << midline << std::endl;
					for (std::list<security_scan_results_t>::const_iterator v = ssr_list.begin();
							v != ssr_list.end();
							v++)
					{
						std::cout << std::endl;
						std::cout << output_labels[2] << v->file_scan_result << std::endl;
						std::cout << output_labels[3] << v->file_scan_type << std::endl;
						if (v->parent_file_name.size()) {
							if (v->child_file_name.size())
								std::cout << output_labels[6] << v->parent_file_name << std::endl << output_labels[7] << v->child_file_name << std::endl;
							else
								std::cout << output_labels[5] << v->parent_file_name << std::endl;
						}
						std::cout << output_labels[4] << v->file_signature_md5 << std::endl;
						std::cout << std::endl;
					}
					std::cout << std::endl << omega << std::endl;
				} else {
					std::cout << std::endl << omega << std::endl;
				}

				delete[] c;
				fclose(file);
			}
		}

	} else {
		std::cout << std::endl << "Could not read resource: \"" << target_resource << "\", exiting ..." << std::endl << std::endl;
	}

	if (rules != NULL)
		yr_rules_destroy(rules);
	return 0;
}
<commit_msg>include path update for yara wrapper<commit_after>/*****************************************************************************
 *
 * YEXTEND: Help for YARA users.
 * This file is part of yextend.
 *
 * Copyright (c) 2104-2016, Bayshore Networks, Inc.
 * All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without modification, are permitted provided that
 * the following conditions are met:
 *
 * 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the
 * following disclaimer.
 *
 * 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the
 * following disclaimer in the documentation and/or other materials provided with the distribution.
 *
 * 3. Neither the name of the copyright holder nor the names of its contributors may be used to endorse or promote
 * products derived from this software without specific prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
 * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
 * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
 * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 *****************************************************************************/

#include <iostream>
#include <list>

#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <signal.h>
#include <syslog.h>
#include <unistd.h>
#include <sys/stat.h>
#include <stdint.h>
#include <dirent.h>
#include <openssl/md5.h>

#include "bayshore_content_scan.h"

#ifdef __cplusplus
extern "C" {
#endif

#include "libs/bayshore_yara_wrapper.h"

#ifdef __cplusplus
}
#endif

// Get the size of a file
long get_file_size(FILE *file)
{
	long lCurPos, lEndPos;
	lCurPos = ftell(file);
	fseek(file, 0, 2);
	lEndPos = ftell(file);
	fseek(file, lCurPos, 0);
	return lEndPos;
}

char *str_to_md5(const char *str, int length)
{
	int n;
	MD5_CTX c;
	unsigned char digest[16];
	char *out = (char*)malloc(33);

	MD5_Init(&c);

	while (length > 0) {
		if (length > 512) {
			MD5_Update(&c, str, 512);
		} else {
			MD5_Update(&c, str, length);
		}
		length -= 512;
		str += 512;
	}

	MD5_Final(digest, &c);

	for (n = 0; n < 16; ++n) {
		snprintf(&(out[n*2]), 16*2, "%02x", (unsigned int)digest[n]);
	}

	return out;
}

bool is_directory(const char* path)
{
	struct stat st;

	if (stat(path,&st) == 0)
		return S_ISDIR(st.st_mode);

	return false;
}

bool does_this_file_exist(const char *fn)
{
	struct stat st;
	return ( fn && *fn && (stat (fn, &st) == 0) && (S_ISREG(st.st_mode)) );
}

double get_yara_version()
{
    FILE *fp;
    int tok_cnt = 0;
    double yara_version = 0.0;
    char yver[10];
    const char t[2] = " ";
    char *token;

    fp = popen("yara -v", "r");
    /*
    if (fp == NULL) {
        printf("Failed to run command\n" );
        exit;
    }
	*/
    if (fp != NULL) {
		fgets(yver, sizeof(yver)-1, fp);
		if (yver != NULL) {
			token = strtok(yver, t);
			while( token != NULL )
			{
				if (tok_cnt == 1) {
					yara_version = strtod(token, NULL);
				}
				token = strtok(NULL, t);
				tok_cnt++;
			}
		}
    }
    pclose(fp);

    return yara_version;
}

static const char *output_labels[] = {
		"File Name: ",
		"File Size: ",
		"Yara Result(s): ",
		"Scan Type: ",
		"File Signature (MD5): ",
		"Non-Archive File Name: ",
		"Parent File Name: ",
		"Child File Name: ",
		"Ruleset File Name: "
};

static const char *alpha = "===============================ALPHA===================================";
static const char *midline = "=======================================================================";
static const char *omega = "===============================OMEGA===================================";

/****
main
****/

int main(int argc, char* argv[])
{

	if (argc != 3) {
		std::cout << std::endl << "usage: ./yextend RULES_FILE [FILE|DIR]" << std::endl << std::endl;
		exit(0);
	}

	// get yara runtime version
	double yara_version = get_yara_version();
	// version checks
	if (YEXTEND_VERSION >= 1.2 && yara_version < 3.4) {
		std::cout << std::endl << "Version issue: yextend version " << YEXTEND_VERSION << "+ will not run with yara versions below 3.4" << std::endl << std::endl;
		std::cout << "Your env has yextend version ";
		printf("%.1f\n", YEXTEND_VERSION);
		std::cout << "Your env has yara version ";
		printf("%.1f", yara_version);
		std::cout << std::endl << std::endl;
		exit(0);
	}
	const char *yara_ruleset_file_name = argv[1];
	const char *target_resource = argv[2];
	char fs[300];

	/*
	 * pre-process yara rules and then we can use the
	 * pointer to "rules" as an optimized entity.
	 * this is a requirement so that performance
	 * is optimal
	 */
	YR_RULES* rules = NULL;
	rules = bayshore_yara_preprocess_rules(yara_ruleset_file_name);
	if (!rules) {
		if (!does_this_file_exist(yara_ruleset_file_name)) {
			std::cout << std::endl << "Yara Ruleset file: \"" << yara_ruleset_file_name << "\" does not exist, exiting ..." << std::endl << std::endl;
			exit(0);
		}
		std::cout << std::endl << "Problem compiling Yara Ruleset file: \"" << yara_ruleset_file_name << "\", continuing with regular ruleset file ..." << std::endl << std::endl;
	}

	if (is_directory(target_resource)) {

		DIR *dpdf;
		struct dirent *epdf;

		dpdf = opendir(target_resource);
		if (dpdf != NULL) {
			while (epdf = readdir(dpdf)){

				uint8_t *c;
				FILE *file = NULL;

				strncpy (fs, target_resource, strlen(target_resource));
				fs[strlen(target_resource)] = '\0';

				if (epdf->d_name[0] != '.') {

					strncat (fs, epdf->d_name, strlen(epdf->d_name));
					fs[strlen(fs)] = '\0';

					if (is_directory(fs)) {
						// We do not recurse into directories yet
						continue;
					}

					if ((file = fopen(fs, "rb")) != NULL) {
						// Get the size of the file in bytes
						long fileSize = get_file_size(file);

						// Allocate space in the buffer for the whole file
						c = new uint8_t[fileSize];
						// Read the file in to the buffer
						fread(c, fileSize, 1, file);

						std::cout << std::endl << alpha << std::endl;
						std::cout << output_labels[8] << yara_ruleset_file_name << std::endl;
						std::cout << output_labels[0] << fs << std::endl;
						std::cout << output_labels[1] << fileSize << std::endl;

						char *output = str_to_md5((const char *)c, fileSize);
						if (output) {
							std::cout << output_labels[4] << output << std::endl;
							free(output);
						}

						std::list<security_scan_results_t> ssr_list;

						if (rules) {

							scan_content (
									c,
									fileSize,
									rules,
									&ssr_list,
									fs,
									yara_cb,
									1);

						} else {
							scan_content (
									c,
									fileSize,
									yara_ruleset_file_name,
									&ssr_list,
									fs,
									yara_cb,
									1);
						}

						if (!ssr_list.empty()) {

							std::cout << std::endl << midline << std::endl;
							for (std::list<security_scan_results_t>::const_iterator v = ssr_list.begin();
									v != ssr_list.end();
									v++)
							{
								std::cout << std::endl;
								std::cout << output_labels[2] << v->file_scan_result << std::endl;
								std::cout << output_labels[3] << v->file_scan_type << std::endl;
								if (v->parent_file_name.size()) {
									if (v->child_file_name.size())
										std::cout << output_labels[6] << v->parent_file_name << std::endl << output_labels[7] << v->child_file_name << std::endl;
									else
										std::cout << output_labels[5] << v->parent_file_name << std::endl;
								}
								std::cout << output_labels[4] << v->file_signature_md5 << std::endl;
								std::cout << std::endl;
							}
							std::cout << std::endl << omega << std::endl;
						} else {
							std::cout << std::endl << omega << std::endl;
						}

						delete[] c;
						fclose(file);
					}
				}
			}
			closedir(dpdf);
		}
	} else if(does_this_file_exist(target_resource)) {

		uint8_t *c;
		FILE *file = NULL;
		strncpy (fs, target_resource, strlen(target_resource));
		fs[strlen(target_resource)] = '\0';

		if (fs[0] != '.') {

			if ((file = fopen(fs, "rb")) != NULL) {
				// Get the size of the file in bytes
				long fileSize = get_file_size(file);

				// Allocate space in the buffer for the whole file
				c = new uint8_t[fileSize];

				// Read the file in to the buffer
				fread(c, fileSize, 1, file);

				std::cout << std::endl << alpha << std::endl;
				std::cout << output_labels[0] << fs << std::endl;
				std::cout << output_labels[1] << fileSize << std::endl;

				char *output = str_to_md5((const char *)c, fileSize);
				if (output) {
					// XXX fixme
					std::cout << output_labels[4] << output << std::endl;
					free(output);
				}

				std::list<security_scan_results_t> ssr_list;

				if (rules) {

					scan_content (
							c,
							fileSize,
							rules,
							&ssr_list,
							fs,
							yara_cb,
							1);
				} else {
					scan_content (
							c,
							fileSize,
							yara_ruleset_file_name,
							&ssr_list,
							fs,
							yara_cb,
							1);
				}

				if (!ssr_list.empty()) {
					std::cout << std::endl << midline << std::endl;
					for (std::list<security_scan_results_t>::const_iterator v = ssr_list.begin();
							v != ssr_list.end();
							v++)
					{
						std::cout << std::endl;
						std::cout << output_labels[2] << v->file_scan_result << std::endl;
						std::cout << output_labels[3] << v->file_scan_type << std::endl;
						if (v->parent_file_name.size()) {
							if (v->child_file_name.size())
								std::cout << output_labels[6] << v->parent_file_name << std::endl << output_labels[7] << v->child_file_name << std::endl;
							else
								std::cout << output_labels[5] << v->parent_file_name << std::endl;
						}
						std::cout << output_labels[4] << v->file_signature_md5 << std::endl;
						std::cout << std::endl;
					}
					std::cout << std::endl << omega << std::endl;
				} else {
					std::cout << std::endl << omega << std::endl;
				}

				delete[] c;
				fclose(file);
			}
		}

	} else {
		std::cout << std::endl << "Could not read resource: \"" << target_resource << "\", exiting ..." << std::endl << std::endl;
	}

	if (rules != NULL)
		yr_rules_destroy(rules);
	return 0;
}
<|endoftext|>


<commit_before>9a74d0eb-2747-11e6-b5d4-e0f84713e7b8<commit_msg>Initial commit.13<commit_after>9a87f211-2747-11e6-8786-e0f84713e7b8<|endoftext|>


<commit_before>2cc7ea2e-ad5c-11e7-b925-ac87a332f658<commit_msg>Really doesn't crash if X, now<commit_after>2d3e9763-ad5c-11e7-b334-ac87a332f658<|endoftext|>