Logo Search packages:      
Sourcecode: libqalculate version File versions  Download package

util.cc

/*
    Qalculate    

    Copyright (C) 2003-2006  Niklas Knutsson (nq@altern.org)

    This program is free software; you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
    the Free Software Foundation; either version 2 of the License, or
    (at your option) any later version.
*/

#include "support.h"

#include "util.h"
#include <stdarg.h>
#include "Number.h"

#include <glib.h>
#include <time.h>
#include <sys/types.h>
#include <unistd.h>
#include <pwd.h>


bool eqstr::operator()(const char *s1, const char *s2) const {
      return strcmp(s1, s2) == 0;
}

char buffer[20000];

string date2s(int year, int month, int day) {
      string str = i2s(year);
      str += "-";
      if(month < 10) {
            str += "0";
      }
      str += i2s(month);
      str += "-";
      if(day < 10) {
            str += "0";
      }
      str += i2s(day);
      return str;
}
void now(int &hour, int &min, int &sec) {
      time_t t = time(NULL);
      struct tm *lt = localtime(&t);
      hour = lt->tm_hour;
      min = lt->tm_min;
      sec = lt->tm_sec;
}
void today(int &year, int &month, int &day) {
      GDate *gtime = g_date_new();
      g_date_set_time(gtime, time(NULL));
      year = g_date_get_year(gtime);
      month = g_date_get_month(gtime);
      day = g_date_get_day(gtime);
      g_date_free(gtime);
}
bool s2date(string str, GDate *gtime) {
/*    if(strptime(str.c_str(), "%x", time) || strptime(str.c_str(), "%Ex", time) || strptime(str.c_str(), "%Y-%m-%d", time) || strptime(str.c_str(), "%m/%d/%Y", time) || strptime(str.c_str(), "%m/%d/%y", time)) {
            return true;
      }*/
      //char *date_format = nl_langinfo(D_FMT);
      g_date_set_parse(gtime, str.c_str());
      return g_date_valid(gtime);
}

int week(string str, bool start_sunday) {
      remove_blank_ends(str);
      GDate *gtime = g_date_new();
      bool b = false;
      if(str == _("today") || str == "today") {
            g_date_set_time(gtime, time(NULL));
            b = true;
      } else if(str == _("now") || str == "now") {
            g_date_set_time(gtime, time(NULL));
            b = true;
      } else {
            b = s2date(str, gtime);
      }
      int week = -1;
      if(b) {
            if(start_sunday) {
                  week = g_date_get_sunday_week_of_year(gtime);
            } else {
                  if(g_date_get_month(gtime) == G_DATE_DECEMBER && g_date_get_day(gtime) >= 29 && g_date_get_weekday(gtime) <= g_date_get_day(gtime) - 28) {
                        week = 1;
                  } else {
                        calc_week_1:
                        int day = g_date_get_day_of_year(gtime);
                        g_date_set_day(gtime, 1);
                        g_date_set_month(gtime, G_DATE_JANUARY);
                        int wday = g_date_get_weekday(gtime);
                        day -= (8 - wday);
                        if(wday <= 4) {
                              week = 1;
                        } else {
                              week = 0;
                        }
                        if(day > 0) {
                              day--;
                              week += day / 7 + 1;
                        }
                        if(week == 0) {
                              int year = g_date_get_year(gtime);
                              g_date_set_dmy(gtime, 31, G_DATE_DECEMBER, year - 1);
                              goto calc_week_1;
                        }
                  }
            }
      }
      g_date_free(gtime);
      return week;
}
int weekday(string str) {
      remove_blank_ends(str);
      GDate *gtime = g_date_new();
      bool b = false;
      if(str == _("today") || str == "today") {
            g_date_set_time(gtime, time(NULL));
            b = true;
      } else if(str == _("now") || str == "now") {
            g_date_set_time(gtime, time(NULL));
            b = true;   
      } else {
            b = s2date(str, gtime);
      }
      int day = -1;
      if(b) {
            day = g_date_get_weekday(gtime);
      }
      g_date_free(gtime);
      return day;
}
int yearday(string str) {
      remove_blank_ends(str);
      GDate *gtime = g_date_new();
      bool b = false;
      if(str == _("today") || str == "today") {
            g_date_set_time(gtime, time(NULL));
            b = true;
      } else if(str == _("now") || str == "now") {
            g_date_set_time(gtime, time(NULL));
            b = true;
      } else {
            b = s2date(str, gtime);
      }
      int day = -1;
      if(b) {
            day = g_date_get_day_of_year(gtime);
      }
      g_date_free(gtime);
      return day;
}

