~jdpipe/ascend/trunk-old

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
#include <iostream>
#include <stdexcept>
#include <sstream>
using namespace std;

#include "units.h"
#include "dimensions.h"

extern "C"{
#include <ascend/compiler/cmpfunc.h>
}

UnitsM::UnitsM(){
	int errcode;
	long unsigned pos;
	u = FindOrDefineUnits("?",&pos,&errcode);
	if(errcode){
		// naughty to throw exceptions during ctor.
		throw runtime_error("Can't create wildcard (?)");
	}
}

UnitsM::UnitsM(const struct Units *u) : u(u){
	// nothing else
}

/*
exception
UnitsM::getException(const int &errorcode, const char *ustr, const int &pos){
	const char *s;
	switch(errorcode){
		case 0: return runtime_error("This error should not have been thrown!");
		case 1: s = "Undefined unit used in string"; break;
		case 2: s = "Unbalanced parenthesis"; break;
		case 3: s = "Illegal character"; break;
		case 4: s = "Illegal real value"; break;
		case 5: s = "Oversized identifier or real"; break;
		case 6: s = "Missing operator in real followed by identifier"; break;
		case 7: s = "Term missing after * or / or ("; break;
		case 8: s = "Term missing before * or /"; break;
		case 9: s = "Too many closing parentheses"; break;
		case 10: s = "Bad fraction exponent"; break;
		case 11: raise runtime_error("Invalid UnitsM::getException errorcode = 11");
	}
	exception e = runtime_error(s);
	CONSOLE_DEBUG("Units error: %s",s);
	CONSOLE_DEBUG("%s",ustr);
	char indic[strlen(ustr)+1];
	for(int i=0; i<pos; ++i){
		indic[i] = ' ';
	}
	indic[pos] = '^'; indic[pos+1] = '\0';
	CONSOLE_DEBUG(indic);
	return e;
}
*/

/**
	Parse a units string, create a new UnitsM object from the string.

	UnitsM doesn't allocate any storage so it's OK to throw
	an exception in a ctor
*/
UnitsM::UnitsM(const char *units){
	const struct Units *u = LookupUnits(units);
	if(u==NULL){
		//cerr << "About to create new units '" << units << "'" << endl;
		long unsigned pos;
		int err;
		u = FindOrDefineUnits(units, &pos, &err);
		if(u==NULL){
			char **errv = UnitsExplainError(units, err, pos);
			stringstream ss;
			ss << "Error parsing units: " << errv[0] << endl << errv[1] << endl << errv[2];
			throw runtime_error(ss.str());
		}
	}/*else{
		cerr << "Units '" << units << "' were found in lookup" << endl;
	}*/
	this->u = u;
}

const struct Units *
UnitsM::getInternalType() const{
	return u;
}

const SymChar
UnitsM::getName() const{
	return SymChar(SCP( UnitsDescription(u) ));
}

const Dimensions
UnitsM::getDimensions() const{
	const dim_type *d = UnitsDimensions(u);
	return Dimensions(d);
}

const double
UnitsM::getConversion() const{
	return UnitsConvFactor(u);
}

const bool
UnitsM::operator==(const UnitsM &other) const{
	// because of the FindOrDefineUnits thing, equivalent units will always have the same pointer
	return 0==CmpRealPtrs(getInternalType(),other.getInternalType());
}