1 /*
2  * CParameterMap.cc
3  *
4  * Copyright 2014-2018 D. Mitch Bailey  cvc at shuharisystem dot com
5  *
6  * This file is part of cvc.
7  *
8  * cvc is free software: you can redistribute it and/or modify
9  * it under the terms of the GNU General Public License as published by
10  * the Free Software Foundation, either version 3 of the License, or
11  * (at your option) any later version.
12  *
13  * cvc is distributed in the hope that it will be useful,
14  * but WITHOUT ANY WARRANTY; without even the implied warranty of
15  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16  * GNU General Public License for more details.
17  *
18  * You should have received a copy of the GNU General Public License
19  * along with cvc.  If not, see <http://www.gnu.org/licenses/>.
20  *
21  * You can download cvc from https://github.com/d-m-bailey/cvc.git
22  */
23 
24 #include "CParameterMap.hh"
25 
CreateParameterMap(string theParameterString)26 void CParameterMap::CreateParameterMap(string theParameterString) {
27 	string myParameterName;
28 	string myParameterValue;
29 	size_t	myEqualIndex;
30 	size_t	myStringBegin = 0;
31 	size_t	myStringEnd;
32 	if (theParameterString.length() > 0) {
33 		do {
34 			myStringEnd = theParameterString.find(" ", myStringBegin);
35 			myEqualIndex = theParameterString.find("=", myStringBegin);
36 			myParameterName = theParameterString.substr(myStringBegin, myEqualIndex - myStringBegin);
37 			if ( myParameterName[0] == '$' ) myParameterName = myParameterName.substr(1);
38 			toupper_(myParameterName);
39 			myParameterValue = theParameterString.substr(myEqualIndex + 1, myStringEnd - (myEqualIndex + 1));
40 			(*this)[myParameterName] = myParameterValue;
41 			myStringBegin = myStringEnd + 1;
42 		} while (myStringEnd < theParameterString.length());
43 	}
44 }
45 
Print(string theIndentation,string theHeading)46 void CParameterMap::Print(string theIndentation, string theHeading) {
47 	string myIndentation = theIndentation + " ";
48 	cout << theIndentation << theHeading << endl;
49 	cout << myIndentation << "Parameters:";
50 	for (CParameterMap::iterator parameterPair_pit = begin(); parameterPair_pit != end(); parameterPair_pit++) {
51 		cout << " " << parameterPair_pit->first << ":" << parameterPair_pit->second;
52 	}
53 	cout << endl;
54 }
55 
CalculateResistance(string theEquation)56 resistance_t CParameterMap::CalculateResistance(string theEquation) {
57 	list<string> * myTokenList_p;
58 	// exceptions cause memory leaks
59 	if ( IsValidVoltage_(theEquation) ) {
60 		myTokenList_p = new(list<string>);
61 		myTokenList_p->push_back(theEquation);
62 	} else {
63 		myTokenList_p = postfix(theEquation);
64 	}
65 	list<double> myResistanceStack;
66 	double	myResistance;
67 	string	myOperators = "+-/*<>";
68 	for ( auto token_pit = myTokenList_p->begin(); token_pit != myTokenList_p->end(); token_pit++ ) {
69 		if ( myOperators.find(*token_pit) < myOperators.length() ) {
70 			if ( myResistanceStack.size() < 2 ) throw EPowerError("invalid equation: " + theEquation);
71 			myResistance = myResistanceStack.back();
72 			myResistanceStack.pop_back();
73 			if ( *token_pit == "+" ) {
74 				myResistanceStack.back() += myResistance;
75 			} else if ( *token_pit == "-" ) {
76 				myResistanceStack.back() -= myResistance;
77 			} else if ( *token_pit == "*" ) {
78 				myResistanceStack.back() *= myResistance;
79 			} else if ( *token_pit == "/" ) {
80 				myResistanceStack.back() /= myResistance;
81 			} else if ( *token_pit == "<" ) {
82 				myResistanceStack.back() = min(myResistanceStack.back(), myResistance);
83 			} else if ( *token_pit == ">" ) {
84 				myResistanceStack.back() = max(myResistanceStack.back(), myResistance);
85 			} else throw EPowerError("invalid operator: " + *token_pit);
86 		} else if ( isalpha((*token_pit)[0]) ) { // parameter name
87 			string myParameter = *token_pit;
88 			toupper_(myParameter);
89 			if ( this->count(myParameter) > 0 ) { // parameter definition exists
90 				CNormalValue myParameterValue((*this)[myParameter]);
91 				myResistanceStack.push_back(myParameterValue.RealValue());
92 			} else {
93 				throw EResistanceError("missing parameter: " + *token_pit + " in " + theEquation);
94 			}
95 		} else if ( IsValidVoltage_(*token_pit) ) {
96 			myResistanceStack.push_back(from_string<float>(*token_pit));
97 		} else {
98 			throw EResistanceError("invalid resistance calculation token: " + *token_pit + " in " + theEquation);
99 		}
100 	}
101 	if ( myResistanceStack.size() != 1 ) EResistanceError("invalid equation: " + theEquation);
102 	delete myTokenList_p;
103 	if ( myResistanceStack.front() >= MAX_RESISTANCE ) {
104 		return ( MAX_RESISTANCE );
105 	} else {
106 		return ( max(1, round(myResistanceStack.front())) );  // minimum resistance is 1 ohm
107 	}
108 }
109