bool s2date(string str, int &year, int &month, int &day) {
      //struct tm time;
      remove_blank_ends(str);
      if(str == _("today") || str == "today") {
            today(year, month, day);
            return true;
      } else if(str == _("now") || str == "now") {
            today(year, month, day);
            return true;
      }
      GDate *gtime = g_date_new();
      bool b = s2date(str, gtime);
      if(b) {
/*          year = time.tm_year + 1900;
            month = time.tm_mon + 1;
            day = time.tm_mday;     */
            year = g_date_get_year(gtime);
            month = g_date_get_month(gtime);
            day = g_date_get_day(gtime);
            g_date_free(gtime);
            return true;
      }
      g_date_free(gtime);
      return false;
}
bool isLeapYear(int year) {
      return year % 4 == 0 && (year % 100 != 0 || year % 400 == 0);
}
int daysPerYear(int year, int basis) {
      switch(basis) {
            case 0: {
                  return 360;
            }
            case 1: {
                  if(isLeapYear(year)) {
                        return 366;
                  } else {
                        return 365;
                  }
            }
            case 2: {
                  return 360;
            }           
            case 3: {
                  return 365;
            } 
            case 4: {
                  return 360;
            }
      }
      return -1;
}

int daysPerMonth(int month, int year) {
      switch(month) {
            case 1: {} case 3: {} case 5: {} case 7: {} case 8: {} case 10: {} case 12: {
                  return 31;
            }
            case 2:     {
                  if(isLeapYear(year)) return 29;
                  else return 28;
            }                       
            default: {
                  return 30;
            }
      }
}     

