1 /* $Header: /var/cvs/mbdyn/mbdyn/mbdyn-1.0/libraries/libmbutil/table.cc,v 1.45 2017/01/12 14:44:05 masarati Exp $ */
2 /*
3  * MBDyn (C) is a multibody analysis code.
4  * http://www.mbdyn.org
5  *
6  * Copyright (C) 1996-2017
7  *
8  * Pierangelo Masarati	<masarati@aero.polimi.it>
9  * Paolo Mantegazza	<mantegazza@aero.polimi.it>
10  *
11  * Dipartimento di Ingegneria Aerospaziale - Politecnico di Milano
12  * via La Masa, 34 - 20156 Milano, Italy
13  * http://www.aero.polimi.it
14  *
15  * Changing this copyright notice is forbidden.
16  *
17  * This program is free software; you can redistribute it and/or modify
18  * it under the terms of the GNU General Public License as published by
19  * the Free Software Foundation (version 2 of the License).
20  *
21  *
22  * This program is distributed in the hope that it will be useful,
23  * but WITHOUT ANY WARRANTY; without even the implied warranty of
24  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
25  * GNU General Public License for more details.
26  *
27  * You should have received a copy of the GNU General Public License
28  * along with this program; if not, write to the Free Software
29  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
30  */
31 
32 #include "mbconfig.h"           /* This goes first in every *.c,*.cc file */
33 
34 #include <cstring>
35 #include <string>
36 #include <cmath>
37 #include <limits>
38 
39 #include "myassert.h"
40 #include "mynewmem.h"
41 
42 #include "table.h"
43 
44 struct tmp_sym {
45 	const char* name;
46 	TypedValue val;
47 };
48 
49 tmp_sym consts[] = {
50 	{ "TRUE",      true               },
51 	{ "FALSE",     false              },
52 
53 	{ "RAND_MAX",  Int(RAND_MAX)      }, // 2147483647
54 
55 	{ "INT_MAX",   std::numeric_limits<Int>::max() },
56 	{ "INT_MIN",   std::numeric_limits<Int>::min() },
57 	{ "REAL_MAX",   std::numeric_limits<Real>::max() },
58 	{ "REAL_MIN",   std::numeric_limits<Real>::min() },
59 
60 	{ "e",         Real(M_E)          },
61 	{ "pi",        Real(M_PI)         },
62 
63 	{ "in2m",      Real(.0254)        }, // inches -> meters
64 	{ "m2in",      Real(1./.0254)     }, // meters -> inches
65 	{ "in2mm",     Real(25.4)         }, // inches -> millimeters
66 	{ "mm2in",     Real(1./25.4)      }, // millimeters -> inches
67 	{ "ft2m",      Real(.3048)        }, // feet -> meters
68 	{ "m2ft",      Real(1./.3048)     }, // meters -> feet
69 	{ "lb2kg",     Real(.45359237)    }, // pounds -> kg
70 	{ "kg2lb",     Real(1./.45359237) }, // kg -> pounds
71 	{ "deg2rad",   Real(M_PI/180.)    }, // degrees -> radians
72 	{ "rad2deg",   Real(180./M_PI)    }, // radians -> degrees
73 	{ "slug2kg",   Real(9.80665/.3048*.45359237) }, // slugs -> kilograms (14.5939029372064)
74 	{ "kg2slug",   Real(.3048/.45359237/9.80665) }, // kilograms -> slugs (0.0685217658567918)
75 
76 	// add as needed...
77 
78 	{ 0,           Int(0)           }
79 };
80 
81 
Table(bool bSetConstants)82 Table::Table(bool bSetConstants)
83 : vm()
84 {
85 	DEBUGCOUT("Table::Table" << std::endl);
86 
87 	if (bSetConstants) {
88 		tmp_sym* p = consts;
89 		while (p->name != 0) {
90 			p->val.SetConst();
91 			NamedValue* n = Put(p->name, p->val);
92 			if (n == 0) {
93 				silent_cerr("Table: unable to insert const \"" << p->name << "\""
94 					<< std::endl);
95 				throw ErrGeneric(MBDYN_EXCEPT_ARGS);
96 			}
97 			p++;
98 		}
99 	}
100 }
101 
~Table(void)102 Table::~Table(void)
103 {
104 	for (VM::iterator i = vm.begin(); i != vm.end(); ++i) {
105 		delete i->second;
106 	}
107 }
108 
109 Var *
Put(const std::string & name,const TypedValue & x)110 Table::Put(const std::string& name, const TypedValue& x)
111 {
112 	NamedValue* pNV = Get(name);
113 	if (pNV != 0) {
114 		silent_cerr("Table::Put(): name \"" << name << "\" "
115 			"already defined" << std::endl);
116 		throw Table::ErrNameAlreadyDefined(MBDYN_EXCEPT_ARGS);
117 	}
118 
119 	Var *pVar = new Var(name.c_str(), x);
120 
121 	if (!vm.insert(VM::value_type(name, pVar)).second) {
122 		silent_cerr("Table::Put(): unable to insert variable "
123 			"\"" << name << "\"" << std::endl);
124 		throw ErrGeneric(MBDYN_EXCEPT_ARGS);
125 	}
126 
127 	return pVar;
128 }
129 
130 const NamedValue *
Put(NamedValue * p)131 Table::Put(NamedValue *p)
132 {
133 	const NamedValue* pNV = Get(p->GetName());
134 	if (pNV != 0) {
135 		silent_cerr("Table::Put(): name \"" << p->GetName()
136 			<< "\" already defined" << std::endl);
137 		throw Table::ErrNameAlreadyDefined(MBDYN_EXCEPT_ARGS);
138 	}
139 
140 	if (!vm.insert(VM::value_type(p->GetName(), p)).second) {
141 		silent_cerr("Table::Put(): unable to insert named value "
142 			"\"" << p->GetName() << "\"" << std::endl);
143 		throw ErrGeneric(MBDYN_EXCEPT_ARGS);
144 	}
145 
146 	return p;
147 }
148 
149 NamedValue *
Get(const std::string & name) const150 Table::Get(const std::string& name) const
151 {
152 	VM::const_iterator i = vm.find(name);
153 	if (i == vm.end()) {
154 		return 0;
155 	}
156 	return i->second;
157 }
158 
159 std::ostream&
operator <<(std::ostream & out,const Table & T)160 operator << (std::ostream& out, const Table& T)
161 {
162 	for (Table::VM::const_iterator i = T.vm.begin(); i != T.vm.end(); ++i) {
163 		out << "  ";
164 		if (i->second->Const()) {
165 			out << "const ";
166 		}
167 		out << i->second->GetTypeName()
168 			<< " " << i->second->GetName()
169 			<< " = " << i->second->GetVal() << std::endl;
170 	}
171 
172 	return out;
173 }
174 
175