Select Git revision
documentation.html
cfg-var.cpp 8.17 KiB
#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);
}