Number yearsBetweenDates(string date1, string date2, int basis, bool date_func) {
      if(basis < 0 || basis > 4) return -1;
      if(basis == 1) {
            int day1, day2, month1, month2, year1, year2;
            if(!s2date(date1, year1, month1, day1)) {
                  return -1;
            }
            if(!s2date(date2, year2, month2, day2)) {
                  return -1;
            }           
            if(year1 > year2 || (year1 == year2 && month1 > month2) || (year1 == year2 && month1 == month2 && day1 > day2)) {
                  int year3 = year1, month3 = month1, day3 = day1;
                  year1 = year2; month1 = month2; day1 = day2;
                  year2 = year3; month2 = month3; day2 = day3;          
            }           
            int days = 0;
            if(year1 == year2) {
                  days = daysBetweenDates(year1, month1, day1, year2, month2, day2, basis, date_func);
                  if(days < 0) return -1;
                  return Number(days, daysPerYear(year1, basis));
            }
            for(int month = 12; month > month1; month--) {
                  days += daysPerMonth(month, year1);
            }
            days += daysPerMonth(month1, year1) - day1 + 1;
/*          Number *nr = new Number(days, daysPerYear(year1, basis));
            year1++;
            if(year1 != year2) {
                  Number yfr(year2 - year1);
                  nr->add(&yfr);
            }
            days = 0;*/
            for(int month = 1; month < month2; month++) {
                  days += daysPerMonth(month, year2);
            }
            days += day2 - 1;
            int days_of_years = 0;
            for(int year = year1; year <= year2; year++) {
                  days_of_years += daysPerYear(year, basis);
                  if(year != year1 && year != year2) {
                        days += daysPerYear(year, basis);
                  }
            }
            Number year_frac(days_of_years, year2 + 1 - year1);
/*          if(days > 0) {
                  Number nr2(days, daysPerYear(year2, basis));
                  nr->add(&nr2);
            }*/
            Number nr(days);
            nr /= year_frac;
            return nr;
      } else {
            int days = daysBetweenDates(date1, date2, basis, date_func);
            if(days < 0) return -1;
            return Number(days, daysPerYear(0, basis));     
      }
      return -1;
}
int daysBetweenDates(string date1, string date2, int basis, bool date_func) {
      int day1, day2, month1, month2, year1, year2;
      if(!s2date(date1, year1, month1, day1)) {
            return -1;
      }
      if(!s2date(date2, year2, month2, day2)) {
            return -1;
      }
      return daysBetweenDates(year1, month1, day1, year2, month2, day2, basis, date_func);      
}
int daysBetweenDates(int year1, int month1, int day1, int year2, int month2, int day2, int basis, bool date_func) {
      if(basis < 0 || basis > 4) return -1;
      bool isleap = false;
      int days, months, years;

      if(year1 > year2 || (year1 == year2 && month1 > month2) || (year1 == year2 && month1 == month2 && day1 > day2)) {
            int year3 = year1, month3 = month1, day3 = day1;
            year1 = year2; month1 = month2; day1 = day2;
            year2 = year3; month2 = month3; day2 = day3;          
      }

      years = year2  - year1;
      months = month2 - month1 + years * 12;
      days = day2 - day1;

      isleap = isLeapYear(year1);

      switch(basis) {
            case 0: {
                  if(date_func) {
                        if(month1 == 2 && ((day1 == 28 && !isleap) || (day1 == 29 && isleap)) && !(month2 == month1 && day1 == day2 && year1 == year2)) {
                              if(isleap) return months * 30 + days - 1;
                              else return months * 30 + days - 2;
                        }
                        if(day1 == 31 && day2 < 31) days++;
                  } else {
                        if(month1 == 2 && month2 != 2 && year1 == year2) {
                              if(isleap) return months * 30 + days - 1;
                              else return months * 30 + days - 2;
                        }                 
                  }
                  return months * 30 + days;
            }
            case 1: {}
            case 2: {}        
            case 3: {
                  int month4 = month2;
                  bool b;
                  if(years > 0) {
                        month4 = 12;
                        b = true;
                  } else {
                        b = false;
                  }
                  for(; month1 < month4 || b; month1++) {
                        if(month1 > month4 && b) {
                              b = false;
                              month1 = 1;
                              month4 = month2;
                              if(month1 == month2) break;
                        }
                        if(!b) {
                              days += daysPerMonth(month1, year2);
                        } else {
                              days += daysPerMonth(month1, year1);
                        }
                  }
                  if(years == 0) return days;
                  //if(basis == 1) {
                        for(year1 += 1; year1 < year2; year1++) {
                              if(isLeapYear(year1)) days += 366;
                              else days += 365;
                        } 
                        return days;
                  //}
                  //if(basis == 2) return (years - 1) * 360 + days;           
                  //if(basis == 3) return (years - 1) * 365 + days;
            } 
            case 4: {
                  if(date_func) {
                        if(day2 == 31 && day1 < 31) days--;
                        if(day1 == 31 && day2 < 31) days++;
                  }
                  return months * 30 + days;
            }
      }
      return -1;
      
}

string& gsub(const string &pattern, const string &sub, string &str) {
      size_t i = str.find(pattern);
      while(i != string::npos) {
            str.replace(i, pattern.length(), sub);
            i = str.find(pattern, i + sub.length());
      }
      return str;
}
string& gsub(const char *pattern, const char *sub, string &str) {
      size_t i = str.find(pattern);
      while(i != string::npos) {
            str.replace(i, strlen(pattern), string(sub));
            i = str.find(pattern, i + strlen(sub));
      }
      return str;
}

string& remove_blanks(string &str) {
      size_t i = str.find_first_of(SPACES, 0);
      while(i != string::npos) {
            str.erase(i, 1);
            i = str.find_first_of(SPACES, i);
      }
      return str;
}

string& remove_duplicate_blanks(string &str) {
      size_t i = str.find_first_of(SPACES, 0);
      while(i != string::npos) {
            if(i == 0 || is_in(SPACES, str[i - 1])) {
                  str.erase(i, 1);
            } else {
                  i++;
            }
            i = str.find_first_of(SPACES, i);
      }
      return str;
}

string& remove_blank_ends(string &str) {
      size_t i = str.find_first_not_of(SPACES);
      size_t i2 = str.find_last_not_of(SPACES);
      if(i != string::npos && i2 != string::npos) {
            if(i > 0 || i2 < str.length() - 1) {
                  str = str.substr(i, i2 - i + 1);
            }
      } else {
            str.resize(0);
      }
      return str;
}
string& remove_parenthesis(string &str) {
      if(str[0] == LEFT_PARENTHESIS_CH && str[str.length() - 1] == RIGHT_PARENTHESIS_CH) {
            str = str.substr(1, str.length() - 2);
            return remove_parenthesis(str);
      }
      return str;
}

