misc.cpp
#include "misc.h"
#include <sys/time.h>
#include <sys/times.h>
#include <sys/wait.h>
#include <cmath>
#include <unistd.h>
#include <iomanip>
#include <cstdio>
#include <sstream>
#include <string>

using namespace std;

string CurrentDayHour(){
  std::time_t t = std::time(0);   // get time now
  std::tm* now = std::localtime(&t);
  ostringstream oss;
  oss << (now->tm_year + 1900) << '-' << (now->tm_mon + 1) << '-' <<  now->tm_mday << " " <<  now->tm_hour << ":" <<  now->tm_min << ":" <<  now->tm_sec;
  return oss.str();
}

string CurrentDay(){
  std::time_t t = std::time(0);   // get time now
  std::tm* now = std::localtime(&t);
  ostringstream oss;
  oss << (now->tm_year + 1900) << '-' << (now->tm_mon + 1) << '-' <<  now->tm_mday;
  return oss.str();
}

string CurrentHour(){
  std::time_t t = std::time(0);   // get time now
  std::tm* now = std::localtime(&t);
  ostringstream oss;
  oss << now->tm_hour << ":" <<  now->tm_min << ":" <<  now->tm_sec;
  return oss.str();
}

string HostName(){
  char hostname[1024];
  gethostname(hostname, 1024);
  return string(hostname);
}

bool FileRemove(const char *filename){
  if (remove(filename)!=0){
    //    cerr << "Error deleting file" << filename << endl;
    return false;
  }
  //  cout << "File " << filename << " successfully deleted." << endl;
  return true;
}

bool FileExists(const char *filename){
  std::fstream fin;
  fin.open(filename,std::ios::in);
  if(fin.is_open()){
    fin.close();
    return true;
  }
  //  fin.close(); 
  return false;
}

int FileSize(const char* FileName){
  std::ifstream f;
  f.open(FileName, std::ios_base::binary | std::ios_base::in);
  if (!f.good() || f.eof() || !f.is_open()) { return 0; }
  f.seekg(0, std::ios_base::beg);
  std::ifstream::pos_type begin_pos = f.tellg();
  f.seekg(0, std::ios_base::end);
  return static_cast<int>(f.tellg() - begin_pos);
}

void FileCopy(const char* From, const char* To){
  ifstream InFileCopy(From) ;
  ofstream OutFileCopy(To) ;

  char ch;
  while (InFileCopy.get(ch)) OutFileCopy.put(ch);
  InFileCopy.close();
  OutFileCopy.close();
}

string dirname(const char* FileName){
  string name(FileName);
  size_t found=name.rfind("/");
  if (found!=string::npos) name.replace(found,name.length(),"");
  return name;
}

string itos(int i){
  char str[20];
  sprintf(str,"%d",i);
  string s(str);
  return s;
}

long GetMemAvail(){
  // returns size of currently available physical memory in Bytes
  return (sysconf(_SC_PAGESIZE))*sysconf(_SC_AVPHYS_PAGES);
}

long GetMemMax(){
  // returns size of physical memory in Bytes
  return (sysconf(_SC_PAGESIZE))*sysconf(_SC_PHYS_PAGES);
}

int exec(char *argv[]){
  int ExecRes;
  int ForkRes=fork();
  switch (ForkRes) {
    case 0:
      /* we are in a CHILD program */
      ExecRes = execvp( argv[0], argv);
      /* if there is return form execvp then there was an error in execution of a program */
      /*      printf( "Execution result:%d\n",ExecRes ) ;*/
      /*      printf( "ERROR: %d.\n",errno ) ; */
      cout << "Cannot execute program: "; 
      for (int i=0;argv[i]!=NULL;i++) cout << " " << argv[i];
      cout << endl; 
      /* There was an error in execution: exit from CHILD */
      exit(-1);
      break;
    case -1:
      /* ERROR in fork */
      printf( "Child process not created - fork error\n" ) ;
      break;
    default:
      /* we are in PARENT program */
      if (false) cout << "ID: " << ForkRes << endl;
      return ForkRes;
  }
  return -1;
}

