#include "warning.h"
#include "var.h"
#include "constants.h"
#include "config.h"
#include <ctype.h>
#include <cstdio>
#include <stdlib.h>
#include <cstring>
#ifdef HAVE_REGEX_H
#include <regex.h>
#endif
#include "array.h"
using namespace std;
namespace blop
{
var &var::replace_re(const var &pattern, const var &replacement_var)
{
#ifdef HAVE_REGEX_H
string replacement = replacement_var.str();
regex_t preg;
int result = regcomp(&preg,pattern.c_str(),REG_EXTENDED);
if(result != 0)
{
char errbuf[300];
regerror(result,&preg,errbuf,299);
regfree(&preg);
warning::print(var("Failed to compile regex pattern: ") & errbuf,
"var::matches(const var &pattern)");
return *this;
}
regmatch_t regmatches[100];
result = regexec(&preg,c_str(),100,regmatches,0);
if(result != 0) return *this;
int nmatches = 0;
for(; nmatches<100 && regmatches[nmatches].rm_so>=0; ++nmatches);
for(string::size_type i=0; i<replacement.size(); ++i)
{
if(replacement[i] != '\\') continue;
if(i>0 && replacement[i-1] == '\\') continue;
string::size_type end = i+1;
for(; end<replacement.size() && isdigit(replacement[end]); ++end);
if(end != i+1)
{
int ref = atoi(replacement.substr(i+1,end-(i+1)).c_str());
if(ref<nmatches)
{
string submatch =
string_.substr(regmatches[ref].rm_so,
regmatches[ref].rm_eo-regmatches[ref].rm_so);
replacement.replace(i,end-i,submatch);
i += submatch.size()-1;
}
}
}
string_.replace(regmatches[0].rm_so,
regmatches[0].rm_eo-regmatches[0].rm_so,
replacement);
double_ = atof(string_.c_str());
regfree(&preg);
#else
warning::print("<regex.h> missing, therefore this function is not supported",
"var::replace_re(const var &pattern, const var &replacement)");
#endif
return *this;
}
bool var::matches(const var &pattern)
{
#ifdef HAVE_REGEX_H
regex_t preg;
int result = regcomp(&preg,pattern.c_str(),REG_EXTENDED|REG_NOSUB);
if(result != 0)
{
char errbuf[300];
regerror(result,&preg,errbuf,299);
regfree(&preg);
warning::print(var("Failed to compile regex pattern: ") & errbuf,
"var::matches(const var &pattern)");
return false;
}
regmatch_t regmatches;
result = regexec(&preg,c_str(),1,®matches,0);
regfree(&preg);
return result==0;
#else
warning::print("<regex.h> missing, therefore this function is not supported",
"var::matches(const var &pattern, array &matches)");
return false;
#endif
}
int var::matches(const var &pattern,array &the_matches)
{
#ifdef HAVE_REGEX_H
the_matches.clear();
regex_t preg;
int result = regcomp(&preg,pattern.c_str(),REG_EXTENDED);
if(result != 0)
{
char errbuf[300];
regerror(result,&preg,errbuf,299);
regfree(&preg);
warning::print(var("Failed to compile regex pattern: ") & errbuf,
"var::matches(const var &pattern)");
return false;
}
regmatch_t regmatches[100];
result = regexec(&preg,c_str(),100,regmatches,0);
if(result != 0) return 0;
for(int i=0; i<100 && regmatches[i].rm_so>=0; ++i)
{
the_matches.push_back(str().substr(regmatches[i].rm_so,
regmatches[i].rm_eo-regmatches[i].rm_so));
}
regfree(&preg);
return the_matches.size();
#else
warning::print("<regex.h> missing, therefore this function is not supported",
"var::matches(const var &pattern, array &matches)");
return 0;
#endif
}
string &var::default_format_()
{
static string f = "%g";
return f;
}
char var::back() const
{
if(string_.size() == 0) return '\0';
return string_[string_.size()-1];
}
char var::pop_back()
{
if(string_.size() == 0) return '\0';
char c = string_[string_.size()-1];
string_.resize(string_.size()-1);
return c;
}
char var::operator[] (int i) const
{
return string_[i];
}
var::var() {double_ = 0; string_ = ""; format_ = default_format_();}
var::var(const string &s) {format_ = default_format_(); *this = s; }
var::var(double d) { format_ = default_format_(); *this = d; }
var::var(long double d) { format_ = default_format_(); *this = (double)d; }
var::var(double d, const var &fmt) { format_ = fmt.str(); *this = d; }
var::var(int i) {format_ = default_format_(); *this = i; }
var::var(long int i) {format_ = default_format_(); *this = (int)i; }
var::var(unsigned int i) {format_ = default_format_(); *this = i; }
var::var(const var &other) { format_ = other.format_; *this = other; }
var::var(const char *s) { format_ = default_format_(); if(s == 0) *this = ""; else *this = s; }
var::var(char c) { format_ = default_format_(); *this = c; }
var &var::format(const var &f) {format_ = f.str(); return *this; }
void var::default_format(const var &f) {default_format_() = f.str(); }
bool var::is_int() const
{
if(string_.empty()) return false;
if(string_[0] == '-' && string_.size() == 1) return false;
if(string_[0] != '-' && !isdigit(string_[0])) return false;
for(unsigned int i=1; i<string_.size(); ++i) if(!isdigit(string_[i])) return false;
return true;
}
bool var::is_dbl() const
{
if(string_.empty()) return false;
const char *c = string_.c_str();
char *endptr;
(void)strtod(c,&endptr);
if(endptr == c + string_.size()) return true;
return false;
}
const var &var::operator= (const string &s)
{
if(s == "nan") double_ = 0;
else if(s == "inf") double_ = 0;
else double_ = atof(s.c_str());
string_ = s;
return *this;
}
const var &var::operator= (const char *s)
{
if(s == 0)
{
double_ = 0;
string_ = "";
return *this;
}
if(!strcmp(s,"nan")) double_ = 0;
else if(!strcmp(s,"inf")) double_ = 0;
else double_ = atof(s);
string_ = s;
return *this;
}
const var &var::operator= (char c)
{
string_ = c;
double_ = atof(string_.c_str());
return *this;
}
const var &var::operator= (double d)
{
double_ = d;
if(d == unset) string_ = "unset";
else
{
char s[1000];
sprintf(s,format_.c_str(),d);
string_ = s;
}
return *this;
}
const var &var::operator= (int i)
{
double_ = i;
char s[1000];
sprintf(s,"%i",i);
string_ = s;
return *this;
}
const var &var::operator= (unsigned int i)
{
double_ = i;
char s[1000];
sprintf(s,"%i",i);
string_ = s;
return *this;
}
const var &var::operator= (const var &o)
{
double_ = o.double_;
string_ = o.string_;
return *this;
}
const var &var::operator+= (double d)
{
double_ += d;
char s[1000];
sprintf(s,format_.c_str(),double_);
string_ = s;
return *this;
}
const var &var::operator+= (const string &s)
{
double ddd = atof(s.c_str());
operator+=(ddd);
return *this;
}
const var &var::operator+= (const var &o)
{
operator+=(o.double_);
return *this;
}
const var &var::operator+= (int i)
{
if(!is_int())
{
operator += ((double)i);
return *this;
}
int old_value = atoi(string_.c_str());
int new_value = old_value + i;
double_ = new_value;
char s[1000];
if(string_[0] == '0')
{
int old_size = string_.size();
char format[100];
sprintf(format,"%%0%ii",old_size);
sprintf(s,format,new_value);
string_ = s;
}
else
{
sprintf(s,"%i",new_value);
string_ = s;
}
return *this;
}
const var &var::operator-= (double d)
{
double_ -= d;
char s[1000];
sprintf(s,format_.c_str(),double_);
string_ = s;
return *this;
}
const var &var::operator-= (int i)
{
operator += (-i);
return *this;
}
const var &var::operator-= (const string &s)
{
double ddd = atof(s.c_str());
operator-=(ddd);
return *this;
}
const var &var::operator-= (const var &o)
{
operator-=(o.double_);
return *this;
}
const var &var::operator*= (double d)
{
double_ *= d;
char s[1000];
sprintf(s,format_.c_str(),double_);
string_ = s;
return *this;
}
const var &var::operator*= (int i)
{
double_ *= i;
char s[1000];
sprintf(s,format_.c_str(),double_);
string_ = s;
return *this;
}
const var &var::operator*= (const string &s)
{
double ddd = atof(s.c_str());
operator*=(ddd);
return *this;
}
const var &var::operator*= (const var &v)
{
operator*=(v.double_);
return *this;
}
const var &var::operator/= (double d)
{
double_ /= d;
char s[1000];
sprintf(s,format_.c_str(),double_);
string_ = s;
return *this;
}
const var &var::operator/= (int i)
{
double_ /= i;
char s[1000];
sprintf(s,format_.c_str(),double_);
string_ = s;
return *this;
}
const var &var::operator/= (const string &s)
{
double ddd = atof(s.c_str());
operator/=(ddd);
return *this;
}
const var &var::operator/= (const var &v)
{
operator/=(v.double_);
return *this;
}
const var &var::operator++ ()
{
*this += 1;
return *this;
}
var var::operator++ (int)
{
var tmp = *this;
*this += 1;
return tmp;
}
const var &var::operator-- ()
{
*this -= 1;
return *this;
}
var var::operator-- (int)
{
var tmp = *this;
*this -= 1;
return tmp;
}
const var &var::operator&= (const string &s)
{
string_ += s;
double_ = atof(string_.c_str());
return *this;
}
const var &var::operator&= (const char *s)
{
string_ += s;
double_ = atof(string_.c_str());
return *this;
}
const var &var::operator&= (char c)
{
string_ += c;
double_ = atof(string_.c_str());
return *this;
}
const var &var::operator&= (double d)
{
char s[100];
sprintf(s,default_format_().c_str(),d);
string_ += s;
double_ = atof(string_.c_str());
return *this;
}
const var &var::operator&= (int i)
{
char s[100];
sprintf(s,"%i",i);
string_ += s;
double_ = atof(string_.c_str());
return *this;
}
const var &var::operator&= (const var &v)
{
operator&=(v.string_);
return *this;
}
var::operator bool () const
{
if(string_ == "" ||
string_ == "0") return false;
return true;
}
int var::integer() const
{
return (int)(double_);
}
const char *var::c_str() const
{
return string_.c_str();
}
var replace_re(const var &pattern, const var &replacement, const var &in)
{
var tmp = in;
tmp.replace_re(pattern, replacement);
return tmp;
}
var replace(const var &from, const var &to, const var &in)
{
var tmp = in;
tmp.replace(from,to);
return tmp;
}
var replace1(const var &from, const var &to, const var &in)
{
var tmp = in;
tmp.replace1(from,to);
return tmp;
}
var abs(var v)
{
if(v.string_[0] != '-' && v.double_ >= 0) return v;
if(v.string_[0] == '-' && v.double_ < 0)
{
v.double_ = -v.double_;
v.string_.erase(0,1);
return v;
}
warning::print("Inconsistency between string/double representation ",
"abs(const var &)");
return v;
}
bool operator< (const blop::var &v,double d)
{
return v.dbl() < d;
}
bool operator< (const blop::var &v,int i)
{
return v.dbl() < i;
}
bool operator< (double d,const blop::var &v)
{
return d < v.dbl();
}
bool operator< (int i,const blop::var &v)
{
return i < v.dbl();
}
bool operator< (const blop::var &v1,const blop::var &v2)
{
return v1.dbl() < v2.dbl();
}
bool operator<= (const blop::var &v,double d)
{
return v.dbl() <= d;
}
bool operator<= (const blop::var &v,int i)
{
return v.dbl() <= i;
}
bool operator<= (double d,const blop::var &v)
{
return d <= v.dbl();
}
bool operator<= (int i,const blop::var &v)
{
return i <= v.dbl();
}
bool operator<= (const blop::var &v1,const blop::var &v2)
{
return v1.dbl() <= v2.dbl();
}
bool operator> (const blop::var &v,double d)
{
return v.dbl() > d;
}
bool operator> (const blop::var &v,int i)
{
return v.dbl() > i;
}
bool operator> (double d,const blop::var &v)
{
return d > v.dbl();
}
bool operator> (int i,const blop::var &v)
{
return i > v.dbl();
}
bool operator> (const blop::var &v1,const blop::var &v2)
{
return v1.dbl() > v2.dbl();
}
bool operator>= (const blop::var &v,double d)
{
return v.dbl() >= d;
}
bool operator>= (const blop::var &v,int i)
{
return v.dbl() >= i;
}
bool operator>= (double d,const blop::var &v)
{
return d >= v.dbl();
}
bool operator>= (int i,const blop::var &v)
{
return i >= v.dbl();
}
bool operator>= (const blop::var &v1,const blop::var &v2)
{
return v1.dbl() >= v2.dbl();
}
bool operator == (const blop::var &v1,const blop::var &v2)
{
return v1.str() == v2.str();
}
bool operator == (const blop::var &v1,const char *v2)
{
return v1.str() == v2;
}
bool operator == (const char *v1,const blop::var &v2)
{
return v1 == v2.str();
}
bool operator == (const blop::var &v1,const string &v2)
{
return v1.str() == v2;
}
bool operator == (const string &v1,const blop::var &v2)
{
return v1 == v2.str();
}
bool operator == (const blop::var &v1, double d)
{
return v1.dbl() == d;
}
bool operator == (double d, const blop::var &v2)
{
return d == v2.dbl();
}
bool operator == (const blop::var &v1, int i)
{
return v1.dbl() == i;
}
bool operator == (int d, const blop::var &v2)
{
return d == v2.dbl();
}
bool operator != (const blop::var &v1,const blop::var &v2)
{
return !operator==((var)v1,(var)v2);
}
bool operator != (const blop::var &v1,const char *v2)
{
return !operator==(v1,v2);
}
bool operator != (const char *v1,const blop::var &v2)
{
return !operator==(v1,v2);
}
bool operator != (const blop::var &v1,const string &v2)
{
return !operator==(v1,v2);
}
bool operator != (const string &v1,const blop::var &v2)
{
return !operator==(v1,v2);
}
bool operator != (const blop::var &v1, double d)
{
return !operator==(v1,d);
}
bool operator != (double d, const blop::var &v2)
{
return !operator==(d,v2);
}
bool operator != (const blop::var &v1, int d)
{
return !operator==(v1,d);
}
bool operator != (int d, const blop::var &v2)
{
return !operator==(d,v2);
}
var &var::replace(size_type pos, size_type n, const var &s)
{
string_.replace(pos,n,s.str());
double_ = atof(string_.c_str());
return *this;
}
var &var::replace(const var &from,const var &to)
{
string::size_type s1 = from.length();
string::size_type s2 = to.length();
for(string::size_type ind = 0;
(ind = string_.find(from.str(), ind)) != std::string::npos;
ind += s2)
{
string_.replace(ind, s1, to.str());
}
double_ = atof(string_.c_str());
return *this;
}
var &var::replace1(const var &from,const var &to)
{
string::size_type ind = 0;
if( (ind = string_.find(from.str(), ind)) != std::string::npos )
{
string_.replace(ind, from.length(), to.str());
}
double_ = atof(string_.c_str());
return *this;
}
const var::size_type var::npos = std::string::npos;
var::size_type var::size() const
{
return string_.size();
}
var::size_type var::length() const
{
return string_.length();
}
var::size_type var::find(const var &o, var::size_type i) const
{
return string_.find(o.str(),i);
}
var::size_type var::rfind(const var &o, var::size_type i) const
{
return string_.rfind(o.str(),i);
}
var::size_type var::find_first_of(const var &o, size_type i) const
{
return string_.find_first_of(o.str(), i);
}
var::size_type var::find_last_of(const var &o, size_type i) const
{
return string_.find_last_of(o.str(), i);
}
var::size_type var::find_first_not_of(const var &o, size_type i) const
{
return string_.find_first_not_of(o.str(), i);
}
var::size_type var::find_last_not_of(const var &o, size_type i) const
{
return string_.find_last_not_of(o.str(), i);
}
void var::subvar::update_var()
{
var result;
if(from_ > 0) result &= var_->string_.substr(0,from_);
result &= *this;
if(to_ != std::string::npos) result &= var_->string_.substr(to_+1,std::string::npos);
*var_ = result;
}
var::subvar::subvar(var *v,std::string::size_type from,std::string::size_type to)
{
var_ = v;
from_ = from;
to_ = to;
var::operator=( v->string_.substr(from,to-from+1) );
}
var::subvar::subvar(const subvar &o) : var(o)
{
var_ = o.var_;
from_ = o.from_;
to_ = o.to_;
}
var::subvar var::operator() (std::string::size_type from, std::string::size_type to)
{
return subvar(this,from,to);
}
ostream &operator<<(ostream &out,const blop::var &v)
{
out<<v.str();
return out;
}
istream &operator>>(istream &in,blop::var &v)
{
string s;
in>>s;
v = s;
return in;
}
var operator& (const var &v1,const var &v2)
{
var result = v1;
result &= v2;
return result;
}
var operator& (const var &v1,const string &s )
{
var result = v1;
result &= s;
return result;
}
var operator& (const string &s ,const var &v2)
{
var result = s;
result += v2;
return result;
}
var operator& (const var &v1,const char *s )
{
var result = v1;
result &= s;
return result;
}
var operator& (const char *s ,const var &v2)
{
var result = s;
result &= v2;
return result;
}
var operator& (const var &v1,double d )
{
var result = v1;
result &= d;
return result;
}
var operator& (double d ,const var &v2)
{
var result = d;
result &= v2;
return result;
}
var operator& (const string &s1,const string &s2)
{
var result = s1;
result &= s2;
return result;
}
var operator& (const string &s1,const char *s2)
{
var result = s1;
result &= s2;
return result;
}
var operator& (const char *s1,const string &s2)
{
var result = s1;
result &= s2;
return result;
}
var operator& (double d,const string &s)
{
var result = d;
result &= s;
return result;
}
var operator& (const string &s,double d)
{
var result = s;
result &= d;
return result;
}
var operator& (const var &v, int i)
{
var result = v;
result &= i;
return result;
}
var operator& (int i, const var &v)
{
var result = i;
result &= v;
return result;
}
var operator& (const var &v, char c)
{
var result = v;
result &= c;
return result;
}
var operator& (char c, const var &v)
{
var result = c;
result &= v;
return result;
}
}
ostream &operator<<(ostream &out,const blop::var &v)
{
blop::operator<<(out,v);
return out;
}
istream &operator>>(istream &in,blop::var &v)
{
blop::operator>>(in,v);
return in;
}
blop::var pow (const blop::var &a,const blop::var &b)
{
return pow(a.dbl(),b.dbl());
}
blop::var exp (const blop::var &a)
{
return exp(a.dbl());
}
blop::var log (const blop::var &a)
{
return log(a.dbl());
}
blop::var log10(const blop::var &a)
{
return log10(a.dbl());
}
blop::var sqrt (const blop::var &a)
{
return sqrt(a.dbl());
}
blop::var sin (const blop::var &a)
{
return sin(a.dbl());
}
blop::var cos (const blop::var &a)
{
return cos(a.dbl());
}
blop::var asin (const blop::var &a)
{
return asin(a.dbl());
}
blop::var acos (const blop::var &a)
{
return acos(a.dbl());
}
blop::var tan (const blop::var &a)
{
return tan(a.dbl());
}
blop::var atan (const blop::var &a)
{
return atan(a.dbl());
}
blop::var sinh (const blop::var &a)
{
return sinh(a.dbl());
}
blop::var asinh(const blop::var &a)
{
return asinh(a.dbl());
}
blop::var cosh (const blop::var &a)
{
return cosh(a.dbl());
}
blop::var acosh(const blop::var &a)
{
return acosh(a.dbl());
}
#ifdef _BLOP_VAR_ARITHMETIC_OPERATORS_IN_NAMESPACE
namespace blop
{
#endif
blop::var operator+ (const blop::var &v1,const blop::var &v2) {return v1.dbl() + v2.dbl();}
blop::var operator+ (const blop::var &v1,double d) {return v1.dbl() + d;}
blop::var operator+ (double d, const blop::var &v2) {return d + v2.dbl();}
blop::var operator+ (const blop::var &v1, int d) { return v1.dbl() + d; }
blop::var operator+ (int d, const blop::var &v2) { return d + v2.dbl(); }
blop::var operator+ (const blop::var &v1,const string &s)
{
blop::var result = v1;
result += s;
return result;
}
blop::var operator+ (const string &s,const blop::var &v2)
{
blop::var result = s;
result += v2;
return result;
}
blop::var operator+ (const char *s,const blop::var &v2)
{
return string(s) + v2;
}
blop::var operator+ (const blop::var &v2,const char *s)
{
return v2 + string(s);
}
blop::var operator- (const blop::var &v)
{
return - v.dbl();
}
blop::var operator- (const blop::var &v1,const blop::var &v2) {return v1.dbl() - v2.dbl();}
blop::var operator- (const blop::var &v1,double d) {return v1.dbl() - d;}
blop::var operator- (double d, const blop::var &v2) {return d - v2.dbl();}
blop::var operator- (const blop::var &v1, int d) { return v1.dbl() - d; }
blop::var operator- (int d, const blop::var &v2) { return d - v2.dbl(); }
blop::var operator- (const blop::var &v1,const string &s)
{
blop::var result = v1;
result -= s;
return result;
}
blop::var operator- (const string &s,const blop::var &v2)
{
blop::var result = s;
result -= v2;
return result;
}
blop::var operator- (const char *s,const blop::var &v2)
{
return string(s) - v2;
}
blop::var operator- (const blop::var &v2,const char *s)
{
return v2 - string(s);
}
blop::var operator* (const blop::var &v1,const blop::var &v2) {return v1.dbl() * v2.dbl();}
blop::var operator* (const blop::var &v1,double d) {return v1.dbl() * d;}
blop::var operator* (double d, const blop::var &v2) {return d * v2.dbl();}
blop::var operator* (const blop::var &v1, int d) { return v1.dbl() * d; }
blop::var operator* (int d, const blop::var &v2) { return d * v2.dbl(); }
blop::var operator* (const blop::var &v1,const string &s)
{
blop::var result = v1;
result *= s;
return result;
}
blop::var operator* (const string &s,const blop::var &v2)
{
blop::var result = s;
result *= v2;
return result;
}
blop::var operator* (const char *s,const blop::var &v2)
{
return string(s) + v2;
}
blop::var operator* (const blop::var &v2,const char *s)
{
return v2 * string(s);
}
blop::var operator/ (const blop::var &v1,const blop::var &v2) {return v1.dbl() / v2.dbl();}
blop::var operator/ (const blop::var &v1,double d) {return v1.dbl() / d;}
blop::var operator/ (double d, const blop::var &v2) {return d / v2.dbl();}
blop::var operator/ (const blop::var &v1, int d) { return v1.dbl() / d; }
blop::var operator/ (int d, const blop::var &v2) { return d / v2.dbl(); }
blop::var operator/ (const blop::var &v1,const string &s)
{
blop::var result = v1;
result /= s;
return result;
}
blop::var operator/ (const string &s,const blop::var &v2)
{
blop::var result = s;
result /= v2;
return result;
}
blop::var operator/ (const char *s,const blop::var &v2)
{
return string(s) / v2;
}
blop::var operator/ (const blop::var &v2,const char *s)
{
return v2 / string(s);
}
#ifdef _BLOP_VAR_ARITHMETIC_OPERATORS_IN_NAMESPACE
}
#endif