string d2s(double value, int precision) {
      //      qgcvt(value, precision, buffer);
      sprintf(buffer, "%.*G", precision, value);
      string stmp = buffer;
      //      gsub("e", "E", stmp);
      return stmp;
}

string p2s(void *o) {
      sprintf(buffer, "%p", o);
      string stmp = buffer;
      return stmp;
}
string i2s(int value) {
      //      char buffer[10];
      sprintf(buffer, "%i", value);
      string stmp = buffer;
      return stmp;
}
string i2s(long int value) {
      sprintf(buffer, "%li", value);
      string stmp = buffer;
      return stmp;
}
string i2s(unsigned int value) {
      sprintf(buffer, "%u", value);
      string stmp = buffer;
      return stmp;
}
string i2s(unsigned long int value) {
      sprintf(buffer, "%lu", value);
      string stmp = buffer;
      return stmp;
}
const char *b2yn(bool b, bool capital) {
      if(capital) {
            if(b) return _("Yes");
            return _("No");
      }
      if(b) return _("yes");
      return _("no");
}
const char *b2tf(bool b, bool capital) {
      if(capital) {
            if(b) return _("True");
            return _("False");
      }
      if(b) return _("true");
      return _("false");
}
const char *b2oo(bool b, bool capital) {
      if(capital) {
            if(b) return _("On");
            return _("Off");
      }
      if(b) return _("on");
      return _("off");
}
int s2i(const string& str) {
      return strtol(str.c_str(), NULL, 10);
}
int s2i(const char *str) {
      return strtol(str, NULL, 10);
}
void *s2p(const string& str) {
      void *p;
      sscanf(str.c_str(), "%p", &p);
      return p;
}
void *s2p(const char *str) {
      void *p;
      sscanf(str, "%p", &p);
      return p;
}

size_t find_ending_bracket(const string &str, size_t start, int *missing) {
      int i_l = 1;
      while(true) {
            start = str.find_first_of(LEFT_PARENTHESIS RIGHT_PARENTHESIS, start);
            if(start == string::npos) {
                  if(missing) *missing = i_l;
                  return string::npos;
            }
            if(str[start] == LEFT_PARENTHESIS_CH) {
                  i_l++;
            } else {
                  i_l--;
                  if(!i_l) {
                        if(missing) *missing = i_l;
                        return start;
                  }
            }
            start++;
      }
}

char op2ch(MathOperation op) {
      switch(op) {
            case OPERATION_ADD: return PLUS_CH;
            case OPERATION_SUBTRACT: return MINUS_CH;       
            case OPERATION_MULTIPLY: return MULTIPLICATION_CH;          
            case OPERATION_DIVIDE: return DIVISION_CH;            
            case OPERATION_RAISE: return POWER_CH;          
            case OPERATION_EXP10: return EXP_CH;
            default: return ' ';          
      }
}

string& wrap_p(string &str) {
      str.insert(str.begin(), 1, LEFT_PARENTHESIS_CH);
      str += RIGHT_PARENTHESIS_CH;
      return str;
}

bool is_in(const char *str, char c) {
      for(size_t i = 0; i < strlen(str); i++) {
            if(str[i] == c)
                  return true;
      }
      return false;
}
bool is_not_in(const char *str, char c) {
      for(size_t i = 0; i < strlen(str); i++) {
            if(str[i] == c)
                  return false;
      }
      return true;
}
bool is_in(const string &str, char c) {
      for(size_t i = 0; i < str.length(); i++) {
            if(str[i] == c)
                  return true;
      }
      return false;
}
bool is_not_in(const string &str, char c) {
      for(size_t i = 0; i < str.length(); i++) {
            if(str[i] == c)
                  return false;
      }
      return true;
}

int sign_place(string *str, size_t start) {
      size_t i = str->find_first_of(OPERATORS, start);
      if(i != string::npos)
            return i;
      else
            return -1;
}