int execwait(char *argv[]){
  int ExecRes;
  int ForkRes=fork();
  switch (ForkRes) {
    case 0:
      /* we are in a CHILD program */
      ExecRes = execvp( argv[0], argv);
      /* if there is return form execvp then there was an error in execution of a program */
      /*      printf( "Execution result:%d\n",ExecRes ) ;*/
      /*      printf( "ERROR: %d.\n",errno ) ; */
      cout << "Cannot execute program: "; 
      for (int i=0;argv[i]!=NULL;i++) cout << " " << argv[i];
      cout << endl; 
      /* There was an error in execution: exit from CHILD */
      exit(-1); 
      return -1;
    case -1:
      /* ERROR in fork */
      printf( "Child process not created - fork error\n" ) ;
      return -1;
    default:
      /* we are in PARENT program */
      cout << "ID: " << ForkRes << endl;
      int status=0;
      waitpid(ForkRes,&status,0);
      if (WIFEXITED(status)==0) cerr << "Error" << endl;
      // WIFEXITED(status)
      //              jest niezerowe, je�li potomek normalnie zako�czy� prac�.

      //       WEXITSTATUS(status)
      //              analizuje osiem najmniej  znacz�cych  bit�w  kodu
      //              powrotu  zako�czonego  potomka,  kt�re  mog�y by�
      //              ustawione jako argument wywo�ania exit() lub jako
      //              argument  instrukcji  return w programie g��wnym.
      //              Makro  to  mo�e  by�  przetworzone,  tylko  je�li
      //              WIFEXITED zwr�ci�o warto�� niezerow�.
      // WIFEXITED(status)
      cout << "Process with ID: " << ForkRes << " returned with status " << (status>>8) << endl;
      return (status>>8);
  }
  return -1;
}

int execwait(vector <string> argstring){
  int ParNum=argstring.size();
  char *args[ParNum+1];
  for (unsigned int i=0;i<argstring.size();i++){
    args[i]=new char[strlen(argstring[i].c_str())+1];
    strcpy(args[i],argstring[i].c_str());
  }
  args[ParNum]=NULL;
  int res=-1;
  if (args[0]!=NULL) res=execwait(args);
  else cerr << "Empty command\n";
  for (int i=0;args[i]!=NULL;i++) delete [] args[i];
  return res;
}

int execwait(const char *arg){
  istringstream istr(arg);
  vector <string> argstring;
  while (!istr.eof()){
    string s;
    istr >> s;
    argstring.push_back(s);
  }
  return execwait(argstring);
}

void ViewTempFile(const char *PrintCommand, const char *FileName){
  const int ParamNumMax=20;
  char *args[ParamNumMax+1];
  istringstream istr(PrintCommand);
  int ParNum=0;
  while (!istr.eof()){
    char WS[50];
    istr >> WS;
    if (strcmp(WS,"%f")==0) sprintf(WS,"%s",FileName);
    args[ParNum]=new char[strlen(WS)+1];
    strcpy(args[ParNum],WS);
    cout << args[ParNum] << " ";
    ParNum++;
    if (ParNum>=ParamNumMax){
      cerr << "Too many parameters in command line\n";
      return;
    }
  }
  args[ParNum]=NULL;
  cout << endl;
  if (args[0]!=NULL) exec(args);
  else cerr << "Empty command\n";
  for (int i=0;args[i]!=NULL;i++) delete [] args[i];
}

int Execute(const char *Command, bool disp){
  // execute the command
  const int ParamNumMax=20;
  char *args[ParamNumMax+1];
  if (disp) cout << Command << endl;
  istringstream istr(Command);
  int ParNum=0;
  while (!istr.eof()){
    char WS[20];
    istr >> WS;
    args[ParNum]=new char[strlen(WS)+1];
    strcpy(args[ParNum],WS);
    ParNum++;
    if (ParNum>=ParamNumMax) {
      cerr << "Too many parameters in command line\n";
      return -1;
    }
  }
  args[ParNum]=NULL;
  if (disp){
    for (int i=0;args[i]!=NULL;i++) cout << args[i] << " ";
    cout << endl;
  }
  int res=0;
  if (args[0]!=NULL) res=exec(args);
  else cerr << "Empty command\n";
  for (int i=0;args[i]!=NULL;i++) delete [] args[i];
  return res;
}

int Execute(const char *Command, const char *FileName, bool disp){
  // substitute replace for %f in Command and execute the command
  string s(Command);
  string::size_type pos=0;
  while ((pos=s.find("%f",0))!=string::npos) s.replace(pos,2,FileName);
  return Execute(s.c_str(),disp);
}

void TimeCount::Reset(){
  struct tms buffer;
  times(&buffer);
  TicksComp=(buffer.tms_utime+buffer.tms_stime);

  struct timeval tp;
  struct timezone tzp ;
  gettimeofday( &tp,&tzp ) ;
  TicksElapsed = tp.tv_sec*100+tp.tv_usec/10000 ;
}

long TimeCount::GetCompTime(){
  struct tms buffer;
  times(&buffer);
//  cout << buffer.tms_utime << ' ' << buffer.tms_stime << ' ' << buffer.tms_cutime << ' ' << buffer.tms_cstime << '\n';
  long msec = (buffer.tms_utime+buffer.tms_stime) - TicksComp;
  return msec/* *5/3*/;
}

