#include "cfg-var.h" #include "str-com.h" #define _CRT_SECURE_NO_DEPRECATE #include <stdio.h> #include <string.h> #include <math.h> // CPP namespace nse { // a = b, b = a template< typename T > void swap_vars(T& a, T& b) { T c = a; a = b; b = c; } // = x^p int ipow(const int x, const int p) { if (p == 0) return 1; if (p == 1) return x; int tmp = ipow(x, p / 2); if (p % 2 == 0) return tmp*tmp; else return x*tmp*tmp; } } // // Implementation: cfgVariable // nse::cfgVariable::cfgVariable( ) : type(IS_UNDEF), eint(0), edouble((double)0), estring(NULL), ebool(false) { name_memsize = 1; name = new char[name_memsize]; *name = '\0'; } nse::cfgVariable::cfgVariable( const char* ex_name, const char* ex_value) : type(IS_UNDEF), eint(0), edouble((double)0), estring(NULL), ebool(false) { name_memsize = 1; name = new char[name_memsize]; *name = '\0'; set(ex_name, ex_value); } nse::cfgVariable::cfgVariable( const char* ex_value) : type(IS_UNDEF), eint(0), edouble((double)0), estring(NULL), ebool(false) { name_memsize = 1; name = new char[name_memsize]; *name = '\0'; set(NULL, ex_value); } nse::cfgVariable::~cfgVariable() { clear(); delete[] name; } nse::cfgVariable::cfgVariable(const cfgVariable& var) { type = var.type; name_memsize = strlen(var.name) + 1; name = new char[name_memsize]; strcpy(name, var.name); if (type == IS_INT) eint = var.eint; else if (type == IS_DOUBLE) edouble = var.edouble; else if (type == IS_STRING) { estring = new char[strlen(var.estring) + 1]; strcpy(estring, var.estring); } else if (type == IS_BOOLEAN) ebool = var.ebool; } const nse::cfgVariable& nse::cfgVariable::operator=(cfgVariable var) { swap(var); return (*this); } void nse::cfgVariable::swap( cfgVariable& var) { nse::swap_vars(type, var.type); nse::swap_vars(name, var.name); nse::swap_vars(eint, var.eint); nse::swap_vars(edouble, var.edouble); nse::swap_vars(estring, var.estring); nse::swap_vars(ebool, var.ebool); nse::swap_vars(name_memsize, var.name_memsize); } nse::cfgVariable& nse::cfgVariable::operator+=(const cfgVariable& var) { // (int) += (int) // (double) += (double) // (string) += (string) if ((type == IS_INT) && (var.type == IS_INT)) { eint += var.eint; } else if ((type == IS_DOUBLE) && (var.type == IS_DOUBLE)) { edouble += (double)var.edouble; } else if ((type == IS_STRING) && (var.type == IS_STRING)) { const size_t length = strlen(estring) + strlen(var.estring) + 1; char *buf = new char[length]; strcpy(buf, estring); strcat(buf, var.estring); delete[] estring; estring = buf; } else { clear(); // type:= IS_UNDEF } return (*this); } nse::cfgVariable& nse::cfgVariable::operator-=(const cfgVariable& var) { // (int) -= (int) // (double) -= (double) if ((type == IS_INT) && (var.type == IS_INT)) { eint -= var.eint; } else if ((type == IS_DOUBLE) && (var.type == IS_DOUBLE)) { edouble -= var.edouble; } else { clear(); // type:= IS_UNDEF } return (*this); } nse::cfgVariable& nse::cfgVariable::operator*=(const cfgVariable& var) { // (int) *= (int) // (double) *= (double) if ((type == IS_INT) && (var.type == IS_INT)) { eint *= var.eint; } else if ((type == IS_DOUBLE) && (var.type == IS_DOUBLE)) { edouble *= var.edouble; } else { clear(); // type:= IS_UNDEF } return (*this); } nse::cfgVariable& nse::cfgVariable::operator/=(const cfgVariable& var) { // (int) /= (int) // (double) /= (double) if ((type == IS_INT) && (var.type == IS_INT)) { eint /= var.eint; } else if ((type == IS_DOUBLE) && (var.type == IS_DOUBLE)) { edouble /= var.edouble; } else { clear(); // type:= IS_UNDEF } return (*this); } nse::cfgVariable& nse::cfgVariable::operator%=(const cfgVariable& var) { // int %= (int) if ((type == IS_INT) && (var.type == IS_INT)) { eint %= var.eint; } else { clear(); // type:= IS_UNDEF } return (*this); } nse::cfgVariable& nse::cfgVariable::operator^=(const cfgVariable& var) { // (int) ^= (int) // (double) ^= (double) if ((type == IS_INT) && (var.type == IS_INT)) { eint = ipow(eint, var.eint); } else if ((type == IS_DOUBLE) && (var.type == IS_DOUBLE)) { edouble = pow(edouble, var.edouble); } else { clear(); // type:= IS_UNDEF } return (*this); } // check if we should really use const on return (all operators) -> // const nse::cfgVariable nse::cfgVariable::operator+(const cfgVariable& var) const { return cfgVariable(*this) += var; } const nse::cfgVariable nse::cfgVariable::operator-(const cfgVariable& var) const { return cfgVariable(*this) -= var; } const nse::cfgVariable nse::cfgVariable::operator*(const cfgVariable& var) const { return cfgVariable(*this) *= var; } const nse::cfgVariable nse::cfgVariable::operator/(const cfgVariable& var) const { return cfgVariable(*this) /= var; } const nse::cfgVariable nse::cfgVariable::operator%(const cfgVariable& var) const { return cfgVariable(*this) %= var; } const nse::cfgVariable nse::cfgVariable::operator^(const cfgVariable& var) const { return cfgVariable(*this) ^= var; } const nse::cfgVariable nse::cfgVariable::operator-() const { // -(int) // -(double) cfgVariable var; // default: type:= IS_UNDEF if (type == IS_INT) { var = (*this); var.eint = -var.eint; } else if (type == IS_DOUBLE) { var = (*this); var.edouble = -var.edouble; } return var; } const nse::cfgVariable nse::cfgVariable::operator+() const { // +(int) // +(double) cfgVariable var; // default: type:= IS_UNDEF if (type == IS_INT) { var = (*this); } else if (type == IS_DOUBLE) { var = (*this); } return var; } // <- // void nse::cfgVariable::set(const char* ex_name, const char* ex_value) { clear(); // default: type = IS_UNDEF change_name(ex_name); if (is_integer(ex_value, &eint)) type = IS_INT; else if (is_double(ex_value, &edouble)) type = IS_DOUBLE; else if (is_valid_string(ex_value)) { type = IS_STRING; estring = new char[strlen(ex_value) + 1]; strcpyrm(estring, ex_value, '"'); return; } else if (is_boolean(ex_value, &ebool)) type = IS_BOOLEAN; } void nse::cfgVariable::change_name(const char* ex_name) { if (ex_name == NULL) return; // keeping old name const size_t ex_length = strlen(ex_name) + 1; if (ex_length > name_memsize) { delete[] name; name_memsize = ex_length; name = new char[name_memsize]; } strcpy(name, ex_name); } void nse::cfgVariable::clear() { if (type == IS_STRING) { delete[] estring; estring = NULL; } type = IS_UNDEF; } int nse::cfgVariable::get_value(int* value) const { if (type != IS_INT) return 0; (*value) = eint; return 1; } int nse::cfgVariable::get_value(float* value) const { if (type != IS_DOUBLE) return 0; (*value) = (float)edouble; return 1; } int nse::cfgVariable::get_value(double* value) const { if (type != IS_DOUBLE) return 0; (*value) = edouble; return 1; } int nse::cfgVariable::get_value(char** value) const { if (type != IS_STRING) return 0; (*value) = new char[strlen(estring) + 1]; strcpy(*value, estring); return 1; } int nse::cfgVariable::get_value(std::string& value) const { if (type != IS_STRING) return 0; value = std::string(estring); return 1; } int nse::cfgVariable::get_value(bool* value) const { if (type != IS_BOOLEAN) return 0; (*value) = ebool; return 1; } nse::cfgVariable::VAR_TYPE nse::cfgVariable::get_type() const { return type; } bool nse::cfgVariable::is_varname(const char* ex_name) const { if (ex_name == NULL) return false; return (!strcmp(ex_name, name)); } bool nse::cfgVariable::is_valid_name() const { return (strlen(name) > 0); } bool nse::cfgVariable::is_valid_type() const { return (type != IS_UNDEF); } bool nse::cfgVariable::is_eq_name(const cfgVariable& var) const { return (!strcmp(name, var.name)); } void nse::cfgVariable::print() const { if (type == IS_INT) printf(" > INT '%s' = %i\n", name, eint); else if (type == IS_DOUBLE) printf(" > DOUBLE '%s' = %f\n", name, edouble); else if (type == IS_STRING) printf(" > STRING '%s' = %s\n", name, estring); else if (type == IS_BOOLEAN) printf(" > BOOLEAN '%s' = %s\n", name, ebool ? "true" : "false"); else printf(" > UNDEFINED '%s'\n", name); }