UnitsApi.cpp

Go to the documentation of this file.
00001 /***************************************************************************
00002  *   Copyright (c) 2009 Juergen Riegel (FreeCAD@juergen-riegel.net)        *
00003  *                                                                         *
00004  *   This file is part of the FreeCAD CAx development system.              *
00005  *                                                                         *
00006  *   This library is free software; you can redistribute it and/or         *
00007  *   modify it under the terms of the GNU Library General Public           *
00008  *   License as published by the Free Software Foundation; either          *
00009  *   version 2 of the License, or (at your option) any later version.      *
00010  *                                                                         *
00011  *   This library  is distributed in the hope that it will be useful,      *
00012  *   but WITHOUT ANY WARRANTY; without even the implied warranty of        *
00013  *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the         *
00014  *   GNU Library General Public License for more details.                  *
00015  *                                                                         *
00016  *   You should have received a copy of the GNU Library General Public     *
00017  *   License along with this library; see the file COPYING.LIB. If not,    *
00018  *   write to the Free Software Foundation, Inc., 59 Temple Place,         *
00019  *   Suite 330, Boston, MA  02111-1307, USA                                *
00020  *                                                                         *
00021  ***************************************************************************/
00022 
00023 
00024 #include "PreCompiled.h"
00025 #ifdef __GNUC__
00026 # include <unistd.h>
00027 #endif
00028 
00029 #include <QString>
00030 #include "Exception.h"
00031 #include "UnitsApi.h"
00032 #include "UnitsSchemaInternal.h"
00033 #include "UnitsSchemaImperial1.h"
00034 #include "UnitsSchemaMKS.h"
00035 //#include "UnitsApiPy.h"
00036 
00037 #ifndef M_PI
00038 #define M_PI       3.14159265358979323846
00039 #endif
00040 #ifndef M_E
00041 #define M_E        2.71828182845904523536
00042 #endif
00043 #ifndef  DOUBLE_MAX
00044 # define DOUBLE_MAX 1.7976931348623157E+308    /* max decimal value of a "double"*/
00045 #endif
00046 #ifndef  DOUBLE_MIN
00047 # define DOUBLE_MIN 2.2250738585072014E-308    /* min decimal value of a "double"*/
00048 #endif
00049 
00050 using namespace Base;
00051 
00052 // suppress annoying warnings from generated source files
00053 #ifdef _MSC_VER
00054 # pragma warning(disable : 4003)
00055 # pragma warning(disable : 4018)
00056 # pragma warning(disable : 4065)
00057 # pragma warning( disable : 4273 )
00058 # pragma warning(disable : 4335) // disable MAC file format warning on VC
00059 #endif
00060 
00061 // === names =============================================================
00062 
00063 char *QuantityNames[] = {
00064         "length"      ,   
00065         "area"        ,   
00066         "volume"      ,   
00067         "angle"       , 
00068         "time span"    , 
00069         "velocity"    , 
00070         "acceleration", 
00071         "mass"        ,
00072         "temperature"
00073 };
00074 
00075 const QString  UnitsApi::getQuantityName(QuantityType t)
00076 {
00077     // check limits
00078     assert(t<9);
00079     // returns 
00080     return QString::fromLatin1(QuantityNames[t]);
00081 }
00082 // === static attributes  ================================================
00083 
00084 UnitsSchema  *UnitsApi::UserPrefSystem = new UnitsSchemaInternal();
00085 
00086 double   UnitsApi::UserPrefFactor [50];
00087 QString  UnitsApi::UserPrefUnit   [50];
00088 
00089 UnitsApi::UnitsApi(const char* filter)
00090 {
00091     bool temp;
00092     Result = parse(filter,temp);
00093 }
00094 
00095 UnitsApi::UnitsApi(const std::string& filter)
00096 {
00097     bool temp;
00098     Result = parse(filter.c_str(),temp);
00099 }
00100 
00101 UnitsApi::~UnitsApi()
00102 {
00103 }
00104 
00105 void UnitsApi::setSchema(UnitSystem s)
00106 {
00107     delete UserPrefSystem;
00108     switch (s) {
00109         case SI1      : UserPrefSystem = new UnitsSchemaInternal(); break;
00110         case SI2      : UserPrefSystem = new UnitsSchemaMKS(); break;
00111         case Imperial1: UserPrefSystem = new UnitsSchemaImperial1(); break;
00112     }
00113     UserPrefSystem->setSchemaUnits();
00114 }
00115 
00116 
00117 double UnitsApi::translateUnit(const char* str)
00118 {
00119     bool temp;
00120     return parse(str,temp );
00121 }
00122 
00123 double UnitsApi::translateUnit(const QString & str)
00124 {
00125     bool temp;
00126     return parse(str.toUtf8() ,temp);
00127 }
00128 
00129 
00130 // === static translation methodes ==========================================
00131 
00132 QString UnitsApi::toStrWithUserPrefs(QuantityType t,double Value)
00133 {
00134     return UserPrefSystem->toStrWithUserPrefs(t,Value);
00135     //double UnitValue = Value/UserPrefFactor[t];
00136     //return QString::fromAscii("%1 %2").arg(UnitValue).arg(UserPrefUnit[t]);
00137 }
00138 
00139 void UnitsApi::toStrWithUserPrefs(QuantityType t,double Value,QString &outValue,QString &outUnit)
00140 {
00141     UserPrefSystem->toStrWithUserPrefs(t,Value,outValue,outUnit);
00142 }
00143 
00144 PyObject *UnitsApi::toPyWithUserPrefs(QuantityType t,double Value)
00145 {
00146     return PyFloat_FromDouble(Value * UserPrefFactor[t]);
00147 }
00148 
00149 double UnitsApi::toDblWithUserPrefs(QuantityType t,const QString & Str)
00150 {
00151     return toDblWithUserPrefs(t,(const char*) Str.toUtf8());
00152 }
00153 
00154 double UnitsApi::toDblWithUserPrefs(QuantityType t,const char* Str)
00155 {
00156     bool UsedUnit;
00157     double Value = parse( Str,UsedUnit ); 
00158 
00159     if (UsedUnit)
00160         return Value;
00161     else
00162         return toDblWithUserPrefs(t,Value);
00163 }
00164 
00165 double UnitsApi::toDblWithUserPrefs(QuantityType t,double UserVal)
00166 {
00167     return UserVal*UserPrefFactor[t];
00168 }
00169 
00170 double UnitsApi::toDblWithUserPrefs(QuantityType t,PyObject *ArgObj)
00171 {
00172     if (PyString_Check(ArgObj)) 
00173         return toDblWithUserPrefs(t,PyString_AsString(ArgObj));
00174     else if (PyFloat_Check(ArgObj))
00175         return toDblWithUserPrefs(t,PyFloat_AsDouble(ArgObj));
00176     else if (PyInt_Check(ArgObj))
00177         return toDblWithUserPrefs(t,(double)PyInt_AsLong(ArgObj));
00178     else
00179         throw Base::Exception("Wrong parameter type!");
00180 }
00181 
00182 void UnitsApi::setPrefOf(QuantityType t,const char* Str)
00183 {
00184     double Factor = translateUnit(Str);
00185     UserPrefUnit[t] = QString::fromLatin1(Str);
00186     UserPrefFactor[t] = Factor;
00187 }
00188 
00189 const QString & UnitsApi::getPrefUnitOf(QuantityType t)
00190 {
00191     return UserPrefUnit[t];
00192 }
00193 
00194 const double UnitsApi::getPrefFactorOf(QuantityType t)
00195 {
00196     return UserPrefFactor[t];
00197 }
00198 
00199 void UnitsApi::setDefaults(void)
00200 {
00201     setPrefOf( Length       ,"mm"       );
00202     setPrefOf( Area         ,"mm^2"     );
00203     setPrefOf( Volume       ,"mm^3"     );
00204     setPrefOf( Angle        ,"deg"      );
00205     setPrefOf( TimeSpan     ,"s"        );
00206     setPrefOf( Velocity     ,"mm/s"     );
00207     setPrefOf( Acceleration ,"mm/s^2"   );
00208     setPrefOf( Mass         ,"kg"       );
00209     setPrefOf( Temperature  ,"K"        );
00210   
00211 }
00212 
00213 
00214 
00215 
00216 // === Parser & Scanner stuff ===============================================
00217 
00218 // include the Scanner and the Parser for the filter language
00219 
00220 double ScanResult=0;
00221 bool   UU = false;
00222 
00223 // error func
00224 void Unit_yyerror(char *errorinfo)
00225 {  throw Base::Exception(errorinfo);  }
00226 
00227 
00228 // for VC9 (isatty and fileno not supported anymore)
00229 #ifdef _MSC_VER
00230 int isatty (int i) {return _isatty(i);}
00231 int fileno(FILE *stream) {return _fileno(stream);}
00232 #endif
00233 
00234 namespace UnitParser {
00235 
00236 // show the parser the lexer method
00237 #define yylex UnitsApilex
00238 int UnitsApilex(void);
00239 
00240 // Parser, defined in UnitsApi.y
00241 #include "UnitsApi.tab.c"
00242 
00243 #ifndef DOXYGEN_SHOULD_SKIP_THIS
00244 // Scanner, defined in UnitsApi.l
00245 #include "lex.UnitsApi.c"
00246 #endif // DOXYGEN_SHOULD_SKIP_THIS
00247 }
00248 
00249 double UnitsApi::parse(const char* buffer,bool &UsedUnit)
00250 {
00251     // parse from buffer
00252     UnitParser::YY_BUFFER_STATE my_string_buffer = UnitParser::UnitsApi_scan_string (buffer);
00253     // set the global return variables
00254     ScanResult = DOUBLE_MIN;
00255     UU = false;
00256     // run the parser
00257     UnitParser::Unit_yyparse ();
00258     UsedUnit = UU;
00259     UU=false;
00260     // free the scan buffer
00261     UnitParser::UnitsApi_delete_buffer (my_string_buffer);
00262 
00263     if (ScanResult == DOUBLE_MIN)
00264         throw Base::Exception("Unknown error in Unit expression");
00265     return ScanResult;
00266 }

Generated on Wed Nov 23 19:00:56 2011 for FreeCAD by  doxygen 1.6.1