long TimeCount::GetElapsedTime(){
  struct timeval tp;
  struct timezone tzp ;
  gettimeofday( &tp,&tzp ) ;
  long msec = tp.tv_sec*100+tp.tv_usec/10000 - TicksElapsed;
  return msec;
}


ostream& operator<<(ostream& s, TimeCount & TC){
  long tc=TC.GetCompTime();
  return s << tc / 100 << '.' << setw(2) << setfill('0') << tc % 100 << setfill(' ');
}

void TimeCount::Print(){
  long tc=GetCompTime();
  long te=GetElapsedTime();
  cout << "Computation time:" << setw(8) << tc / 100 << '.' << setw(2) << setfill('0') << tc % 100 << setfill(' ') << endl;
  cout << "Elapsed time:    " << setw(8) << te / 100 << '.' << setw(2) << setfill('0') << te % 100 << setfill(' ') << endl;
}

void TimeCount::PrintElapsed(int w){
  long te=GetElapsedTime();
  if (w>0) cout << setw(w);
  cout << te / 100 << '.' << setw(2) << setfill('0') << te % 100 << setfill(' ');
}

string TimeCount::ElapsedTimeString(){
  long te=GetElapsedTime();
  ostringstream oss;
  oss << te / 100 << '.' << setw(2) << setfill('0') << te % 100 << setfill(' ');
  return oss.str();
}

bool ConfigFile::GetValue(const char *info, const char *val){
  bool debug=true;
  for (int i=0;i<ItemNum;i++){
    char *WS=(char *)info;
    WS++;
    if (strcmp(WS,Item[i]->info.c_str())==0){
      Item[i]->SetValue(val);
      if (debug) {
	cout << Item[i]->info << " ";
	Item[i]->Print(cout);
	cout << endl;
      }
      return true;
    }
  }
  return false;
}

void VectorItem::SetValue(const char *val){
  istringstream is(val);
  int d; 
  is >> d; (*pvalue).resize(d); for (int i=1;i<=d;i++) is >> (*pvalue)(i); 
}


void ConfigFile::Read(string FN){
  bool debug=!true;
  Define();
  ifstream InFile(FN.c_str());
  if (!InFile){
    cout << "File " << FN << " not found." << endl;
    return;
  }
  cout << "Reading " << FN << endl;
  char ch;
  // check if all fields have different names
  for (int i=0;i<ItemNum;i++)
    for (int j=i+1;j<ItemNum;j++){
      if (Item[i]->info==Item[j]->info) cout << "ERROR: Field " << Item[i]->info << " already exists\n";
    }
  while (InFile.get(ch)){
    switch (ch){
      case '#': // a comment sign
        break;
      default:
        InFile.putback(ch);
        string str;
        InFile >> str;
        if (debug) cout << str << endl;
        for (int i=0;i<ItemNum;i++)
          if (str==Item[i]->info) {
            Item[i]->SetValue(InFile);
            if (debug) {
              cout << Item[i]->info << " ";
              Item[i]->Print(cout);
              cout << endl;
            }
          }
    }
    while (InFile.get(ch) && ch!='\n'); // skip the rest of line
  }
  InFile.close();
  //  for (int i=0;i<ItemNum;i++) cout << Item[i].info << " " << Item[i] << endl;
}

void ConfigFile::Save(string FN){
  Define();
  cout << "Saving " << FN << endl;
  ofstream OutFile(FN.c_str());
  for (int i=0;i<ItemNum;i++) {
    OutFile << Item[i]->info << " ";
    Item[i]->Print(OutFile);
    OutFile << endl;
  }
  OutFile << "# " << ItemNum << endl;
  OutFile.close();
}

string ScalarToLatexString(double x, int width1, int width2){
  if (x==0.0){
    ostringstream oss;
    oss << setw(width1+width2+12) << 0;
    return oss.str();   
  }
  ostringstream oss;
  /*
  double absx=abs(x);
  int e=0;
  for (;;){
    if (absx==0.0) break;
    if (absx>=1.0 && absx<10.0) break;
    if (absx<1.0){e--; absx*=10.0; continue;}
    if (absx>=10.0){e++; absx*=0.1; continue;}
  }
  if (x<0) absx=-absx;
  oss << "\\real{" << std::fixed << setprecision(width1) << setw(width1) << absx << "}{" << setw(width2) << e << "}";
  */
  int exp = (x == 0) ? 0 : (int)floor(log10(abs(x)));
  oss << "$\\real{" << std::fixed << setprecision(width1) << setw(width1) << x * pow(10,-exp) << "}{" << setw(width2) << exp << "}$";
  return oss.str();
}