testCalcExtended.cpp

Go to the documentation of this file.
00001 /*
00002 // $Id: //open/dev/fennel/calctest/testCalcExtended.cpp#3 $
00003 // Fennel is a library of data storage and processing components.
00004 // Copyright (C) 2004-2009 The Eigenbase Project
00005 // Copyright (C) 2004-2009 SQLstream, Inc.
00006 // Copyright (C) 2009-2009 LucidEra, Inc.
00007 //
00008 // This program is free software; you can redistribute it and/or modify it
00009 // under the terms of the GNU General Public License as published by the Free
00010 // Software Foundation; either version 2 of the License, or (at your option)
00011 // any later version approved by The Eigenbase Project.
00012 //
00013 // This program is distributed in the hope that it will be useful,
00014 // but WITHOUT ANY WARRANTY; without even the implied warranty of
00015 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00016 // GNU General Public License for more details.
00017 //
00018 // You should have received a copy of the GNU General Public License
00019 // along with this program; if not, write to the Free Software
00020 // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
00021 //
00022 // Test Calculator object directly by instantiating instruction objects,
00023 // creating programs, running them, and checking the register set values.
00024 */
00025 #include "fennel/common/CommonPreamble.h"
00026 #include "fennel/tuple/TupleDescriptor.h"
00027 #include "fennel/tuple/TupleData.h"
00028 #include "fennel/tuple/TupleAccessor.h"
00029 #include "fennel/tuple/TuplePrinter.h"
00030 #include "fennel/tuple/AttributeAccessor.h"
00031 #include "fennel/tuple/StandardTypeDescriptor.h"
00032 #include "fennel/common/TraceSource.h"
00033 #include "fennel/calculator/BoolInstruction.h"
00034 #include "fennel/calculator/BoolNativeInstruction.h"
00035 #include "fennel/calculator/Calculator.h"
00036 #include "fennel/calculator/IntegralNativeInstruction.h"
00037 #include "fennel/calculator/JumpInstruction.h"
00038 #include "fennel/calculator/NativeInstruction.h"
00039 #include "fennel/calculator/NativeNativeInstruction.h"
00040 #include "fennel/calculator/ReturnInstruction.h"
00041 #include "fennel/calculator/ExtendedInstruction.h"
00042 #include "fennel/calculator/InstructionCommon.h"
00043 #include <stdlib.h>
00044 #include <stdio.h>
00045 #include <string>
00046 #include <boost/scoped_array.hpp>
00047 #include <boost/test/unit_test_suite.hpp>
00048 #include <limits>
00049 #include <iostream.h>
00050 #include <math.h>
00051 using namespace std;
00052 using namespace fennel;
00053 char *ProgramName;
00054 void
00055 fail(const char *str, int line) {
00056     assert(ProgramName);
00057     assert(str);
00058     printf("%s: unit test failed: |%s| line %d\n", ProgramName, str, line);
00059     exit(-1);
00060 }
00061 // ----------------------------------------------------------------------
00062 // conversion functions
00063 // ----------------------------------------------------------------------
00064 void convertDoubleToFloat(
00065     RegisterRef<float>* regOut,
00066     RegisterRef<double>* regIn)
00067 {
00068     regOut->value((float)regIn->value());
00069 }
00070 void convertFloatToDouble(
00071     RegisterRef<double>* regOut,
00072     RegisterRef<float>* regIn)
00073 {
00074     regOut->value((double)regIn->value());
00075 }
00076 void convertFloatToInt(
00077     RegisterRef<int>* regOut,
00078     RegisterRef<float>* regIn)
00079 {
00080     regOut->value((int)regIn->value());
00081 }
00082 void convertIntToFloat(
00083     RegisterRef<float>* regOut,
00084     RegisterRef<int>* regIn)
00085 {
00086     regOut->value((float)regIn->value());
00087 }
00091 void convertDecimal(
00092     RegisterRef<int32_t>* resultReg,
00093     RegisterRef<int32_t>* inputReg,
00094     RegisterRef<int32_t>* exponentReg)
00095 {
00096     int32_t in = inputReg->value();
00097     int32_t exp = exponentReg->value();
00098     int32_t result = in;
00099     if (exp < 0) {
00100         while (exp++ < 0) {
00101             result /= 10;
00102         }
00103     } else {
00104         while (exp-- > 0) {
00105             result *= 10;
00106         }
00107     }
00108     resultReg->value(result);
00109 }
00110 
00111 void convertStringToExactNumber(
00112     RegisterRef<int>* regOut,
00113     RegisterRef<char *>* regIn)
00114 {
00115 #if 0
00116     // TODO: Wrap this code in
00117     uint srcL = regIn->getS();
00118     // TODO: Change the following proof-of-concept code into
00119     // TODO: something real.
00120     char *nullTermStr = new char[srcL + 1];
00121     nullTermStr[srcL + 1] = 0;
00122     memcpy(nullTermStr, regIn->pointer(), srcL);
00123     regOut->value(strtol(nullTermStr, 0, 10));
00124     delete [] nullTermStr;
00125 #endif
00126 #if 0
00127 
00128     // TODO: Nope this is a disaster JR 6/07 (valueToString() returns "Unimpl");
00129     const char *pString = regIn->valueToString().c_str();
00130     assert(pString);
00131     int iValue = atoi(pString);
00132     regOut->value(iValue);
00133 #endif
00134 
00135     // Try original pointer casting code updated to new class interface
00136     // This code is the same as above
00137     uint srcL = regIn->stringLength();
00138     char *nullTermStr = new char[srcL + 1];
00139     nullTermStr[srcL] = 0;
00140     memcpy(nullTermStr, regIn->pointer(), srcL);
00141     regOut->value(strtol(nullTermStr, 0, 10));
00142     delete [] nullTermStr;
00143 }
00144 
00145 #if 0
00146 // TODO: JR 6/07 removing this
00147 void convertExactNumberToString(
00148     RegisterRef<char *>* regOut,
00149     RegisterRef<int>* regIn)
00150 {
00151 #if 1
00152     // TODO: Change the following proof-of-concept code into
00153     // TODO: something real.
00154     char *nullTermStr = new char[256];
00155     sprintf(nullTermStr, "%d", regIn->value());
00156 
00157     uint dstL = regOut->storage();
00158     uint newL = strlen(nullTermStr);
00159 
00160     printf("dstL = %d  newL = %d\n", dstL, newL);
00161 
00162     if (newL > dstL) {
00163         // TODO: Must check right space padding to see what, if
00164         // anything valid is truncated before going all wild and
00165         // throwing exception
00166         assert(0);        // TODO: Must have a valid pc here!
00167         // SQL99 Part 2 Section 22.1 22-001 "string data, right truncation"
00168         memcpy(regOut->pointer(), nullTermStr, dstL);
00169         regOut->putS(dstL);
00170         throw CalcMessage("22001", 0); // TODO: PC is bogus
00171         printf("ConvertExactNumberToString\n");
00172         assert(newL <= dstL);
00173     }
00174 
00175     regOut->putS(newL);
00176     memcpy(regOut->pointer(), nullTermStr, newL);
00177     delete [] nullTermStr;
00178 #endif
00179 #if 0
00180 // TODO: JR 6/07 ... valueToStringis not implemented yet ...
00181 // re-enabled the above ...
00182     const char *pString = regIn->valueToString().c_str();
00183     assert(pString);
00184     regOut->value(const_cast<char*>(pString));
00185 #endif
00186 }
00187 #endif
00188 
00189 void convertStringToFloat(
00190     RegisterRef<float>* regOut,
00191     RegisterRef<char *>* regIn)
00192 {
00193     //*regOut = strtof(*regIn, (char **)NULL);
00194 }
00195 
00196 void convertFloatToString(
00197     RegisterRef<char *>* regOut,
00198     RegisterRef<float>* regIn)
00199 {
00200     //*str = itoa ((int) *approx);
00201 }
00202 
00203 void convertStringToDouble(
00204     RegisterRef<double>* regOut,
00205     RegisterRef<char *>* regIn)
00206 {
00207     //*regOut = strtod(*regIn, (char **)NULL);
00208 }
00209 
00210 void convertDoubleToString(
00211     RegisterRef<char *>* regOut,
00212     RegisterRef<double>* regIn)
00213 {}
00214 
00215 
00216 // ----------------------------------------------------------------------
00217 // -- Test driver
00218 // ----------------------------------------------------------------------
00225 class TestCalculator : public Calculator {
00226     TupleDescriptor _tupleDescLiteral;
00227     TupleDescriptor _tupleDescInput;
00228     TupleDescriptor _tupleDescOutput;
00229     TupleDescriptor _tupleDescLocal;
00230     TupleDescriptor _tupleDescStatus;
00231     bool _isNullable;
00232     ExtendedInstructionDef *_instrDef;
00233     TupleAccessor _tupleAccessorLiteral;
00234     TupleAccessor _tupleAccessorInput;
00235     TupleAccessor _tupleAccessorOutput;
00236     TupleAccessor _tupleAccessorLocal;
00237     TupleAccessor _tupleAccessorStatus;
00238     boost::scoped_array<FixedBuffer> _pTupleBufLiteral;
00239     boost::scoped_array<FixedBuffer> _pTupleBufInput;
00240     boost::scoped_array<FixedBuffer> _pTupleBufOutput;
00241     boost::scoped_array<FixedBuffer> _pTupleBufLocal;
00242     boost::scoped_array<FixedBuffer> _pTupleBufStatus;
00243     TupleData _tupleDataLiteral;
00244     TupleData _tupleDataInput;
00245     TupleData _tupleDataOutput;
00246     TupleData _tupleDataLocal;
00247     TupleData _tupleDataStatus;
00248 public:
00249     TestCalculator(
00250         DynamicParamManager *pdpm,
00251         bool isNullable,
00252         ExtendedInstructionDef *instrDef)
00253         : Calculator(pdpm, 0, 0, 0, 0, 0, 0),
00254           _isNullable(isNullable),
00255           _instrDef(instrDef),
00256           _pTupleBufLiteral(NULL),
00257           _pTupleBufInput(NULL),
00258           _pTupleBufOutput(NULL),
00259           _pTupleBufLocal(NULL),
00260           _pTupleBufStatus(NULL),
00261           _tupleDataLiteral(),
00262           _tupleDataInput(),
00263           _tupleDataOutput(),
00264           _tupleDataLocal(),
00265           _tupleDataStatus()
00266     {
00267         setUp();
00268     }
00269 
00270     void setUp() {
00271         const vector<StandardTypeDescriptorOrdinal> parameterTypes =
00272             _instrDef->getParameterTypes();
00273         // assume first parameter is out, rest are in
00274         StandardTypeDescriptorFactory typeFactory;
00275         for (uint i = 0; i < parameterTypes.size(); i++) {
00276             StoredTypeDescriptor const &typeDesc =
00277                 typeFactory.newDataType(parameterTypes[i]);
00278             if (i == 0) {
00279                 // 0th parameter is "OUT"
00280                 _tupleDescOutput.push_back(
00281                     TupleAttributeDescriptor(typeDesc, _isNullable));
00282             } else if (i > 0) {
00283                 // other parameters are "IN"
00284                 _tupleDescInput.push_back(
00285                     TupleAttributeDescriptor(typeDesc, _isNullable));
00286             }
00287         }
00288         // Create a tuple accessor from the description
00289         //
00290         // Note: Must use a NOT_NULL_AND_FIXED accessor when creating
00291         // a tuple out of the air like this, otherwise unmarshal()
00292         // does not know what to do. If you need a STANDARD type tuple
00293         // that supports nulls, it has to be built as a copy.
00294         _tupleAccessorLiteral.compute(
00295             _tupleDescLiteral, TUPLE_FORMAT_ALL_FIXED);
00296         _tupleAccessorInput.compute(_tupleDescInput, TUPLE_FORMAT_ALL_FIXED);
00297         _tupleAccessorOutput.compute(_tupleDescOutput, TUPLE_FORMAT_ALL_FIXED);
00298         _tupleAccessorLocal.compute(_tupleDescLocal, TUPLE_FORMAT_ALL_FIXED);
00299         _tupleAccessorStatus.compute(_tupleDescStatus, TUPLE_FORMAT_ALL_FIXED);
00300         // Allocate memory for the tuple
00301         _pTupleBufLiteral.reset(
00302             new FixedBuffer[_tupleAccessorLiteral.getMaxByteCount()]);
00303         _pTupleBufInput.reset(
00304             new FixedBuffer[_tupleAccessorInput.getMaxByteCount()]);
00305         _pTupleBufOutput.reset(
00306             new FixedBuffer[_tupleAccessorOutput.getMaxByteCount()]);
00307         _pTupleBufLocal.reset(
00308             new FixedBuffer[_tupleAccessorLocal.getMaxByteCount()]);
00309         _pTupleBufStatus.reset(
00310             new FixedBuffer[_tupleAccessorStatus.getMaxByteCount()]);
00311         // Link memory to accessor
00312         _tupleAccessorLiteral.setCurrentTupleBuf(
00313             _pTupleBufLiteral.get(), false);
00314         _tupleAccessorInput.setCurrentTupleBuf(_pTupleBufInput.get(), false);
00315         _tupleAccessorOutput.setCurrentTupleBuf(_pTupleBufOutput.get(), false);
00316         _tupleAccessorLocal.setCurrentTupleBuf(_pTupleBufLocal.get(), false);
00317         _tupleAccessorStatus.setCurrentTupleBuf(_pTupleBufStatus.get(), false);
00318         // Create a vector of TupleDatum objects based on the
00319         // description we built
00320         _tupleDataLiteral.compute(_tupleDescLiteral);
00321         _tupleDataInput.compute(_tupleDescInput);
00322         _tupleDataOutput.compute(_tupleDescOutput);
00323         _tupleDataLocal.compute(_tupleDescLocal);
00324         _tupleDataStatus.compute(_tupleDescStatus);
00325         // Do something mysterious. Probably binding pointers in the
00326         // accessor to items in the TupleData vector.
00327         _tupleAccessorLiteral.unmarshal(_tupleDataLiteral);
00328         _tupleAccessorInput.unmarshal(_tupleDataInput);
00329         _tupleAccessorOutput.unmarshal(_tupleDataOutput);
00330         _tupleAccessorLocal.unmarshal(_tupleDataLocal);
00331     }
00332 
00333     template <typename T>
00334     void setInput(int index, T *valP)
00335     {
00336         // reinterpret_cast<T *>(const_cast<PBuffer>(
00337         //     _tupleDataInput[index].pData)) = valP;
00338         _tupleDataInput[index].pData = reinterpret_cast<const uint8_t *>(valP);
00339         if (true) {
00340             // Print out the nullable tuple
00341             TuplePrinter tuplePrinter;
00342             printf("Literals\n");
00343             tuplePrinter.print(cout, _tupleDescLiteral, _tupleDataLiteral);
00344             printf("\nInput\n");
00345             tuplePrinter.print(cout, _tupleDescInput, _tupleDataInput);
00346             cout << endl;
00347             printf("\nOutput\n");
00348             tuplePrinter.print(cout, _tupleDescOutput, _tupleDataOutput);
00349             cout << endl;
00350             printf("\nLocal\n");
00351             tuplePrinter.print(cout, _tupleDescLocal, _tupleDataLocal);
00352             cout << endl;
00353         }
00354     }
00355     template <typename T>
00356     void setInput(int index, T *valP, TupleStorageByteLength length)
00357     {
00358         // reinterpret_cast<T *>(const_cast<PBuffer>(
00359         //     _tupleDataInput[index].pData)) = valP;
00360         _tupleDataInput[index].pData = reinterpret_cast<const uint8_t *>(valP);
00361         _tupleDataInput[index].cbData = length;
00362         if (true) {
00363             // Print out the nullable tuple
00364             TuplePrinter tuplePrinter;
00365             printf("Literals\n");
00366             tuplePrinter.print(cout, _tupleDescLiteral, _tupleDataLiteral);
00367             printf("\nInput\n");
00368             tuplePrinter.print(cout, _tupleDescInput, _tupleDataInput);
00369             cout << endl;
00370             printf("\nOutput\n");
00371             tuplePrinter.print(cout, _tupleDescOutput, _tupleDataOutput);
00372             cout << endl;
00373             printf("\nLocal\n");
00374             tuplePrinter.print(cout, _tupleDescLocal, _tupleDataLocal);
00375             cout << endl;
00376         }
00377     }
00378 
00379     template <typename T>
00380     void setOutput(
00381         int index,
00382         T *valP,
00383         TupleStorageByteLength cbData,
00384         TupleStorageByteLength cbStorage)
00385     {
00386         // reinterpret_cast<T *>(const_cast<PBuffer>(
00387         //     _tupleDataOutput[index].pData)) = valP;
00388         _tupleDataOutput[index].pData = reinterpret_cast<const uint8_t *>(valP);
00389         _tupleDataOutput[index].cbData = cbData;
00390         _tupleDescOutput[index].cbStorage = cbStorage;
00391         if (true) {
00392             // Print out the nullable tuple
00393             TuplePrinter tuplePrinter;
00394             printf("Literals\n");
00395             tuplePrinter.print(cout, _tupleDescLiteral, _tupleDataLiteral);
00396             printf("\nInput\n");
00397             tuplePrinter.print(cout, _tupleDescInput, _tupleDataInput);
00398             cout << endl;
00399             printf("\nOutput\n");
00400             tuplePrinter.print(cout, _tupleDescOutput, _tupleDataOutput);
00401             cout << endl;
00402             printf("\nLocal\n");
00403             tuplePrinter.print(cout, _tupleDescLocal, _tupleDataLocal);
00404             cout << endl;
00405         }
00406     }
00407     void printOutput() {
00408         TuplePrinter tuplePrinter;
00409         printf("\nOutput\n");
00410         tuplePrinter.print(cout, _tupleDescOutput, _tupleDataOutput);
00411         cout << endl;
00412     }
00413     void bind()
00414     {
00415         Calculator::bind(
00416             RegisterReference::ELiteral,
00417             &_tupleDataLiteral,
00418             _tupleDescLiteral);
00419         Calculator::bind(
00420             RegisterReference::EInput,
00421             &_tupleDataInput,
00422             _tupleDescInput);
00423         Calculator::bind(
00424             RegisterReference::EOutput,
00425             &_tupleDataOutput,
00426             _tupleDescOutput);
00427         Calculator::bind(
00428             RegisterReference::ELocal,
00429             &_tupleDataLocal,
00430             _tupleDescLocal);
00431         Calculator::bind(
00432             RegisterReference::EStatus,
00433             &_tupleDataStatus,
00434             _tupleDescStatus);
00435     }
00436 
00437     template <typename T>
00438     void getOutput(
00439         int i,
00440         T &val)
00441     {
00442         val = *(reinterpret_cast<T *>(const_cast<PBuffer>(
00443             _tupleDataOutput[i].pData)));
00444     }
00445 
00446     template <typename T>
00447     void getOutputP(
00448         int i,
00449         T &val)
00450     {
00451         val = (reinterpret_cast<T>(const_cast<PBuffer>(
00452             _tupleDataOutput[i].pData)));
00453     }
00454 };
00455 // ----------------------------------------------------------------------
00456 // tests
00457 //---------------------------------------------
00458 
00459 void printTestHeader(const char *msg)
00460 {
00461     printf("=========================================================\n");
00462     printf("=========================================================\n");
00463     printf("=====\n");
00464     printf("=====     ");
00465     printf("%s", msg);
00466     printf("\n");
00467     printf("=====\n");
00468     printf("=========================================================\n");
00469     printf("=========================================================\n");
00470 }
00471 
00472 void testConvertDoubleToFloat(double val, float expected)
00473 {
00474     printTestHeader("testConvertDoubleToFloat()");
00475     ExtendedInstructionTable table;
00476     vector<StandardTypeDescriptorOrdinal> parameterTypes;
00477     // define a function
00478     parameterTypes.resize(2);
00479     parameterTypes[0] = STANDARD_TYPE_REAL;
00480     parameterTypes[1] = STANDARD_TYPE_DOUBLE;
00481     table.add(
00482         "convert",
00483         parameterTypes,
00484         (ExtendedInstruction2<float,double>*) NULL,
00485         &convertDoubleToFloat);
00486     // lookup a function
00487     ExtendedInstructionDef *pDef = table["convert(r,d)"];
00488     assert(pDef != NULL);
00489     assert(pDef->getName() == string("convert"));
00490     assert(pDef->getParameterTypes().size() == 2);
00491     // lookup non-existent, should return NULL
00492     ExtendedInstructionDef *pNonExistentDef = table["convert(d,r)"];
00493     assert(pNonExistentDef == NULL);
00494     // Set up the Calculator
00495     DynamicParamManager dpm;
00496     TestCalculator c(&dpm, true, pDef);
00497     c.setInput(0, &val);
00498     // setup registers
00499     vector<RegisterReference *> regRefs(2);
00500     regRefs[0] = new RegisterRef<float>(
00501         RegisterReference::EOutput, 0,
00502         STANDARD_TYPE_REAL);
00503     regRefs[1] = new RegisterRef<double>(
00504         RegisterReference::EInput, 0,
00505         STANDARD_TYPE_DOUBLE);
00506     c.appendRegRef(regRefs[0]);
00507     c.appendRegRef(regRefs[1]);
00508     c.bind();
00509     // create an instruction
00510     //ExtendedInstruction *pInstr = pDef->createInstruction(&c, regRefs);
00511     ExtendedInstruction *pInstr = pDef->createInstruction(regRefs);
00512     assert(pInstr != NULL);
00513     // execute it
00514     c.appendInstruction(pInstr);
00515     c.exec();
00516     c.printOutput();
00517     float f;
00518     c.getOutput(0, f);
00519     cout << f << endl;
00520     assert(fabs(expected - f) < 0.0001);
00521 };
00522 
00523 void testConvertFloatToDouble(float val, double expected)
00524 {
00525     printTestHeader("testConvertFloatToDouble()");
00526     ExtendedInstructionTable table;
00527     vector<StandardTypeDescriptorOrdinal> parameterTypes;
00528     // define a function
00529     parameterTypes.resize(2);
00530     parameterTypes[0] = STANDARD_TYPE_DOUBLE;
00531     parameterTypes[1] = STANDARD_TYPE_REAL;
00532     table.add(
00533         "convert",
00534         parameterTypes,
00535         (ExtendedInstruction2<double, float>*) NULL,
00536         &convertFloatToDouble);
00537     // lookup a function
00538     ExtendedInstructionDef *pDef = table["convert(d,r)"];
00539     assert(pDef != NULL);
00540     assert(pDef->getName() == string("convert"));
00541     assert(pDef->getParameterTypes().size() == 2);
00542     // Set up the Calculator
00543     DynamicParamManager dpm;
00544     TestCalculator c(&dpm, true, pDef);
00545     c.setInput(0, &val);
00546     // setup registers
00547     vector<RegisterReference *> regRefs(2);
00548     regRefs[0] = new RegisterRef<double>(
00549         RegisterReference::EOutput, 0,
00550         STANDARD_TYPE_DOUBLE);
00551     regRefs[1] = new RegisterRef<float>(
00552         RegisterReference::EInput, 0,
00553         STANDARD_TYPE_REAL);
00554     c.appendRegRef(regRefs[0]);
00555     c.appendRegRef(regRefs[1]);
00556     c.bind();
00557     // create an instruction
00558     //ExtendedInstruction *pInstr = pDef->createInstruction(&c, regRefs);
00559     ExtendedInstruction *pInstr = pDef->createInstruction(regRefs);
00560     assert(pInstr != NULL);
00561     // execute it
00562     c.appendInstruction(pInstr);
00563     c.exec();
00564     c.printOutput();
00565     double d;
00566     c.getOutput(0, d);
00567     cout << d << endl;
00568     assert(fabs(expected - d) < 0.0001);
00569 };
00570 
00571 
00572 void testConvertFloatToIntTypes(const char * const str, float val, int expected)
00573 {
00574     printTestHeader("testConvertFloatToIntTypes()");
00575     ExtendedInstructionTable table;
00576     vector<StandardTypeDescriptorOrdinal> parameterTypes;
00577     // define a function
00578     parameterTypes.resize(2);
00579     parameterTypes[0] = StandardTypeDescriptor::fromString(str);
00580     parameterTypes[1] = STANDARD_TYPE_REAL;
00581     table.add(
00582         "convert",
00583         parameterTypes,
00584         (ExtendedInstruction2<int, float>*) NULL,
00585         &convertFloatToInt);
00586     // lookup a function
00587     string s("convert(");
00588     s += str;
00589     s += ",r)";
00590     cout << s << endl;
00591     ExtendedInstructionDef *pDef = table[s];
00592     assert(pDef != NULL);
00593     assert(pDef->getName() == string("convert"));
00594     assert(pDef->getParameterTypes().size() == 2);
00595     // lookup non-existent, should return NULL
00596     ExtendedInstructionDef *pNonExistentDef = table["convert(d,r)"];
00597     assert(pNonExistentDef == NULL);
00598     // Set up the Calculator
00599     DynamicParamManager dpm;
00600     TestCalculator c(&dpm, true, pDef);
00601     c.setInput(0, &val);
00602     // setup registers
00603     vector<RegisterReference *> regRefs(2);
00604     regRefs[0] = new RegisterRef<int>(
00605         RegisterReference::EOutput, 0,
00606         STANDARD_TYPE_INT_32);
00607     regRefs[1] = new RegisterRef<float>(
00608         RegisterReference::EInput, 0,
00609         STANDARD_TYPE_REAL);
00610     c.appendRegRef(regRefs[0]);
00611     c.appendRegRef(regRefs[1]);
00612     c.bind();
00613     // create an instruction
00614     //ExtendedInstruction *pInstr = pDef->createInstruction(&c, regRefs);
00615     ExtendedInstruction *pInstr = pDef->createInstruction(regRefs);
00616     assert(pInstr != NULL);
00617     // execute it
00618     c.appendInstruction(pInstr);
00619     c.exec();
00620     c.printOutput();
00621     int d;
00622     c.getOutput(0, d);
00623     cout << d << endl;
00624     assert(expected == d);
00625 };
00626 
00627 void testConvertIntTypesToFloat(const char * const str, int val, float expected)
00628 {
00629     printTestHeader("testConvertIntTypesToFloat()");
00630     ExtendedInstructionTable table;
00631     vector<StandardTypeDescriptorOrdinal> parameterTypes;
00632     // define a function
00633     parameterTypes.resize(2);
00634     parameterTypes[0] = STANDARD_TYPE_REAL;
00635     parameterTypes[1] = StandardTypeDescriptor::fromString(str);
00636     table.add(
00637         "convert",
00638         parameterTypes,
00639         (ExtendedInstruction2<float, int>*) NULL,
00640         &convertIntToFloat);
00641     // lookup a function
00642     string s("convert(r,");
00643     s += str;
00644     s += ")";
00645     cout << s << endl;
00646     ExtendedInstructionDef *pDef = table[s];
00647     assert(pDef != NULL);
00648     assert(pDef->getName() == string("convert"));
00649     assert(pDef->getParameterTypes().size() == 2);
00650     // Set up the Calculator
00651     DynamicParamManager dpm;
00652     TestCalculator c(&dpm, true, pDef);
00653     c.setInput(0, &val);
00654     // setup registers
00655     vector<RegisterReference *> regRefs(2);
00656     regRefs[0] = new RegisterRef<float>(
00657         RegisterReference::EOutput, 0,
00658         STANDARD_TYPE_REAL);
00659     regRefs[1] = new RegisterRef<int>(
00660         RegisterReference::EInput, 0,
00661         STANDARD_TYPE_INT_32);
00662     c.appendRegRef(regRefs[0]);
00663     c.appendRegRef(regRefs[1]);
00664     c.bind();
00665     // create an instruction
00666     //ExtendedInstruction *pInstr = pDef->createInstruction(&c, regRefs);
00667     ExtendedInstruction *pInstr = pDef->createInstruction(regRefs);
00668     assert(pInstr != NULL);
00669     // execute it
00670     c.appendInstruction(pInstr);
00671     c.exec();
00672     c.printOutput();
00673     float f;
00674     c.getOutput(0, f);
00675     cout << f << endl;
00676     assert(expected == f);
00677 };
00678 
00679 void testConvertDecimal(const char * const str, int val, int exp, int expected)
00680 {
00681     printTestHeader("testConvertDecimal()");
00682     ExtendedInstructionTable table;
00683     vector<StandardTypeDescriptorOrdinal> parameterTypes;
00684     // define a function
00685     parameterTypes.resize(3);
00686     parameterTypes[0] = StandardTypeDescriptor::fromString(str);
00687     parameterTypes[1] = StandardTypeDescriptor::fromString(str);
00688     parameterTypes[2] = STANDARD_TYPE_INT_8;
00689     table.add(
00690         "convert",
00691         parameterTypes,
00692         (ExtendedInstruction3<int, int, int>*) NULL,
00693         &convertDecimal);
00694     // lookup a function
00695     string s("convert(");
00696     s += str;
00697     s += ",";
00698     s += str;
00699     s += ",";
00700     s += "s1";
00701     s += ")";
00702     cout << s << endl;
00703     ExtendedInstructionDef *pDef = table[s];
00704     assert(pDef != NULL);
00705     assert(pDef->getName() == string("convert"));
00706     assert(pDef->getParameterTypes().size() == 3);
00707     // Set up the Calculator
00708     DynamicParamManager dpm;
00709     TestCalculator c(&dpm, true, pDef);
00710     c.setInput(0, &val);
00711     c.setInput(1, &exp);
00712     // setup registers
00713     vector<RegisterReference *> regRefs(3);
00714     regRefs[0] = new RegisterRef<int>(
00715         RegisterReference::EOutput, 0,
00716         STANDARD_TYPE_INT_32);
00717     regRefs[1] = new RegisterRef<int>(
00718         RegisterReference::EInput, 0,
00719         STANDARD_TYPE_INT_32);
00720     regRefs[2] = new RegisterRef<int>(
00721         RegisterReference::EInput, 1,
00722         STANDARD_TYPE_INT_32);
00723     c.appendRegRef(regRefs[0]);
00724     c.appendRegRef(regRefs[1]);
00725     c.appendRegRef(regRefs[2]);
00726     c.bind();
00727     // create an instruction
00728     //ExtendedInstruction *pInstr = pDef->createInstruction(&c, regRefs);
00729     ExtendedInstruction *pInstr = pDef->createInstruction(regRefs);
00730     assert(pInstr != NULL);
00731     // execute it
00732     c.appendInstruction(pInstr);
00733     c.exec();
00734     c.printOutput();
00735     int i;
00736     c.getOutput(0, i);
00737     //cout << i << endl;
00738     assert(abs(expected - i)<0.00001);
00739 };
00740 
00741 void testConvertStringToExactNumber(const char *str, int expected)
00742 {
00743     printTestHeader("testConvertStringToExactNumber()");
00744     ExtendedInstructionTable table;
00745     vector<StandardTypeDescriptorOrdinal> parameterTypes;
00746     // define a function
00747     parameterTypes.resize(2);
00748     parameterTypes[0] = STANDARD_TYPE_INT_32;
00749     parameterTypes[1] = STANDARD_TYPE_VARCHAR;
00750 
00751     table.add(
00752         "convert",
00753         parameterTypes,
00754         (ExtendedInstruction2<int32_t, char *>*) NULL,
00755         &convertStringToExactNumber);
00756 
00757     // lookup a function
00758     ExtendedInstructionDef *pDef = table["convert(s4,vc)"];
00759     assert(pDef != NULL);
00760     assert(pDef->getName() == string("convert"));
00761     assert(pDef->getParameterTypes().size() == 2);
00762 
00763     // Set up the Calculator
00764     DynamicParamManager dpm;
00765     TestCalculator c(&dpm, true, pDef);
00766     c.setInput(0, str, strlen(str));
00767 
00768     // setup registers
00769     vector<RegisterReference *> regRefs(2);
00770     regRefs[0] = new RegisterRef<int32_t>(
00771         RegisterReference::EOutput, 0,
00772         STANDARD_TYPE_INT_32);
00773     regRefs[1] = new RegisterRef<char *>(
00774         RegisterReference::EInput, 0,
00775         STANDARD_TYPE_VARCHAR);
00776     c.appendRegRef(regRefs[0]);
00777     c.appendRegRef(regRefs[1]);
00778     c.bind();
00779 
00780     // create an instruction
00781     //ExtendedInstruction *pInstr = pDef->createInstruction(&c, regRefs);
00782     ExtendedInstruction *pInstr = pDef->createInstruction(regRefs);
00783     assert(pInstr != NULL);
00784     // execute it
00785     c.appendInstruction(pInstr);
00786     c.exec();
00787     c.printOutput();
00788     int i;
00789     c.getOutput(0, i);
00790     assert(i == expected);
00791     cout << i << endl;
00792 }
00793 
00794 #if 0
00795 // TODO .... JR 6/07 removing this
00796 void testConvertExactNumberToString(int num, char *expected)
00797 {
00798     printTestHeader("testConvertExactNumberToString()");
00799     ExtendedInstructionTable table;
00800     vector<StandardTypeDescriptorOrdinal> parameterTypes;
00801     // define a function
00802     parameterTypes.resize(2);
00803     parameterTypes[0] = STANDARD_TYPE_VARCHAR;
00804     parameterTypes[1] = STANDARD_TYPE_INT_32;
00805 
00806     table.add(
00807         "convert",
00808         parameterTypes,
00809         (ExtendedInstruction2<char *, int32_t>*) NULL,
00810         &convertExactNumberToString);
00811 
00812     // lookup a function
00813     ExtendedInstructionDef *pDef = table["convert(vc,s4)"];
00814     assert(pDef != NULL);
00815     assert(pDef->getName() == string("convert"));
00816     assert(pDef->getParameterTypes().size() == 2);
00817 
00818     // Set up the Calculator
00819     DynamicParamManager dpm;
00820     TestCalculator c(&dpm, true, pDef);
00821     c.setInput(0, &num);
00822     int destLen = strlen(expected);
00823     char *buf = new char[destLen*2];
00824     memset(buf, 'X', destLen*2); // no null terminator
00825     c.setOutput(0, buf, destLen*2, destLen*2);
00826 
00827     // setup registers
00828     vector<RegisterReference *> regRefs(2);
00829     regRefs[0] = new RegisterRef<int32_t>(
00830         RegisterReference::EOutput, 0,
00831         STANDARD_TYPE_VARCHAR);
00832     regRefs[1] = new RegisterRef<char *>(
00833         RegisterReference::EInput, 0,
00834         STANDARD_TYPE_INT_32);
00835     c.appendRegRef(regRefs[0]);
00836     c.appendRegRef(regRefs[1]);
00837     c.bind();
00838 
00839     // create an instruction
00840     //ExtendedInstruction *pInstr = pDef->createInstruction(&c, regRefs);
00841     ExtendedInstruction *pInstr = pDef->createInstruction(regRefs);
00842     assert(pInstr != NULL);
00843     // execute it
00844     c.appendInstruction(pInstr);
00845     c.exec();
00846     c.printOutput();
00847     char *outP;
00848     c.getOutputP(0, outP);
00849     assert(outP == buf);
00850     assert(!strncmp(outP, expected, destLen));
00851     outP[destLen] = 0;
00852     cout << outP << endl;
00853 }
00854 #endif
00855 void testStringToApproximateNumber(char *str, float expected)
00856 {
00857 }
00858 void testApproximateNumberToString(float expected, char *str)
00859 {
00860 }
00861 void testStringToDate(char *str, long long expected)
00862 {
00863 }
00864 void testDateToString(long long d, char *expected)
00865 {
00866 }
00867 
00868 // ----------------------------------------------------------------------
00869 // test cases
00870 // ----------------------------------------------------------------------
00871 int main(int argc, char *argv[])
00872 {
00873     ProgramName = argv[0];
00874     testConvertDoubleToFloat((double) 100.33, (float) 100.33);
00875     testConvertFloatToDouble((float) 33.3378, (double) 33.3378);
00876     testConvertFloatToIntTypes("s1",(float) 45.65, 45);
00877     testConvertFloatToIntTypes("u1",(float) 45.65, 45);
00878     testConvertFloatToIntTypes("s2",(float) 45.65, 45);
00879     testConvertFloatToIntTypes("u2",(float) 45.65, 45);
00880     testConvertFloatToIntTypes("s4",(float) 45.65, 45);
00881     testConvertFloatToIntTypes("u4",(float) 45.65, 45);
00882     testConvertFloatToIntTypes("s8",(float) 45.65, 45);
00883     testConvertFloatToIntTypes("u8",(float) 45.65, 45);
00884     testConvertIntTypesToFloat("s1", 4565, (float) 4565);
00885     testConvertIntTypesToFloat("u1", 4565, (float) 4565);
00886     testConvertIntTypesToFloat("s2", 4565, (float) 4565);
00887     testConvertIntTypesToFloat("u2", 4565, (float) 4565);
00888     testConvertIntTypesToFloat("s4", 4565, (float) 4565);
00889     testConvertIntTypesToFloat("u4", 4565, (float) 4565);
00890     testConvertIntTypesToFloat("s8", 4565, (float) 4565);
00891     testConvertIntTypesToFloat("u8", 4565, (float) 4565);
00892     testConvertDecimal("s2", 123, 3, 123000);
00893 
00894     testConvertStringToExactNumber("123", 123);
00895 //    testConvertExactNumberToString(123, "123"); -- JR 6/07 removing this
00896     printf("all tests passed\n");
00897     exit(0);
00898 }
00899 
00900 boost::unit_test_framework::test_suite *init_unit_test_suite(int,char **)
00901 {
00902     return NULL;
00903 }
00904 
00905 // End testCalcExtended.cpp

Generated on Mon Jun 22 04:00:14 2009 for Fennel by  doxygen 1.5.1