int gcd(int i1, int i2) {
      if(i1 < 0) i1 = -i1;
      if(i2 < 0) i2 = -i2;
      if(i1 == i2) return i2;
      int i3;
      if(i2 > i1) {
            i3 = i2;
            i2 = i1;
            i1 = i3;
      }
      while((i3 = i1 % i2) != 0) {
            i1 = i2;
            i2 = i3;
      }
      return i2;
}

size_t unicode_length(const string &str) {
      size_t l = str.length(), l2 = 0;
      for(size_t i = 0; i < l; i++) {
            if(str[i] > 0 || (unsigned char) str[i] >= 0xC2) {
                  l2++;
            }
      }
      return l2;
}
size_t unicode_length(const char *str) {
      size_t l = strlen(str), l2 = 0;
      for(size_t i = 0; i < l; i++) {
            if(str[i] > 0 || (unsigned char) str[i] >= 0xC2) {
                  l2++;
            }
      }
      return l2;
}

bool text_length_is_one(const string &str) {
      if(str.empty()) return false;
      if(str.length() == 1) return true;
      if(str[0] >= 0) return false;
      for(size_t i = 1; i < str.length(); i++) {
            if(str[i] > 0 || (unsigned char) str[i] >= 0xC2) {
                  return false;
            }
      }
      return true;
}

bool equalsIgnoreCase(const string &str1, const string &str2) {
      if(str1.length() != str2.length()) return false;
      for(size_t i = 0; i < str1.length(); i++) {
            if(str1[i] < 0 && i + 1 < str1.length()) {
                  if(str2[i] >= 0) return false;
                  int i2 = 1;
                  while(i2 + i < str1.length() && str1[i2 + i] < 0) {
                        if(str2[i2 + i] >= 0) return false;
                        i2++;
                  }
                  gchar *gstr1 = g_utf8_strdown(str1.c_str() + (sizeof(char) * i), i2);
                  gchar *gstr2 = g_utf8_strdown(str2.c_str() + (sizeof(char) * i), i2);
                  if(strcmp(gstr1, gstr2) != 0) return false;
                  g_free(gstr1);
                  g_free(gstr2);
                  i += i2 - 1;
            } else if(str1[i] != str2[i] && !((str1[i] >= 'a' && str1[i] <= 'z') && str1[i] - 32 == str2[i]) && !((str1[i] <= 'Z' && str1[i] >= 'A') && str1[i] + 32 == str2[i])) {
                  return false;
            }
      }
      return true;
}

bool equalsIgnoreCase(const string &str1, const char *str2) {
      if(str1.length() != strlen(str2)) return false;
      for(size_t i = 0; i < str1.length(); i++) {
            if(str1[i] < 0 && i + 1 < str1.length()) {
                  if(str2[i] >= 0) return false;
                  int i2 = 1;
                  while(i2 + i < str1.length() && str1[i2 + i] < 0) {
                        if(str2[i2 + i] >= 0) return false;
                        i2++;
                  }
                  gchar *gstr1 = g_utf8_strdown(str1.c_str() + (sizeof(char) * i), i2);
                  gchar *gstr2 = g_utf8_strdown(str2 + (sizeof(char) * i), i2);
                  if(strcmp(gstr1, gstr2) != 0) return false;
                  g_free(gstr1);
                  g_free(gstr2);
                  i += i2 - 1;
            } else if(str1[i] != str2[i] && !((str1[i] >= 'a' && str1[i] <= 'z') && str1[i] - 32 == str2[i]) && !((str1[i] <= 'Z' && str1[i] >= 'A') && str1[i] + 32 == str2[i])) {
                  return false;
            }
      }
      return true;
}

void parse_qalculate_version(string qalculate_version, int *qalculate_version_numbers) {
      for(size_t i = 0; i < 3; i++) {
            size_t dot_i = qalculate_version.find(".");
            if(dot_i == string::npos) {
                  qalculate_version_numbers[i] = s2i(qalculate_version);
                  break;
            }
            qalculate_version_numbers[i] = s2i(qalculate_version.substr(0, dot_i));
            qalculate_version = qalculate_version.substr(dot_i + 1, qalculate_version.length() - (dot_i + 1));
      }
}

string getLocalDir() {
      string homedir = "";
      struct passwd *pw = getpwuid(getuid());
      if(pw) {
            homedir = pw->pw_dir;
            homedir += "/";
      }
      homedir += ".qalculate/";
      return homedir;
}


Generated by  Doxygen 1.6.0   Back to index