testCalc.cpp

Go to the documentation of this file.
00001 /*
00002 // $Id: //open/dev/fennel/calctest/testCalc.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 
00026 #ifndef __MSVC__
00027 
00028 #include "fennel/common/CommonPreamble.h"
00029 #include "fennel/tuple/TupleDescriptor.h"
00030 #include "fennel/tuple/TupleData.h"
00031 #include "fennel/tuple/TupleAccessor.h"
00032 #include "fennel/tuple/TuplePrinter.h"
00033 #include "fennel/tuple/AttributeAccessor.h"
00034 #include "fennel/tuple/StandardTypeDescriptor.h"
00035 #include "fennel/common/TraceSource.h"
00036 
00037 #include "fennel/calculator/CalcCommon.h"
00038 // required as we're manipulating instructions
00039 #include "fennel/calculator/InstructionCommon.h"
00040 
00041 #include <boost/test/unit_test_suite.hpp>
00042 
00043 #include <stdlib.h>
00044 #include <stdio.h>
00045 #include <string>
00046 #include <boost/scoped_array.hpp>
00047 #include <limits>
00048 #include <iostream.h>
00049 
00050 using namespace std;
00051 using namespace fennel;
00052 
00053 char* ProgramName;
00054 
00055 // JR 6/15/07 this construct:
00056 //instP = new (Instruction *)[200];
00057 // no longer permitted as of GCC 4.0 - remove parens
00058 // so typedef an Instruction * and replace through-out file
00059 typedef Instruction *InstructionPtr;
00060 
00061 void
00062 fail(const char* str, int line) {
00063     assert(ProgramName);
00064     assert(str);
00065     printf("%s: unit test failed: |%s| line %d\n", ProgramName, str, line);
00066     exit(-1);
00067 }
00068 
00069 void
00070 unitTestBool()
00071 {
00072     printf("=========================================================\n");
00073     printf("=========================================================\n");
00074     printf("=====\n");
00075     printf("=====     unitTestBool()\n");
00076     printf("=====\n");
00077     printf("=========================================================\n");
00078     printf("=========================================================\n");
00079     bool isNullable = true;    // Can tuple contain nulls?
00080     int i, registersize = 125;
00081 
00082     TupleDescriptor tupleDesc;
00083     tupleDesc.clear();
00084 
00085     // Build up a description of what we'd like the tuple to look like
00086     StandardTypeDescriptorFactory typeFactory;
00087     for (i = 0;i < registersize; i++) {
00088         StoredTypeDescriptor const &typeDesc =
00089             typeFactory.newDataType(STANDARD_TYPE_BOOL);
00090         tupleDesc.push_back(TupleAttributeDescriptor(typeDesc, isNullable));
00091     }
00092 
00093     // Create a tuple accessor from the description
00094     //
00095     // Note: Must use a NOT_NULL_AND_FIXED accessor when creating a tuple out
00096     // of the air like this, otherwise unmarshal() does not know what to do. If
00097     // you need a STANDARD type tuple that supports nulls, it has to be built
00098     // as a copy.
00099     TupleAccessor tupleAccessorFixedLiteral;
00100     TupleAccessor tupleAccessorFixedInput;
00101     TupleAccessor tupleAccessorFixedOutput;
00102     TupleAccessor tupleAccessorFixedLocal;
00103     TupleAccessor tupleAccessorFixedStatus;
00104     tupleAccessorFixedLiteral.compute(tupleDesc, TUPLE_FORMAT_ALL_FIXED);
00105     tupleAccessorFixedInput.compute(tupleDesc, TUPLE_FORMAT_ALL_FIXED);
00106     tupleAccessorFixedOutput.compute(tupleDesc, TUPLE_FORMAT_ALL_FIXED);
00107     tupleAccessorFixedLocal.compute(tupleDesc, TUPLE_FORMAT_ALL_FIXED);
00108     tupleAccessorFixedStatus.compute(tupleDesc, TUPLE_FORMAT_ALL_FIXED);
00109 
00110     // Allocate memory for the tuple
00111     boost::scoped_array<FixedBuffer> pTupleBufFixedLiteral(
00112         new FixedBuffer[tupleAccessorFixedLiteral.getMaxByteCount()]);
00113     boost::scoped_array<FixedBuffer> pTupleBufFixedInput(
00114         new FixedBuffer[tupleAccessorFixedInput.getMaxByteCount()]);
00115     boost::scoped_array<FixedBuffer> pTupleBufFixedOutput(
00116         new FixedBuffer[tupleAccessorFixedOutput.getMaxByteCount()]);
00117     boost::scoped_array<FixedBuffer> pTupleBufFixedLocal(
00118         new FixedBuffer[tupleAccessorFixedLocal.getMaxByteCount()]);
00119     boost::scoped_array<FixedBuffer> pTupleBufFixedStatus(
00120         new FixedBuffer[tupleAccessorFixedStatus.getMaxByteCount()]);
00121 
00122     // Link memory to accessor
00123     tupleAccessorFixedLiteral.setCurrentTupleBuf(
00124         pTupleBufFixedLiteral.get(), false);
00125     tupleAccessorFixedInput.setCurrentTupleBuf(
00126         pTupleBufFixedInput.get(), false);
00127     tupleAccessorFixedOutput.setCurrentTupleBuf(
00128         pTupleBufFixedOutput.get(), false);
00129     tupleAccessorFixedLocal.setCurrentTupleBuf(
00130         pTupleBufFixedLocal.get(), false);
00131     tupleAccessorFixedStatus.setCurrentTupleBuf(
00132         pTupleBufFixedStatus.get(), false);
00133 
00134     // Create a vector of TupleDatum objects based on the description we built
00135     TupleData tupleDataFixedLiteral(tupleDesc);
00136     TupleData tupleDataFixedInput(tupleDesc);
00137     TupleData tupleDataFixedOutput(tupleDesc);
00138     TupleData tupleDataFixedLocal(tupleDesc);
00139     TupleData tupleDataFixedStatus(tupleDesc);
00140 
00141     // Do something mysterious. Probably binding pointers in the accessor to
00142     // items in the TupleData vector
00143     tupleAccessorFixedLiteral.unmarshal(tupleDataFixedLiteral);
00144     tupleAccessorFixedInput.unmarshal(tupleDataFixedInput);
00145     tupleAccessorFixedOutput.unmarshal(tupleDataFixedOutput);
00146     tupleAccessorFixedLocal.unmarshal(tupleDataFixedLocal);
00147     tupleAccessorFixedStatus.unmarshal(tupleDataFixedStatus);
00148 
00149     TupleData::iterator itr = tupleDataFixedLiteral.begin();
00150     for (i = 0; i < registersize; i++, itr++) {
00151         *(reinterpret_cast<bool *>(const_cast<PBuffer>(itr->pData))) = false;
00152     }
00153     itr = tupleDataFixedInput.begin();
00154     for (i = 0; i < registersize; i++, itr++) {
00155         *(reinterpret_cast<bool *>(const_cast<PBuffer>(itr->pData))) = false;
00156     }
00157     itr = tupleDataFixedOutput.begin();
00158     for (i = 0; i < registersize; i++, itr++) {
00159         *(reinterpret_cast<bool *>(const_cast<PBuffer>(itr->pData))) = false;
00160     }
00161     itr = tupleDataFixedLocal.begin();
00162     for (i = 0; i < registersize; i++, itr++) {
00163         *(reinterpret_cast<bool *>(const_cast<PBuffer>(itr->pData))) = false;
00164     }
00165 
00166     // create four nullable tuples to serve as register sets
00167     TupleData literal = tupleDataFixedLiteral;
00168     TupleData input = tupleDataFixedInput;
00169     TupleData output = tupleDataFixedOutput;
00170     TupleData local = tupleDataFixedLocal;
00171     TupleData status = tupleDataFixedStatus;
00172 
00173     // null out last element of each type
00174     int nullidx = registersize-1;
00175     literal[nullidx].pData = NULL;
00176     input[nullidx].pData = NULL;
00177     output[nullidx].pData = NULL;
00178     local[nullidx].pData = NULL;
00179 
00180     // Print out the nullable tuple
00181     TuplePrinter tuplePrinter;
00182     tuplePrinter.print(cout, tupleDesc, literal);
00183     cout << endl;
00184     tuplePrinter.print(cout, tupleDesc, input);
00185     cout << endl;
00186     tuplePrinter.print(cout, tupleDesc, output);
00187     cout << endl;
00188     tuplePrinter.print(cout, tupleDesc, local);
00189     cout << endl;
00190 
00191     // set up some nice literals for tests
00192     *(reinterpret_cast<bool *>(const_cast<PBuffer>((literal[0].pData)))) =
00193         false;
00194     *(reinterpret_cast<bool *>(const_cast<PBuffer>((literal[1].pData)))) =
00195         true;
00196 
00197     // predefine register references. a real compiler wouldn't do
00198     // something so regular and pre-determined. a compiler would
00199     // probably build these on the fly as it built each instruction.
00200     RegisterRef<bool> **bInP, **bOutP, **bLoP, **bLiP;
00201     bInP = new RegisterRef<bool>*[registersize];
00202     bOutP = new RegisterRef<bool>*[registersize];
00203     bLoP = new RegisterRef<bool>*[registersize];
00204     bLiP = new RegisterRef<bool>*[registersize];
00205 
00206     // Set up the Calculator
00207     DynamicParamManager dpm;
00208     Calculator c(&dpm,0,0,0,0,0,0);
00209     c.outputRegisterByReference(false);
00210 
00211     // set up register references to symbolically point to
00212     // their corresponding storage locations -- makes for easy test case
00213     // generation. again, a compiler wouldn't do things in quite
00214     // this way
00215     for (i = 0; i < registersize; i++) {
00216         bInP[i] = new RegisterRef<bool>(
00217             RegisterReference::EInput,
00218             i,
00219             STANDARD_TYPE_BOOL);
00220         c.appendRegRef(bInP[i]);
00221         bOutP[i] = new RegisterRef<bool>(
00222             RegisterReference::EOutput,
00223             i,
00224             STANDARD_TYPE_BOOL);
00225         c.appendRegRef(bOutP[i]);
00226         bLoP[i] = new RegisterRef<bool>(
00227             RegisterReference::ELocal,
00228             i,
00229             STANDARD_TYPE_BOOL);
00230         c.appendRegRef(bLoP[i]);
00231         bLiP[i] = new RegisterRef<bool>(
00232             RegisterReference::ELiteral,
00233             i,
00234             STANDARD_TYPE_BOOL);
00235         c.appendRegRef(bLiP[i]);
00236     }
00237 
00238 
00239     // Set up storage for instructions
00240     // a real compiler would probably cons up instructions and insert them
00241     // directly into the calculator. keep an array of the instructions at
00242     // this level to allow printing of the program after execution, and other
00243     // debugging
00244     Instruction **instP;
00245     instP = new InstructionPtr[200];
00246     int pc = 0, outC = 0;
00247 
00248     // not
00249     instP[pc++] = new BoolNot(bOutP[outC++], bLiP[0]);
00250     instP[pc++] = new BoolNot(bOutP[outC++], bLiP[1]);
00251     instP[pc++] = new BoolNot(bOutP[outC++], bLiP[nullidx]);
00252 
00253     // and
00254     instP[pc++] = new BoolAnd(bOutP[outC++], bLiP[0], bLiP[0]);
00255     instP[pc++] = new BoolAnd(bOutP[outC++], bLiP[1], bLiP[1]);
00256     instP[pc++] = new BoolAnd(bOutP[outC++], bLiP[0], bLiP[1]);
00257     instP[pc++] = new BoolAnd(bOutP[outC++], bLiP[1], bLiP[0]);
00258     instP[pc++] = new BoolAnd(bOutP[outC++], bLiP[nullidx], bLiP[0]);
00259     instP[pc++] = new BoolAnd(bOutP[outC++], bLiP[nullidx], bLiP[1]);
00260     instP[pc++] = new BoolAnd(bOutP[outC++], bLiP[0], bLiP[nullidx]);
00261     instP[pc++] = new BoolAnd(bOutP[outC++], bLiP[1], bLiP[nullidx]);
00262     instP[pc++] = new BoolAnd(bOutP[outC++], bLiP[nullidx], bLiP[nullidx]);
00263 
00264     // or
00265     instP[pc++] = new BoolOr(bOutP[outC++], bLiP[0], bLiP[0]);
00266     instP[pc++] = new BoolOr(bOutP[outC++], bLiP[1], bLiP[1]);
00267     instP[pc++] = new BoolOr(bOutP[outC++], bLiP[0], bLiP[1]);
00268     instP[pc++] = new BoolOr(bOutP[outC++], bLiP[1], bLiP[0]);
00269     instP[pc++] = new BoolOr(bOutP[outC++], bLiP[nullidx], bLiP[0]);
00270     instP[pc++] = new BoolOr(bOutP[outC++], bLiP[nullidx], bLiP[1]);
00271     instP[pc++] = new BoolOr(bOutP[outC++], bLiP[0], bLiP[nullidx]);
00272     instP[pc++] = new BoolOr(bOutP[outC++], bLiP[1], bLiP[nullidx]);
00273     instP[pc++] = new BoolOr(bOutP[outC++], bLiP[nullidx], bLiP[nullidx]);
00274 
00275     // move
00276     instP[pc++] = new BoolMove(bOutP[outC++], bLiP[0]);
00277     instP[pc++] = new BoolMove(bOutP[outC++], bLiP[1]);
00278     instP[pc++] = new BoolMove(bOutP[outC++], bLiP[nullidx]);
00279 
00280     // is
00281     instP[pc++] = new BoolIs(bOutP[outC++], bLiP[0], bLiP[0]);
00282     instP[pc++] = new BoolIs(bOutP[outC++], bLiP[1], bLiP[1]);
00283     instP[pc++] = new BoolIs(bOutP[outC++], bLiP[0], bLiP[1]);
00284     instP[pc++] = new BoolIs(bOutP[outC++], bLiP[1], bLiP[0]);
00285 
00286     instP[pc++] = new BoolIs(bOutP[outC++], bLiP[nullidx], bLiP[0]);
00287     instP[pc++] = new BoolIs(bOutP[outC++], bLiP[nullidx], bLiP[1]);
00288     instP[pc++] = new BoolIs(bOutP[outC++], bLiP[0], bLiP[nullidx]);
00289     instP[pc++] = new BoolIs(bOutP[outC++], bLiP[1], bLiP[nullidx]);
00290     instP[pc++] = new BoolIs(bOutP[outC++], bLiP[nullidx], bLiP[nullidx]);
00291 
00292     // isnot
00293     instP[pc++] = new BoolIsNot(bOutP[outC++], bLiP[0], bLiP[0]);
00294     instP[pc++] = new BoolIsNot(bOutP[outC++], bLiP[1], bLiP[1]);
00295     instP[pc++] = new BoolIsNot(bOutP[outC++], bLiP[0], bLiP[1]);
00296     instP[pc++] = new BoolIsNot(bOutP[outC++], bLiP[1], bLiP[0]);
00297 
00298     instP[pc++] = new BoolIsNot(bOutP[outC++], bLiP[nullidx], bLiP[0]);
00299     instP[pc++] = new BoolIsNot(bOutP[outC++], bLiP[nullidx], bLiP[1]);
00300     instP[pc++] = new BoolIsNot(bOutP[outC++], bLiP[0], bLiP[nullidx]);
00301     instP[pc++] = new BoolIsNot(bOutP[outC++], bLiP[1], bLiP[nullidx]);
00302     instP[pc++] = new BoolIsNot(bOutP[outC++], bLiP[nullidx], bLiP[nullidx]);
00303 
00304     // equal
00305     instP[pc++] = new BoolEqual(bOutP[outC++], bLiP[0], bLiP[0]);
00306     instP[pc++] = new BoolEqual(bOutP[outC++], bLiP[1], bLiP[1]);
00307     instP[pc++] = new BoolEqual(bOutP[outC++], bLiP[0], bLiP[1]);
00308     instP[pc++] = new BoolEqual(bOutP[outC++], bLiP[1], bLiP[0]);
00309 
00310     instP[pc++] = new BoolEqual(bOutP[outC++], bLiP[nullidx], bLiP[0]);
00311     instP[pc++] = new BoolEqual(bOutP[outC++], bLiP[nullidx], bLiP[1]);
00312     instP[pc++] = new BoolEqual(bOutP[outC++], bLiP[0], bLiP[nullidx]);
00313     instP[pc++] = new BoolEqual(bOutP[outC++], bLiP[1], bLiP[nullidx]);
00314     instP[pc++] = new BoolEqual(bOutP[outC++], bLiP[nullidx], bLiP[nullidx]);
00315 
00316     // notequal
00317     instP[pc++] = new BoolNotEqual(bOutP[outC++], bLiP[0], bLiP[0]);
00318     instP[pc++] = new BoolNotEqual(bOutP[outC++], bLiP[1], bLiP[1]);
00319     instP[pc++] = new BoolNotEqual(bOutP[outC++], bLiP[0], bLiP[1]);
00320     instP[pc++] = new BoolNotEqual(bOutP[outC++], bLiP[1], bLiP[0]);
00321 
00322     instP[pc++] = new BoolNotEqual(bOutP[outC++], bLiP[nullidx], bLiP[0]);
00323     instP[pc++] = new BoolNotEqual(bOutP[outC++], bLiP[nullidx], bLiP[1]);
00324     instP[pc++] = new BoolNotEqual(bOutP[outC++], bLiP[0], bLiP[nullidx]);
00325     instP[pc++] = new BoolNotEqual(bOutP[outC++], bLiP[1], bLiP[nullidx]);
00326     instP[pc++] = new BoolNotEqual(bOutP[outC++], bLiP[nullidx], bLiP[nullidx]);
00327 
00328     // greater
00329     instP[pc++] = new BoolGreater(bOutP[outC++], bLiP[0], bLiP[0]);
00330     instP[pc++] = new BoolGreater(bOutP[outC++], bLiP[1], bLiP[1]);
00331     instP[pc++] = new BoolGreater(bOutP[outC++], bLiP[0], bLiP[1]);
00332     instP[pc++] = new BoolGreater(bOutP[outC++], bLiP[1], bLiP[0]);
00333 
00334     instP[pc++] = new BoolGreater(bOutP[outC++], bLiP[nullidx], bLiP[0]);
00335     instP[pc++] = new BoolGreater(bOutP[outC++], bLiP[nullidx], bLiP[1]);
00336     instP[pc++] = new BoolGreater(bOutP[outC++], bLiP[0], bLiP[nullidx]);
00337     instP[pc++] = new BoolGreater(bOutP[outC++], bLiP[1], bLiP[nullidx]);
00338     instP[pc++] = new BoolGreater(bOutP[outC++], bLiP[nullidx], bLiP[nullidx]);
00339 
00340     // greaterequal
00341     instP[pc++] = new BoolGreaterEqual(bOutP[outC++], bLiP[0], bLiP[0]);
00342     instP[pc++] = new BoolGreaterEqual(bOutP[outC++], bLiP[1], bLiP[1]);
00343     instP[pc++] = new BoolGreaterEqual(bOutP[outC++], bLiP[0], bLiP[1]);
00344     instP[pc++] = new BoolGreaterEqual(bOutP[outC++], bLiP[1], bLiP[0]);
00345 
00346     instP[pc++] = new BoolGreaterEqual(bOutP[outC++], bLiP[nullidx], bLiP[0]);
00347     instP[pc++] = new BoolGreaterEqual(bOutP[outC++], bLiP[nullidx], bLiP[1]);
00348     instP[pc++] = new BoolGreaterEqual(bOutP[outC++], bLiP[0], bLiP[nullidx]);
00349     instP[pc++] = new BoolGreaterEqual(bOutP[outC++], bLiP[1], bLiP[nullidx]);
00350     instP[pc++] =
00351         new BoolGreaterEqual(bOutP[outC++], bLiP[nullidx], bLiP[nullidx]);
00352 
00353     // less
00354     instP[pc++] = new BoolLess(bOutP[outC++], bLiP[0], bLiP[0]);
00355     instP[pc++] = new BoolLess(bOutP[outC++], bLiP[1], bLiP[1]);
00356     instP[pc++] = new BoolLess(bOutP[outC++], bLiP[0], bLiP[1]);
00357     instP[pc++] = new BoolLess(bOutP[outC++], bLiP[1], bLiP[0]);
00358 
00359     instP[pc++] = new BoolLess(bOutP[outC++], bLiP[nullidx], bLiP[0]);
00360     instP[pc++] = new BoolLess(bOutP[outC++], bLiP[nullidx], bLiP[1]);
00361     instP[pc++] = new BoolLess(bOutP[outC++], bLiP[0], bLiP[nullidx]);
00362     instP[pc++] = new BoolLess(bOutP[outC++], bLiP[1], bLiP[nullidx]);
00363     instP[pc++] = new BoolLess(bOutP[outC++], bLiP[nullidx], bLiP[nullidx]);
00364 
00365     // lessequal
00366     instP[pc++] = new BoolLessEqual(bOutP[outC++], bLiP[0], bLiP[0]);
00367     instP[pc++] = new BoolLessEqual(bOutP[outC++], bLiP[1], bLiP[1]);
00368     instP[pc++] = new BoolLessEqual(bOutP[outC++], bLiP[0], bLiP[1]);
00369     instP[pc++] = new BoolLessEqual(bOutP[outC++], bLiP[1], bLiP[0]);
00370 
00371     instP[pc++] = new BoolLessEqual(bOutP[outC++], bLiP[nullidx], bLiP[0]);
00372     instP[pc++] = new BoolLessEqual(bOutP[outC++], bLiP[nullidx], bLiP[1]);
00373     instP[pc++] = new BoolLessEqual(bOutP[outC++], bLiP[0], bLiP[nullidx]);
00374     instP[pc++] = new BoolLessEqual(bOutP[outC++], bLiP[1], bLiP[nullidx]);
00375     instP[pc++] =
00376         new BoolLessEqual(bOutP[outC++], bLiP[nullidx], bLiP[nullidx]);
00377 
00378     // isnull
00379     instP[pc++] = new BoolIsNull(bOutP[outC++], bLiP[1]);
00380     instP[pc++] = new BoolIsNull(bOutP[outC++], bLiP[nullidx]);
00381 
00382     // isnotnull
00383     instP[pc++] = new BoolIsNotNull(bOutP[outC++], bLiP[1]);
00384     instP[pc++] = new BoolIsNotNull(bOutP[outC++], bLiP[nullidx]);
00385 
00386     // tonull
00387     instP[pc++] = new BoolToNull(bOutP[outC++]);
00388     int lastPC = pc;
00389 
00390     for (i = 0; i < pc; i++) {
00391         c.appendInstruction(instP[i]);
00392     }
00393     c.bind(
00394         RegisterReference::ELiteral,
00395         &literal,
00396         tupleDesc);
00397     c.bind(
00398         RegisterReference::EInput,
00399         &input,
00400         tupleDesc);
00401     c.bind(
00402         RegisterReference::EOutput,
00403         &output,
00404         tupleDesc);
00405     c.bind(
00406         RegisterReference::ELocal,
00407         &local,
00408         tupleDesc);
00409     c.bind(
00410         RegisterReference::EStatus,
00411         &status,
00412         tupleDesc);
00413     c.exec();
00414 
00415     string out;
00416     for (i = 0; i < pc; i++) {
00417         instP[i]->describe(out, true);
00418         printf("[%2d] %s\n", i, out.c_str());
00419     }
00420     if (!c.mWarnings.empty()) {
00421         fail("boolwarnings", __LINE__);
00422     }
00423 
00424     // Print out the output tuple
00425     tuplePrinter.print(cout, tupleDesc, output);
00426     cout << endl;
00427 
00428     outC = 0;
00429     // not
00430     if (*(output[outC++].pData) != true) {
00431         fail("boolnot1", __LINE__);
00432     }
00433     if (*(output[outC++].pData) != false) {
00434         fail("boolnot2", __LINE__);
00435     }
00436     if (output[outC++].pData != NULL) {
00437         fail("boolnot3", __LINE__);
00438     }
00439 
00440     // and
00441     if (*(output[outC++].pData) != false) {
00442         fail("booland1", __LINE__);
00443     }
00444     if (*(output[outC++].pData) != true) {
00445         fail("booland2", __LINE__);
00446     }
00447     if (*(output[outC++].pData) != false) {
00448         fail("booland3", __LINE__);
00449     }
00450     if (*(output[outC++].pData) != false) {
00451         fail("booland4", __LINE__);
00452     }
00453 
00454     if (*(output[outC++].pData) != false) {
00455         fail("booland5", __LINE__);
00456     }
00457     if (output[outC++].pData != NULL) {
00458         fail("booland6", __LINE__);
00459     }
00460     if (*(output[outC++].pData) != false) {
00461         fail("booland7", __LINE__);
00462     }
00463     if (output[outC++].pData != NULL) {
00464         fail("booland8", __LINE__);
00465     }
00466     if (output[outC++].pData != NULL) {
00467         fail("booland9", __LINE__);
00468     }
00469 
00470     // or
00471     if (*(output[outC++].pData) != false) {
00472         fail("boolor1", __LINE__);
00473     }
00474     if (*(output[outC++].pData) != true) {
00475         fail("boolor2", __LINE__);
00476     }
00477     if (*(output[outC++].pData) != true) {
00478         fail("boolor3", __LINE__);
00479     }
00480     if (*(output[outC++].pData) != true) {
00481         fail("boolor4", __LINE__);
00482     }
00483 
00484     if (output[outC++].pData != NULL) {
00485         fail("boolor5", __LINE__);
00486     }
00487     if (*(output[outC++].pData) != true) {
00488         fail("boolor6", __LINE__);
00489     }
00490     if (output[outC++].pData != NULL) {
00491         fail("boolor7", __LINE__);
00492     }
00493     if (*(output[outC++].pData) != true) {
00494         fail("boolor8", __LINE__);
00495     }
00496     if (output[outC++].pData != NULL) {
00497         fail("boolor9", __LINE__);
00498     }
00499 
00500     // move
00501     if (*(output[outC++].pData) != false) {
00502         fail("boolmove1", __LINE__);
00503     }
00504     if (*(output[outC++].pData) != true) {
00505         fail("boolmove2", __LINE__);
00506     }
00507     if (output[outC++].pData != NULL) {
00508         fail("boolmove3", __LINE__);
00509     }
00510 
00511     // is
00512     if (*(output[outC++].pData) != true) {
00513         fail("boolis1", __LINE__);
00514     }
00515     if (*(output[outC++].pData) != true) {
00516         fail("boolis2", __LINE__);
00517     }
00518     if (*(output[outC++].pData) != false) {
00519         fail("boolis3", __LINE__);
00520     }
00521     if (*(output[outC++].pData) != false) {
00522         fail("boolis4", __LINE__);
00523     }
00524 
00525     if (*(output[outC++].pData) != false) {
00526         fail("boolis5", __LINE__);
00527     }
00528     if (*(output[outC++].pData) != false) {
00529         fail("boolis6", __LINE__);
00530     }
00531     if (*(output[outC++].pData) != false) {
00532         fail("boolis7", __LINE__);
00533     }
00534     if (*(output[outC++].pData) != false) {
00535         fail("boolis8", __LINE__);
00536     }
00537     if (*(output[outC++].pData) != true) {
00538         fail("boolis9", __LINE__);
00539     }
00540 
00541     // isnot
00542     if (*(output[outC++].pData) != false) {
00543         fail("boolisnot1", __LINE__);
00544     }
00545     if (*(output[outC++].pData) != false) {
00546         fail("boolisnot2", __LINE__);
00547     }
00548     if (*(output[outC++].pData) != true) {
00549         fail("boolisnot3", __LINE__);
00550     }
00551     if (*(output[outC++].pData) != true) {
00552         fail("boolisnot4", __LINE__);
00553     }
00554 
00555     if (*(output[outC++].pData) != true) {
00556         fail("boolisnot5", __LINE__);
00557     }
00558     if (*(output[outC++].pData) != true) {
00559         fail("boolisnot6", __LINE__);
00560     }
00561     if (*(output[outC++].pData) != true) {
00562         fail("boolisnot7", __LINE__);
00563     }
00564     if (*(output[outC++].pData) != true) {
00565         fail("boolisnot8", __LINE__);
00566     }
00567     if (*(output[outC++].pData) != false) {
00568         fail("boolisnot9", __LINE__);
00569     }
00570 
00571     // equal
00572     if (*(output[outC++].pData) != true) {
00573         fail("boolequal1", __LINE__);
00574     }
00575     if (*(output[outC++].pData) != true) {
00576         fail("boolequal2", __LINE__);
00577     }
00578     if (*(output[outC++].pData) != false) {
00579         fail("boolequal3", __LINE__);
00580     }
00581     if (*(output[outC++].pData) != false) {
00582         fail("boolequal4", __LINE__);
00583     }
00584 
00585     if (output[outC++].pData != NULL) {
00586         fail("boolequal5", __LINE__);
00587     }
00588     if (output[outC++].pData != NULL) {
00589         fail("boolequal6", __LINE__);
00590     }
00591     if (output[outC++].pData != NULL) {
00592         fail("boolequal7", __LINE__);
00593     }
00594     if (output[outC++].pData != NULL) {
00595         fail("boolequal8", __LINE__);
00596     }
00597     if (output[outC++].pData != NULL) {
00598         fail("boolequal9", __LINE__);
00599     }
00600 
00601     // notequal
00602     if (*(output[outC++].pData) != false) {
00603         fail("boolnotequal1", __LINE__);
00604     }
00605     if (*(output[outC++].pData) != false) {
00606         fail("boolnotequal2", __LINE__);
00607     }
00608     if (*(output[outC++].pData) != true) {
00609         fail("boolnotequal3", __LINE__);
00610     }
00611     if (*(output[outC++].pData) != true) {
00612         fail("boolnotequal4", __LINE__);
00613     }
00614 
00615     if (output[outC++].pData != NULL) {
00616         fail("boolnotequal5", __LINE__);
00617     }
00618     if (output[outC++].pData != NULL) {
00619         fail("boolnotequal6", __LINE__);
00620     }
00621     if (output[outC++].pData != NULL) {
00622         fail("boolnotequal7", __LINE__);
00623     }
00624     if (output[outC++].pData != NULL) {
00625         fail("boolnotequal8", __LINE__);
00626     }
00627     if (output[outC++].pData != NULL) {
00628         fail("boolnotequal9", __LINE__);
00629     }
00630 
00631     // greater
00632     if (*(output[outC++].pData) != false) {
00633         fail("boolgreater1", __LINE__);
00634     }
00635     if (*(output[outC++].pData) != false) {
00636         fail("boolgreater2", __LINE__);
00637     }
00638     if (*(output[outC++].pData) != false) {
00639         fail("boolgreater3", __LINE__);
00640     }
00641     if (*(output[outC++].pData) != true) {
00642         fail("boolgreater4", __LINE__);
00643     }
00644 
00645     if (output[outC++].pData != NULL) {
00646         fail("boolgreater5", __LINE__);
00647     }
00648     if (output[outC++].pData != NULL) {
00649         fail("boolgreater6", __LINE__);
00650     }
00651     if (output[outC++].pData != NULL) {
00652         fail("boolgreater7", __LINE__);
00653     }
00654     if (output[outC++].pData != NULL) {
00655         fail("boolgreater8", __LINE__);
00656     }
00657     if (output[outC++].pData != NULL) {
00658         fail("boolgreater9", __LINE__);
00659     }
00660 
00661     // greaterequal
00662     if (*(output[outC++].pData) != true) {
00663         fail("boolgreaterequal1", __LINE__);
00664     }
00665     if (*(output[outC++].pData) != true) {
00666         fail("boolgreaterequal2", __LINE__);
00667     }
00668     if (*(output[outC++].pData) != false) {
00669         fail("boolgreaterequal3", __LINE__);
00670     }
00671     if (*(output[outC++].pData) != true) {
00672         fail("boolgreaterequal4", __LINE__);
00673     }
00674 
00675     if (output[outC++].pData != NULL) {
00676         fail("boolgreaterequal5", __LINE__);
00677     }
00678     if (output[outC++].pData != NULL) {
00679         fail("boolgreaterequal6", __LINE__);
00680     }
00681     if (output[outC++].pData != NULL) {
00682         fail("boolgreaterequal7", __LINE__);
00683     }
00684     if (output[outC++].pData != NULL) {
00685         fail("boolgreaterequal8", __LINE__);
00686     }
00687     if (output[outC++].pData != NULL) {
00688         fail("boolgreaterequal9", __LINE__);
00689     }
00690 
00691     // less
00692     if (*(output[outC++].pData) != false) {
00693         fail("boolless1", __LINE__);
00694     }
00695     if (*(output[outC++].pData) != false) {
00696         fail("boolless2", __LINE__);
00697     }
00698     if (*(output[outC++].pData) != true) {
00699         fail("boolless3", __LINE__);
00700     }
00701     if (*(output[outC++].pData) != false) {
00702         fail("boolless4", __LINE__);
00703     }
00704 
00705     if (output[outC++].pData != NULL) {
00706         fail("boolless5", __LINE__);
00707     }
00708     if (output[outC++].pData != NULL) {
00709         fail("boolless6", __LINE__);
00710     }
00711     if (output[outC++].pData != NULL) {
00712         fail("boolless7", __LINE__);
00713     }
00714     if (output[outC++].pData != NULL) {
00715         fail("boolless8", __LINE__);
00716     }
00717     if (output[outC++].pData != NULL) {
00718         fail("boolless9", __LINE__);
00719     }
00720 
00721     // lessequal
00722     if (*(output[outC++].pData) != true) {
00723         fail("boollessequal1", __LINE__);
00724     }
00725     if (*(output[outC++].pData) != true) {
00726         fail("boollessequal2", __LINE__);
00727     }
00728     if (*(output[outC++].pData) != true) {
00729         fail("boollessequal3", __LINE__);
00730     }
00731     if (*(output[outC++].pData) != false) {
00732         fail("boollessequal4", __LINE__);
00733     }
00734 
00735     if (output[outC++].pData != NULL) {
00736         fail("boollessequal5", __LINE__);
00737     }
00738     if (output[outC++].pData != NULL) {
00739         fail("boollessequal6", __LINE__);
00740     }
00741     if (output[outC++].pData != NULL) {
00742         fail("boollessequal7", __LINE__);
00743     }
00744     if (output[outC++].pData != NULL) {
00745         fail("boollessequal8", __LINE__);
00746     }
00747     if (output[outC++].pData != NULL) {
00748         fail("boollessequal9", __LINE__);
00749     }
00750 
00751     // isnull
00752     if (*(output[outC++].pData) != false) {
00753         fail("boolisnull1", __LINE__);
00754     }
00755     if (*(output[outC++].pData) != true) {
00756         fail("boolisnull1", __LINE__);
00757     }
00758 
00759     // isnotnull
00760     if (*(output[outC++].pData) != true) {
00761         fail("boolisnotnull1", __LINE__);
00762     }
00763     if (*(output[outC++].pData) != false) {
00764         fail("boolisnotnull1", __LINE__);
00765     }
00766 
00767     // tonull
00768     if (output[outC++].pData != NULL) {
00769         fail("booltonull1", __LINE__);
00770     }
00771 
00772     cout << "Calculator Warnings: " << c.warnings() << endl;
00773 
00774     delete [] bInP;
00775     delete [] bOutP;
00776     delete [] bLoP;
00777     delete [] bLiP;
00778     for (i = 0; i < lastPC; i++) {
00779         delete instP[i];
00780     }
00781     delete [] instP;
00782 }
00783 
00784 void
00785 unitTestLong()
00786 {
00787     printf("=========================================================\n");
00788     printf("=========================================================\n");
00789     printf("=====\n");
00790     printf("=====     unitTestLong()\n");
00791     printf("=====\n");
00792     printf("=========================================================\n");
00793     printf("=========================================================\n");
00794     bool isNullable = true;    // Can tuple contain nulls?
00795     int i, registersize = 200;
00796 
00797     TupleDescriptor tupleDesc;
00798     tupleDesc.clear();
00799 
00800     // Build up a description of what we'd like the tuple to look like
00801     StandardTypeDescriptorFactory typeFactory;
00802     for (i = 0;i < registersize; i++) {
00803         // longs in first "half"
00804         StoredTypeDescriptor const &typeDesc =
00805             typeFactory.newDataType(STANDARD_TYPE_INT_32);
00806         tupleDesc.push_back(TupleAttributeDescriptor(typeDesc, isNullable));
00807     }
00808     for (i = 0;i < registersize; i++) {
00809         // booleans in second "half"
00810         StoredTypeDescriptor const &typeDesc =
00811             typeFactory.newDataType(STANDARD_TYPE_UINT_8);
00812         tupleDesc.push_back(TupleAttributeDescriptor(typeDesc, isNullable));
00813     }
00814 
00815     // Create a tuple accessor from the description
00816     //
00817     // Note: Must use a NOT_NULL_AND_FIXED accessor when creating a tuple out
00818     // of the air like this, otherwise unmarshal() does not know what to do. If
00819     // you need a STANDARD type tuple that supports nulls, it has to be built
00820     // as a copy.
00821     TupleAccessor tupleAccessorFixedLiteral;
00822     TupleAccessor tupleAccessorFixedInput;
00823     TupleAccessor tupleAccessorFixedOutput;
00824     TupleAccessor tupleAccessorFixedLocal;
00825     TupleAccessor tupleAccessorFixedStatus;
00826     tupleAccessorFixedLiteral.compute(tupleDesc, TUPLE_FORMAT_ALL_FIXED);
00827     tupleAccessorFixedInput.compute(tupleDesc, TUPLE_FORMAT_ALL_FIXED);
00828     tupleAccessorFixedOutput.compute(tupleDesc, TUPLE_FORMAT_ALL_FIXED);
00829     tupleAccessorFixedLocal.compute(tupleDesc, TUPLE_FORMAT_ALL_FIXED);
00830     tupleAccessorFixedStatus.compute(tupleDesc, TUPLE_FORMAT_ALL_FIXED);
00831 
00832     // Allocate memory for the tuple
00833     boost::scoped_array<FixedBuffer> pTupleBufFixedLiteral(
00834         new FixedBuffer[tupleAccessorFixedLiteral.getMaxByteCount()]);
00835     boost::scoped_array<FixedBuffer> pTupleBufFixedInput(
00836         new FixedBuffer[tupleAccessorFixedInput.getMaxByteCount()]);
00837     boost::scoped_array<FixedBuffer> pTupleBufFixedOutput(
00838         new FixedBuffer[tupleAccessorFixedOutput.getMaxByteCount()]);
00839     boost::scoped_array<FixedBuffer> pTupleBufFixedLocal(
00840         new FixedBuffer[tupleAccessorFixedLocal.getMaxByteCount()]);
00841     boost::scoped_array<FixedBuffer> pTupleBufFixedStatus(
00842         new FixedBuffer[tupleAccessorFixedStatus.getMaxByteCount()]);
00843 
00844     // Link memory to accessor
00845     tupleAccessorFixedLiteral.setCurrentTupleBuf(
00846         pTupleBufFixedLiteral.get(), false);
00847     tupleAccessorFixedInput.setCurrentTupleBuf(
00848         pTupleBufFixedInput.get(), false);
00849     tupleAccessorFixedOutput.setCurrentTupleBuf(
00850         pTupleBufFixedOutput.get(), false);
00851     tupleAccessorFixedLocal.setCurrentTupleBuf(
00852         pTupleBufFixedLocal.get(), false);
00853     tupleAccessorFixedStatus.setCurrentTupleBuf(
00854         pTupleBufFixedStatus.get(), false);
00855 
00856     // Create a vector of TupleDatum objects based on the description we built
00857     TupleData tupleDataFixedLiteral(tupleDesc);
00858     TupleData tupleDataFixedInput(tupleDesc);
00859     TupleData tupleDataFixedOutput(tupleDesc);
00860     TupleData tupleDataFixedLocal(tupleDesc);
00861     TupleData tupleDataFixedStatus(tupleDesc);
00862 
00863     // Do something mysterious. Probably binding pointers in the accessor to
00864     // items in the TupleData vector
00865     tupleAccessorFixedLiteral.unmarshal(tupleDataFixedLiteral);
00866     tupleAccessorFixedInput.unmarshal(tupleDataFixedInput);
00867     tupleAccessorFixedOutput.unmarshal(tupleDataFixedOutput);
00868     tupleAccessorFixedLocal.unmarshal(tupleDataFixedLocal);
00869     tupleAccessorFixedStatus.unmarshal(tupleDataFixedStatus);
00870 
00871     // create four nullable tuples to serve as register sets
00872     TupleData literal = tupleDataFixedLiteral;
00873     TupleData input = tupleDataFixedInput;
00874     TupleData output = tupleDataFixedOutput;
00875     TupleData local = tupleDataFixedLocal;
00876     TupleData status = tupleDataFixedStatus;
00877 
00878     TupleData::iterator itr = literal.begin();
00879     for (i = 0; i < registersize; i++, itr++) {
00880         // set up some nice literals for tests
00881         if (i % 2) {
00882             *(reinterpret_cast<int32_t *>(const_cast<PBuffer>(itr->pData))) =
00883                 i * -1;
00884         } else {
00885             *(reinterpret_cast<int32_t *>(const_cast<PBuffer>(itr->pData))) = i;
00886         }
00887     }
00888     itr = input.begin();
00889     for (i = 0; i < registersize; i++, itr++) {
00890         *(reinterpret_cast<int32_t *>(const_cast<PBuffer>(itr->pData))) = -1;
00891     }
00892     itr = output.begin();
00893     for (i = 0; i < registersize; i++, itr++) {
00894         *(reinterpret_cast<int32_t *>(const_cast<PBuffer>(itr->pData))) = -1;
00895     }
00896     itr = local.begin();
00897     for (i = 0; i < registersize; i++, itr++) {
00898         *(reinterpret_cast<int32_t *>(const_cast<PBuffer>(itr->pData))) = -1;
00899     }
00900 
00901     // set up boolean literals
00902     int falseIdx = 0;
00903     int trueIdx = 1;
00904     *(reinterpret_cast<bool *>
00905       (const_cast<PBuffer>
00906        (literal[trueIdx + registersize].pData))) = true;
00907     *(reinterpret_cast<bool *>
00908       (const_cast<PBuffer>
00909        (literal[falseIdx + registersize].pData))) = false;
00910 
00911 
00912     // null out last element of each type
00913     int nullidx = registersize - 1;
00914     literal[nullidx].pData = NULL;
00915     input[nullidx].pData = NULL;
00916     output[nullidx].pData = NULL;
00917     local[nullidx].pData = NULL;
00918 
00919     // also make a null in the boolean part of the literal set
00920     int boolnullidx = (2 * registersize) - 1;
00921     literal[boolnullidx].pData = NULL;
00922 
00923     // Print out the nullable tuple
00924     TuplePrinter tuplePrinter;
00925     printf("Literals\n");
00926     tuplePrinter.print(cout, tupleDesc, literal);
00927     printf("\nInput\n");
00928     tuplePrinter.print(cout, tupleDesc, input);
00929     cout << endl;
00930     printf("\nOutput\n");
00931     tuplePrinter.print(cout, tupleDesc, output);
00932     cout << endl;
00933     printf("\nLocal\n");
00934     tuplePrinter.print(cout, tupleDesc, local);
00935     cout << endl;
00936 
00937 
00938     // predefine register references. a real compiler wouldn't do
00939     // something so regular and pre-determined. a compiler would
00940     // probably build these on the fly as it built each instruction.
00941     // predefine register references. a real compiler wouldn't do
00942     // something so regular and pre-determined
00943     RegisterRef<int32_t> **bInP, **bOutP, **bLoP, **bLiP;
00944     RegisterRef<bool> **bOutBoolP, **bLiteralBoolP;
00945     bInP = new RegisterRef<int32_t>*[registersize];
00946     bOutP = new RegisterRef<int32_t>*[registersize];
00947     bLoP = new RegisterRef<int32_t>*[registersize];
00948     bLiP = new RegisterRef<int32_t>*[registersize];
00949     bOutBoolP = new RegisterRef<bool>*[registersize];
00950     bLiteralBoolP = new RegisterRef<bool>*[registersize];
00951 
00952     // Set up the Calculator
00953     DynamicParamManager dpm;
00954     Calculator c(&dpm,0,0,0,0,0,0);
00955     c.outputRegisterByReference(false);
00956 
00957     // set up register references to symbolically point to
00958     // their corresponding storage locations -- makes for easy test case
00959     // generation. again, a compiler wouldn't do things in quite
00960     // this way
00961     for (i = 0; i < registersize; i++) {
00962         bInP[i] = new RegisterRef<int32_t>(
00963             RegisterReference::EInput,
00964             i,
00965             STANDARD_TYPE_INT_32);
00966         c.appendRegRef(bInP[i]);
00967         bOutP[i] = new RegisterRef<int32_t>(
00968             RegisterReference::EOutput,
00969             i,
00970             STANDARD_TYPE_INT_32);
00971         c.appendRegRef(bOutP[i]);
00972         bLoP[i] = new RegisterRef<int32_t>(
00973             RegisterReference::ELocal,
00974             i,
00975             STANDARD_TYPE_INT_32);
00976         c.appendRegRef(bLoP[i]);
00977         bLiP[i] = new RegisterRef<int32_t>(
00978             RegisterReference::ELiteral,
00979             i,
00980             STANDARD_TYPE_INT_32);
00981         c.appendRegRef(bLiP[i]);
00982         bOutBoolP[i] = new RegisterRef<bool>(
00983             RegisterReference::EOutput,
00984             i + registersize,
00985             STANDARD_TYPE_BOOL);
00986         c.appendRegRef(bOutBoolP[i]);
00987         bLiteralBoolP[i] = new RegisterRef<bool>(
00988             RegisterReference::ELiteral,
00989             i + registersize,
00990             STANDARD_TYPE_BOOL);
00991 
00992         c.appendRegRef(bLiteralBoolP[i]);
00993     }
00994 
00995     // Set up storage for instructions
00996     // a real compiler would probably cons up instructions and insert them
00997     // directly into the calculator. keep an array of the instructions at
00998     // this level to allow printing of the program after execution, and other
00999     // debugging
01000     Instruction **instP;
01001     instP = new InstructionPtr[200];
01002     int pc = 0, outC = 0, outBoolC = 0;
01003 
01004     StandardTypeDescriptorOrdinal isLong = STANDARD_TYPE_INT_32;
01005 
01006     // add
01007     instP[pc++] = new NativeAdd<int32_t>(
01008         bOutP[outC++], bLiP[10], bLiP[10], isLong);
01009     instP[pc++] = new NativeAdd<int32_t>(
01010         bOutP[outC++], bLiP[10], bLiP[9], isLong);
01011     instP[pc++] = new NativeAdd<int32_t>(
01012         bOutP[outC++], bLiP[nullidx], bLiP[9], isLong);
01013     instP[pc++] = new NativeAdd<int32_t>(
01014         bOutP[outC++], bLiP[10], bLiP[nullidx], isLong);
01015     instP[pc++] = new NativeAdd<int32_t>(
01016         bOutP[outC++], bLiP[nullidx], bLiP[nullidx], isLong);
01017 
01018     // sub
01019     instP[pc++] = new NativeSub<int32_t>(
01020         bOutP[outC++], bLiP[10], bLiP[9], isLong);
01021     instP[pc++] = new NativeSub<int32_t>(
01022         bOutP[outC++], bLiP[10], bLiP[10], isLong);
01023     instP[pc++] = new NativeSub<int32_t>(
01024         bOutP[outC++], bLiP[nullidx], bLiP[10], isLong);
01025     instP[pc++] = new NativeSub<int32_t>(
01026         bOutP[outC++], bLiP[10], bLiP[nullidx], isLong);
01027     instP[pc++] = new NativeSub<int32_t>(
01028         bOutP[outC++], bLiP[nullidx], bLiP[nullidx], isLong);
01029 
01030     // mul
01031     instP[pc++] = new NativeMul<int32_t>(
01032         bOutP[outC++], bLiP[4], bLiP[6], isLong);
01033     instP[pc++] = new NativeMul<int32_t>(
01034         bOutP[outC++], bLiP[4], bLiP[5], isLong);
01035 
01036     instP[pc++] = new NativeMul<int32_t>(
01037         bOutP[outC++], bLiP[nullidx], bLiP[5], isLong);
01038     instP[pc++] = new NativeMul<int32_t>(
01039         bOutP[outC++], bLiP[4], bLiP[nullidx], isLong);
01040     instP[pc++] = new NativeMul<int32_t>(
01041         bOutP[outC++], bLiP[nullidx], bLiP[nullidx], isLong);
01042 
01043     // div
01044     instP[pc++] = new NativeDiv<int32_t>(
01045         bOutP[outC++], bLiP[12], bLiP[4], isLong);
01046     instP[pc++] = new NativeDiv<int32_t>(
01047         bOutP[outC++], bLiP[12], bLiP[3], isLong);
01048     instP[pc++] = new NativeDiv<int32_t>(
01049         bOutP[outC++], bLiP[12], bLiP[nullidx], isLong);
01050     instP[pc++] = new NativeDiv<int32_t>(
01051         bOutP[outC++], bLiP[nullidx], bLiP[3], isLong);
01052     instP[pc++] = new NativeDiv<int32_t>(
01053         bOutP[outC++], bLiP[nullidx], bLiP[nullidx], isLong);
01054     // div by zero
01055     int divbyzero = pc;
01056     instP[pc++] = new NativeDiv<int32_t>(
01057         bOutP[outC++], bLiP[4], bLiP[0], isLong);
01058 
01059     // neg
01060     instP[pc++] = new NativeNeg<int32_t>(
01061         bOutP[outC++], bLiP[3], isLong);
01062     instP[pc++] = new NativeNeg<int32_t>(
01063         bOutP[outC++], bLiP[6], isLong);
01064     instP[pc++] = new NativeNeg<int32_t>(
01065         bOutP[outC++], bLiP[nullidx], isLong);
01066 
01067     // move
01068     instP[pc++] = new NativeMove<int32_t>(
01069         bOutP[outC++], bLiP[3], isLong);
01070     instP[pc++] = new NativeMove<int32_t>(
01071         bOutP[outC++], bLiP[6], isLong);
01072     instP[pc++] = new NativeMove<int32_t>(
01073         bOutP[outC++], bLiP[nullidx], isLong);
01074 
01075     // mod
01076     instP[pc++] = new IntegralNativeMod<int32_t>(
01077         bOutP[outC++], bLiP[20], bLiP[4], isLong);
01078     instP[pc++] = new IntegralNativeMod<int32_t>(
01079         bOutP[outC++], bLiP[20], bLiP[6], isLong);
01080     instP[pc++] = new IntegralNativeMod<int32_t>(
01081         bOutP[outC++], bLiP[20], bLiP[5], isLong);
01082     instP[pc++] = new IntegralNativeMod<int32_t>(
01083         bOutP[outC++], bLiP[20], bLiP[7], isLong);
01084     instP[pc++] = new IntegralNativeMod<int32_t>(
01085         bOutP[outC++], bLiP[19], bLiP[7], isLong);
01086     instP[pc++] = new IntegralNativeMod<int32_t>(
01087         bOutP[outC++], bLiP[19], bLiP[4], isLong);
01088 
01089     instP[pc++] = new IntegralNativeMod<int32_t>(
01090         bOutP[outC++], bLiP[12], bLiP[nullidx], isLong);
01091     instP[pc++] = new IntegralNativeMod<int32_t>(
01092         bOutP[outC++], bLiP[nullidx], bLiP[3], isLong);
01093     instP[pc++] = new IntegralNativeMod<int32_t>(
01094         bOutP[outC++], bLiP[nullidx], bLiP[nullidx], isLong);
01095 
01096     // mod by zero
01097     int modbyzero = pc;
01098     instP[pc++] = new IntegralNativeMod<int32_t>(
01099         bOutP[outC++], bLiP[3], bLiP[0], isLong);
01100 
01101     // bitwise and
01102     instP[pc++] = new IntegralNativeAnd<int32_t>(
01103         bOutP[outC++], bLiP[4], bLiP[4], isLong);
01104     instP[pc++] = new IntegralNativeAnd<int32_t>(
01105         bOutP[outC++], bLiP[30], bLiP[4], isLong);
01106     instP[pc++] = new IntegralNativeAnd<int32_t>(
01107         bOutP[outC++], bLiP[30], bLiP[6], isLong);
01108     instP[pc++] = new IntegralNativeAnd<int32_t>(
01109         bOutP[outC++], bLiP[30], bLiP[32], isLong);
01110 
01111     instP[pc++] = new IntegralNativeAnd<int32_t>(
01112         bOutP[outC++], bLiP[12], bLiP[nullidx], isLong);
01113     instP[pc++] = new IntegralNativeAnd<int32_t>(
01114         bOutP[outC++], bLiP[nullidx], bLiP[3], isLong);
01115     instP[pc++] = new IntegralNativeAnd<int32_t>(
01116         bOutP[outC++], bLiP[nullidx], bLiP[nullidx], isLong);
01117 
01118     // bitwise or
01119     instP[pc++] = new IntegralNativeOr<int32_t>(
01120         bOutP[outC++], bLiP[4], bLiP[4], isLong);
01121     instP[pc++] = new IntegralNativeOr<int32_t>(
01122         bOutP[outC++], bLiP[30], bLiP[64], isLong);
01123     instP[pc++] = new IntegralNativeOr<int32_t>(
01124         bOutP[outC++], bLiP[30], bLiP[0], isLong);
01125     instP[pc++] = new IntegralNativeOr<int32_t>(
01126         bOutP[outC++], bLiP[0], bLiP[0], isLong);
01127 
01128     instP[pc++] = new IntegralNativeOr<int32_t>(
01129         bOutP[outC++], bLiP[12], bLiP[nullidx], isLong);
01130     instP[pc++] = new IntegralNativeOr<int32_t>(
01131         bOutP[outC++], bLiP[nullidx], bLiP[3], isLong);
01132     instP[pc++] = new IntegralNativeOr<int32_t>(
01133         bOutP[outC++], bLiP[nullidx], bLiP[nullidx], isLong);
01134 
01135     // bitwise shift left
01136     instP[pc++] = new IntegralNativeShiftLeft<int32_t>(
01137         bOutP[outC++], bLiP[4], bLiP[2], isLong);
01138     instP[pc++] = new IntegralNativeShiftLeft<int32_t>(
01139         bOutP[outC++], bLiP[4], bLiP[0], isLong);
01140 
01141     instP[pc++] = new IntegralNativeShiftLeft<int32_t>(
01142         bOutP[outC++], bLiP[12], bLiP[nullidx], isLong);
01143     instP[pc++] = new IntegralNativeShiftLeft<int32_t>(
01144         bOutP[outC++], bLiP[nullidx], bLiP[3], isLong);
01145     instP[pc++] = new IntegralNativeShiftLeft<int32_t>(
01146         bOutP[outC++], bLiP[nullidx], bLiP[nullidx], isLong);
01147 
01148     // bitwise shift right
01149     instP[pc++] = new IntegralNativeShiftRight<int32_t>(
01150         bOutP[outC++], bLiP[4], bLiP[2], isLong);
01151     instP[pc++] = new IntegralNativeShiftRight<int32_t>(
01152         bOutP[outC++], bLiP[4], bLiP[0], isLong);
01153 
01154     instP[pc++] = new IntegralNativeShiftRight<int32_t>(
01155         bOutP[outC++], bLiP[12], bLiP[nullidx], isLong);
01156     instP[pc++] = new IntegralNativeShiftRight<int32_t>(
01157         bOutP[outC++], bLiP[nullidx], bLiP[3], isLong);
01158     instP[pc++] = new IntegralNativeShiftRight<int32_t>(
01159         bOutP[outC++], bLiP[nullidx], bLiP[nullidx], isLong);
01160 
01161     // equal
01162     instP[pc++] = new BoolNativeEqual<int32_t>(
01163         bOutBoolP[outBoolC++], bLiP[0], bLiP[0], isLong);
01164     instP[pc++] = new BoolNativeEqual<int32_t>(
01165         bOutBoolP[outBoolC++], bLiP[4], bLiP[4], isLong);
01166     instP[pc++] = new BoolNativeEqual<int32_t>(
01167         bOutBoolP[outBoolC++], bLiP[9], bLiP[9], isLong);
01168     instP[pc++] = new BoolNativeEqual<int32_t>(
01169         bOutBoolP[outBoolC++], bLiP[3], bLiP[5], isLong);
01170     instP[pc++] = new BoolNativeEqual<int32_t>(
01171         bOutBoolP[outBoolC++], bLiP[5], bLiP[3], isLong);
01172     instP[pc++] = new BoolNativeEqual<int32_t>(
01173         bOutBoolP[outBoolC++], bLiP[6], bLiP[2], isLong);
01174     instP[pc++] = new BoolNativeEqual<int32_t>(
01175         bOutBoolP[outBoolC++], bLiP[2], bLiP[6], isLong);
01176 
01177     instP[pc++] = new BoolNativeEqual<int32_t>(
01178         bOutBoolP[outBoolC++], bLiP[12], bLiP[nullidx], isLong);
01179     instP[pc++] = new BoolNativeEqual<int32_t>(
01180         bOutBoolP[outBoolC++], bLiP[nullidx], bLiP[3], isLong);
01181     instP[pc++] = new BoolNativeEqual<int32_t>(
01182         bOutBoolP[outBoolC++], bLiP[nullidx], bLiP[nullidx], isLong);
01183 
01184     // notequal
01185     instP[pc++] = new BoolNativeNotEqual<int32_t>(
01186         bOutBoolP[outBoolC++], bLiP[0], bLiP[0], isLong);
01187     instP[pc++] = new BoolNativeNotEqual<int32_t>(
01188         bOutBoolP[outBoolC++], bLiP[4], bLiP[4], isLong);
01189     instP[pc++] = new BoolNativeNotEqual<int32_t>(
01190         bOutBoolP[outBoolC++], bLiP[9], bLiP[9], isLong);
01191     instP[pc++] = new BoolNativeNotEqual<int32_t>(
01192         bOutBoolP[outBoolC++], bLiP[3], bLiP[5], isLong);
01193     instP[pc++] = new BoolNativeNotEqual<int32_t>(
01194         bOutBoolP[outBoolC++], bLiP[5], bLiP[3], isLong);
01195     instP[pc++] = new BoolNativeNotEqual<int32_t>(
01196         bOutBoolP[outBoolC++], bLiP[6], bLiP[2], isLong);
01197     instP[pc++] = new BoolNativeNotEqual<int32_t>(
01198         bOutBoolP[outBoolC++], bLiP[2], bLiP[6], isLong);
01199 
01200     instP[pc++] = new BoolNativeNotEqual<int32_t>(
01201         bOutBoolP[outBoolC++], bLiP[12], bLiP[nullidx], isLong);
01202     instP[pc++] = new BoolNativeNotEqual<int32_t>(
01203         bOutBoolP[outBoolC++], bLiP[nullidx], bLiP[3], isLong);
01204     instP[pc++] = new BoolNativeNotEqual<int32_t>(
01205         bOutBoolP[outBoolC++], bLiP[nullidx], bLiP[nullidx], isLong);
01206 
01207     // greater
01208     instP[pc++] = new BoolNativeGreater<int32_t>(
01209         bOutBoolP[outBoolC++], bLiP[0], bLiP[0], isLong);
01210     instP[pc++] = new BoolNativeGreater<int32_t>(
01211         bOutBoolP[outBoolC++], bLiP[4], bLiP[4], isLong);
01212     instP[pc++] = new BoolNativeGreater<int32_t>(
01213         bOutBoolP[outBoolC++], bLiP[9], bLiP[9], isLong);
01214     instP[pc++] = new BoolNativeGreater<int32_t>(
01215         bOutBoolP[outBoolC++], bLiP[3], bLiP[5], isLong);
01216     instP[pc++] = new BoolNativeGreater<int32_t>(
01217         bOutBoolP[outBoolC++], bLiP[5], bLiP[3], isLong);
01218     instP[pc++] = new BoolNativeGreater<int32_t>(
01219         bOutBoolP[outBoolC++], bLiP[6], bLiP[2], isLong);
01220     instP[pc++] = new BoolNativeGreater<int32_t>(
01221         bOutBoolP[outBoolC++], bLiP[2], bLiP[6], isLong);
01222 
01223     instP[pc++] = new BoolNativeGreater<int32_t>(
01224         bOutBoolP[outBoolC++], bLiP[12], bLiP[nullidx], isLong);
01225     instP[pc++] = new BoolNativeGreater<int32_t>(
01226         bOutBoolP[outBoolC++], bLiP[nullidx], bLiP[3], isLong);
01227     instP[pc++] = new BoolNativeGreater<int32_t>(
01228         bOutBoolP[outBoolC++], bLiP[nullidx], bLiP[nullidx], isLong);
01229 
01230     // greaterequal
01231     instP[pc++] = new BoolNativeGreaterEqual<int32_t>(
01232         bOutBoolP[outBoolC++], bLiP[0], bLiP[0], isLong);
01233     instP[pc++] = new BoolNativeGreaterEqual<int32_t>(
01234         bOutBoolP[outBoolC++], bLiP[4], bLiP[4], isLong);
01235     instP[pc++] = new BoolNativeGreaterEqual<int32_t>(
01236         bOutBoolP[outBoolC++], bLiP[9], bLiP[9], isLong);
01237     instP[pc++] = new BoolNativeGreaterEqual<int32_t>(
01238         bOutBoolP[outBoolC++], bLiP[3], bLiP[5], isLong);
01239     instP[pc++] = new BoolNativeGreaterEqual<int32_t>(
01240         bOutBoolP[outBoolC++], bLiP[5], bLiP[3], isLong);
01241     instP[pc++] = new BoolNativeGreaterEqual<int32_t>(
01242         bOutBoolP[outBoolC++], bLiP[6], bLiP[2], isLong);
01243     instP[pc++] = new BoolNativeGreaterEqual<int32_t>(
01244         bOutBoolP[outBoolC++], bLiP[2], bLiP[6], isLong);
01245 
01246     instP[pc++] = new BoolNativeGreaterEqual<int32_t>(
01247         bOutBoolP[outBoolC++], bLiP[12], bLiP[nullidx], isLong);
01248     instP[pc++] = new BoolNativeGreaterEqual<int32_t>(
01249         bOutBoolP[outBoolC++], bLiP[nullidx], bLiP[3], isLong);
01250     instP[pc++] = new BoolNativeGreaterEqual<int32_t>(
01251         bOutBoolP[outBoolC++], bLiP[nullidx], bLiP[nullidx], isLong);
01252 
01253     // less
01254     instP[pc++] = new BoolNativeLess<int32_t>(
01255         bOutBoolP[outBoolC++], bLiP[0], bLiP[0], isLong);
01256     instP[pc++] = new BoolNativeLess<int32_t>(
01257         bOutBoolP[outBoolC++], bLiP[4], bLiP[4], isLong);
01258     instP[pc++] = new BoolNativeLess<int32_t>(
01259         bOutBoolP[outBoolC++], bLiP[9], bLiP[9], isLong);
01260     instP[pc++] = new BoolNativeLess<int32_t>(
01261         bOutBoolP[outBoolC++], bLiP[3], bLiP[5], isLong);
01262     instP[pc++] = new BoolNativeLess<int32_t>(
01263         bOutBoolP[outBoolC++], bLiP[5], bLiP[3], isLong);
01264     instP[pc++] = new BoolNativeLess<int32_t>(
01265         bOutBoolP[outBoolC++], bLiP[6], bLiP[2], isLong);
01266     instP[pc++] = new BoolNativeLess<int32_t>(
01267         bOutBoolP[outBoolC++], bLiP[2], bLiP[6], isLong);
01268 
01269     instP[pc++] = new BoolNativeLess<int32_t>(
01270         bOutBoolP[outBoolC++], bLiP[12], bLiP[nullidx], isLong);
01271     instP[pc++] = new BoolNativeLess<int32_t>(
01272         bOutBoolP[outBoolC++], bLiP[nullidx], bLiP[3], isLong);
01273     instP[pc++] = new BoolNativeLess<int32_t>(
01274         bOutBoolP[outBoolC++], bLiP[nullidx], bLiP[nullidx], isLong);
01275 
01276     // lessequal
01277     instP[pc++] = new BoolNativeLessEqual<int32_t>(
01278         bOutBoolP[outBoolC++], bLiP[0], bLiP[0], isLong);
01279     instP[pc++] = new BoolNativeLessEqual<int32_t>(
01280         bOutBoolP[outBoolC++], bLiP[4], bLiP[4], isLong);
01281     instP[pc++] = new BoolNativeLessEqual<int32_t>(
01282         bOutBoolP[outBoolC++], bLiP[9], bLiP[9], isLong);
01283     instP[pc++] = new BoolNativeLessEqual<int32_t>(
01284         bOutBoolP[outBoolC++], bLiP[3], bLiP[5], isLong);
01285     instP[pc++] = new BoolNativeLessEqual<int32_t>(
01286         bOutBoolP[outBoolC++], bLiP[5], bLiP[3], isLong);
01287     instP[pc++] = new BoolNativeLessEqual<int32_t>(
01288         bOutBoolP[outBoolC++], bLiP[6], bLiP[2], isLong);
01289     instP[pc++] = new BoolNativeLessEqual<int32_t>(
01290         bOutBoolP[outBoolC++], bLiP[2], bLiP[6], isLong);
01291 
01292     instP[pc++] = new BoolNativeLessEqual<int32_t>(
01293         bOutBoolP[outBoolC++], bLiP[12], bLiP[nullidx], isLong);
01294     instP[pc++] = new BoolNativeLessEqual<int32_t>(
01295         bOutBoolP[outBoolC++], bLiP[nullidx], bLiP[3], isLong);
01296     instP[pc++] = new BoolNativeLessEqual<int32_t>(
01297         bOutBoolP[outBoolC++], bLiP[nullidx], bLiP[nullidx], isLong);
01298 
01299     // isnull
01300     instP[pc++] = new BoolNativeIsNull<int32_t>(
01301         bOutBoolP[outBoolC++], bLiP[12], isLong);
01302     instP[pc++] = new BoolNativeIsNull<int32_t>(
01303         bOutBoolP[outBoolC++], bLiP[nullidx], isLong);
01304     // isnotnull
01305     instP[pc++] = new BoolNativeIsNotNull<int32_t>(
01306         bOutBoolP[outBoolC++], bLiP[12], isLong);
01307     instP[pc++] = new BoolNativeIsNotNull<int32_t>(
01308         bOutBoolP[outBoolC++], bLiP[nullidx], isLong);
01309     // tonull
01310     instP[pc++] = new NativeToNull<int32_t>(
01311         bOutP[outC++], isLong);
01312 
01313     // jump
01314     instP[pc++] = new NativeMove<int32_t>(
01315         bOutP[outC], bLiP[22], isLong);
01316     instP[pc] = new Jump(pc + 2);
01317     pc++;
01318     instP[pc++] = new NativeMove<int32_t>(
01319         bOutP[outC++], bLiP[12], isLong);  // bad flag
01320 
01321     // jumptrue
01322     instP[pc++] = new NativeMove<int32_t>(
01323         bOutP[outC], bLiP[24], isLong);  // jump here good flag
01324     instP[pc] = new JumpTrue(pc + 2, bLiteralBoolP[trueIdx]);
01325     pc++;        // jump over bad flag
01326     instP[pc++] = new NativeMove<int32_t>(
01327         bOutP[outC++], bLiP[14], isLong); // bad flag
01328     instP[pc] = new JumpTrue(pc + 3, bLiteralBoolP[falseIdx]);
01329     pc++;                       // won't jump to bad flag
01330     instP[pc++] = new NativeMove<int32_t>(
01331         bOutP[outC], bLiP[26], isLong);  // good flag
01332     instP[pc] = new Jump(pc + 2); pc++;  // jump over bad flag
01333     instP[pc++] = new NativeMove<int32_t>(
01334         bOutP[outC++], bLiP[18], isLong); // bad flag
01335     instP[pc++] = new NativeMove<int32_t>(
01336         bOutP[outC++], bLiP[28], isLong); // good flag
01337 
01338     // jumpfalse
01339     instP[pc++] = new NativeMove<int32_t>(
01340         bOutP[outC], bLiP[34], isLong);  // good flag
01341     instP[pc] = new JumpFalse(pc + 2, bLiteralBoolP[falseIdx]);
01342     pc++;                       // jump over bad flag
01343     instP[pc++] = new NativeMove<int32_t>(
01344         bOutP[outC++], bLiP[14], isLong); // bad flag
01345     instP[pc] = new JumpFalse(pc + 3, bLiteralBoolP[trueIdx]);
01346     pc++;                       // won't jump to bad flag
01347     instP[pc++] = new NativeMove<int32_t>(
01348         bOutP[outC], bLiP[36], isLong);  // good flag
01349     instP[pc] = new Jump(pc + 2);
01350     pc++;                       // jump over bad flag
01351     instP[pc++] = new NativeMove<int32_t>(
01352         bOutP[outC++], bLiP[18], isLong); // bad flag
01353     instP[pc++] = new NativeMove<int32_t>(
01354         bOutP[outC++], bLiP[38], isLong); // good flag
01355 
01356     // jumpnull
01357     instP[pc++] = new NativeMove<int32_t>(
01358         bOutP[outC], bLiP[44], isLong);  // good flag
01359     instP[pc] = new JumpNull(pc + 2, bLiteralBoolP[nullidx]);
01360     pc++;                       // jump over bad flag
01361     instP[pc++] = new NativeMove<int32_t>(
01362         bOutP[outC++], bLiP[14], isLong); // bad flag
01363     instP[pc] = new JumpNull(pc + 3, bLiteralBoolP[trueIdx]);
01364     pc++;                       // won't jump to bad flag
01365     instP[pc++] = new NativeMove<int32_t>(
01366         bOutP[outC], bLiP[46], isLong); // good flag
01367     instP[pc] = new Jump(pc + 2);
01368     pc++;                       // jump over bad flag
01369     instP[pc++] = new NativeMove<int32_t>(
01370         bOutP[outC++], bLiP[18], isLong); // bad flag
01371     instP[pc++] = new NativeMove<int32_t>(
01372         bOutP[outC++], bLiP[48], isLong); // good flag
01373 
01374     // jumpnotnull
01375     instP[pc++] = new NativeMove<int32_t>(
01376         bOutP[outC], bLiP[64], isLong); // good flag
01377     instP[pc] = new JumpNotNull(pc + 2, bLiteralBoolP[trueIdx]);
01378     pc++;                       // jump over bad flag
01379     instP[pc++] = new NativeMove<int32_t>(
01380         bOutP[outC++], bLiP[14], isLong); // bad flag
01381     instP[pc] = new JumpNotNull(pc + 3, bLiteralBoolP[nullidx]);
01382     pc++;                       // won't jump to bad flag
01383     instP[pc++] = new NativeMove<int32_t>(
01384         bOutP[outC], bLiP[66], isLong); // good flag
01385     instP[pc] = new Jump(pc + 2);
01386     pc++;                       // jump over bad flag
01387     instP[pc++] = new NativeMove<int32_t>(
01388         bOutP[outC++], bLiP[18], isLong); // bad flag
01389     instP[pc++] = new NativeMove<int32_t>(
01390         bOutP[outC++], bLiP[68], isLong); // good flag
01391 
01392     // return
01393     instP[pc++] = new NativeMove<int32_t>(
01394         bOutP[outC], bLiP[70], isLong); // good flag
01395     instP[pc++] = new ReturnInstruction();
01396     instP[pc++] = new NativeMove<int32_t>(
01397         bOutP[outC++], bLiP[15], isLong); // bad flag
01398     int lastPC = pc;
01399 
01400     for (i = 0; i < pc; i++) {
01401         c.appendInstruction(instP[i]);
01402     }
01403 
01404     c.bind(
01405         RegisterReference::ELiteral,
01406         &literal,
01407         tupleDesc);
01408     c.bind(
01409         RegisterReference::EInput,
01410         &input,
01411         tupleDesc);
01412     c.bind(
01413         RegisterReference::EOutput,
01414         &output,
01415         tupleDesc);
01416     c.bind(
01417         RegisterReference::ELocal,
01418         &local,
01419         tupleDesc);
01420     c.bind(
01421         RegisterReference::EStatus,
01422         &status,
01423         tupleDesc);
01424     c.exec();
01425 
01426     string out;
01427     for (i = 0; i < pc; i++) {
01428         instP[i]->describe(out, true);
01429         printf("[%2d] %s\n", i, out.c_str());
01430     }
01431 
01432     // Print out the output tuple
01433     printf("Output Tuple\n");
01434     tuplePrinter.print(cout, tupleDesc, output);
01435     cout << endl;
01436 
01437     outC = 0;
01438     outBoolC = registersize;
01439     // TODO tests to add: Maxint, minint, zeros, negatives, overflow,
01440     // underflow, etc
01441 
01442     // add
01443     if (*(reinterpret_cast<const int32_t *>(output[outC++].pData)) != 20) {
01444         fail("longadd1", __LINE__);
01445     }
01446     if (*(reinterpret_cast<const int32_t *>(output[outC++].pData)) != 1) {
01447         fail("longadd2", __LINE__);
01448     }
01449     if (output[outC++].pData != NULL) {
01450         fail("longadd3", __LINE__);
01451     }
01452     if (output[outC++].pData != NULL) {
01453         fail("longadd4", __LINE__);
01454     }
01455     if (output[outC++].pData != NULL) {
01456         fail("longadd5", __LINE__);
01457     }
01458 
01459     // sub
01460     if (*(reinterpret_cast<const int32_t *>(output[outC++].pData)) != 19) {
01461         fail("longsub1", __LINE__);
01462     }
01463     if (*(reinterpret_cast<const int32_t *>(output[outC++].pData)) != 0) {
01464         fail("longsub2", __LINE__);
01465     }
01466     if (output[outC++].pData != NULL) {
01467         fail("longsub3", __LINE__);
01468     }
01469     if (output[outC++].pData != NULL) {
01470         fail("longsub4", __LINE__);
01471     }
01472     if (output[outC++].pData != NULL) {
01473         fail("longsub5", __LINE__);
01474     }
01475 
01476     // mul
01477     if (*(reinterpret_cast<const int32_t *>(output[outC++].pData)) != 24) {
01478         fail("longmul1", __LINE__);
01479     }
01480     if (*(reinterpret_cast<const int32_t *>(output[outC++].pData)) != -20) {
01481         fail("longmul2", __LINE__);
01482     }
01483     if (output[outC++].pData != NULL) {
01484         fail("longmul3", __LINE__);
01485     }
01486     if (output[outC++].pData != NULL) {
01487         fail("longmul4", __LINE__);
01488     }
01489     if (output[outC++].pData != NULL) {
01490         fail("longmul5", __LINE__);
01491     }
01492 
01493     // div
01494     if (*(reinterpret_cast<const int32_t *>(output[outC++].pData)) != 3) {
01495         fail("longdiv1", __LINE__);
01496     }
01497     if (*(reinterpret_cast<const int32_t *>(output[outC++].pData)) != -4) {
01498         fail("longdiv2", __LINE__);
01499     }
01500     if (output[outC++].pData != NULL) {
01501         fail("longdiv3", __LINE__);
01502     }
01503     if (output[outC++].pData != NULL) {
01504         fail("longdiv4", __LINE__);
01505     }
01506     if (output[outC++].pData != NULL) {
01507         fail("longdiv5", __LINE__);
01508     }
01509     // div by zero
01510     assert(outC == divbyzero);
01511     if (output[outC++].pData != NULL) {
01512         fail("longdiv6", __LINE__);
01513     }
01514     deque<CalcMessage>::iterator iter = c.mWarnings.begin();
01515     if (iter->pc != divbyzero) {
01516         fail("longdiv by zero failed, pc wrong\n", __LINE__);
01517     }
01518     string expectederror("22012");
01519     if (expectederror.compare(iter->str)) {
01520         fail("longdiv by zero failed string was wrong", __LINE__);
01521     }
01522 
01523     // neg
01524     if (*(reinterpret_cast<const int32_t *>(output[outC++].pData)) != 3) {
01525         fail("longneg1", __LINE__);
01526     }
01527     if (*(reinterpret_cast<const int32_t *>(output[outC++].pData)) != -6) {
01528         fail("longneg2", __LINE__);
01529     }
01530     if (output[outC++].pData != NULL) {
01531         fail("longneg3", __LINE__);
01532     }
01533 
01534     // move
01535     if (*(reinterpret_cast<const int32_t *>(output[outC++].pData)) != -3) {
01536         fail("longmove1", __LINE__);
01537     }
01538     if (*(reinterpret_cast<const int32_t *>(output[outC++].pData)) != 6) {
01539         fail("longmove2", __LINE__);
01540     }
01541     if (output[outC++].pData != NULL) {
01542         fail("longmove3", __LINE__);
01543     }
01544 
01545 
01546     // mod
01547     if (*(reinterpret_cast<const int32_t *>(output[outC++].pData)) != 0) {
01548         fail("longmod1", __LINE__);
01549     }
01550     if (*(reinterpret_cast<const int32_t *>(output[outC++].pData)) != 2) {
01551         fail("longmod2", __LINE__);
01552     }
01553     if (*(reinterpret_cast<const int32_t *>(output[outC++].pData)) != 0) {
01554         fail("longmod3", __LINE__);
01555     }
01556     if (*(reinterpret_cast<const int32_t *>(output[outC++].pData)) != 6) {
01557         fail("longmod4", __LINE__);
01558     }
01559     if (*(reinterpret_cast<const int32_t *>(output[outC++].pData)) != -5) {
01560         fail("longmod5", __LINE__);
01561     }
01562     if (*(reinterpret_cast<const int32_t *>(output[outC++].pData)) != -3) {
01563         fail("longmod6", __LINE__);
01564     }
01565 
01566     if (output[outC++].pData != NULL) {
01567         fail("longmod7", __LINE__);
01568     }
01569     if (output[outC++].pData != NULL) {
01570         fail("longmod8", __LINE__);
01571     }
01572     if (output[outC++].pData != NULL) {
01573         fail("longmod9", __LINE__);
01574     }
01575 
01576     // mod by zero
01577     assert(outC == modbyzero);
01578     if (output[outC++].pData != NULL) {
01579         fail("longmod10", __LINE__);
01580     }
01581     iter++;
01582     if (iter->pc != modbyzero) {
01583         fail("longmod by zero failed, pc wrong\n", __LINE__);
01584     }
01585     expectederror = "22012";
01586     if (expectederror.compare(iter->str)) {
01587         fail("longmod by zero failed string was wrong", __LINE__);
01588     }
01589 
01590     // bitwise and
01591     if (*(reinterpret_cast<const int32_t *>(output[outC++].pData)) != 4) {
01592         fail("longbitand1", __LINE__);
01593     }
01594     if (*(reinterpret_cast<const int32_t *>(output[outC++].pData)) != 4) {
01595         fail("longbitand2", __LINE__);
01596     }
01597     if (*(reinterpret_cast<const int32_t *>(output[outC++].pData)) != 6) {
01598         fail("longbitand3", __LINE__);
01599     }
01600     if (*(reinterpret_cast<const int32_t *>(output[outC++].pData)) != 0) {
01601         fail("longbitand4", __LINE__);
01602     }
01603 
01604     if (output[outC++].pData != NULL) {
01605         fail("longbitand5", __LINE__);
01606     }
01607     if (output[outC++].pData != NULL) {
01608         fail("longbitand6", __LINE__);
01609     }
01610     if (output[outC++].pData != NULL) {
01611         fail("longbitand7", __LINE__);
01612     }
01613 
01614     // bitwise or
01615     if (*(reinterpret_cast<const int32_t *>(output[outC++].pData)) != 4) {
01616         fail("longbitor1", __LINE__);
01617     }
01618     if (*(reinterpret_cast<const int32_t *>(output[outC++].pData)) != 94) {
01619         fail("longbitor2", __LINE__);
01620     }
01621     if (*(reinterpret_cast<const int32_t *>(output[outC++].pData)) != 30) {
01622         fail("longbitor3", __LINE__);
01623     }
01624     if (*(reinterpret_cast<const int32_t *>(output[outC++].pData)) != 0) {
01625         fail("longbitor4", __LINE__);
01626     }
01627 
01628     if (output[outC++].pData != NULL) {
01629         fail("longbitor5", __LINE__);
01630     }
01631     if (output[outC++].pData != NULL) {
01632         fail("longbitor6", __LINE__);
01633     }
01634     if (output[outC++].pData != NULL) {
01635         fail("longbitor7", __LINE__);
01636     }
01637 
01638     // bitwise shift left
01639     if (*(reinterpret_cast<const int32_t *>(output[outC++].pData)) != 16) {
01640         fail("longbitshiftleft1", __LINE__);
01641     }
01642     if (*(reinterpret_cast<const int32_t *>(output[outC++].pData)) != 4) {
01643         fail("longbitshiftleft2", __LINE__);
01644     }
01645 
01646     if (output[outC++].pData != NULL) {
01647         fail("longbitshiftleft5", __LINE__);
01648     }
01649     if (output[outC++].pData != NULL) {
01650         fail("longbitshiftleft6", __LINE__);
01651     }
01652     if (output[outC++].pData != NULL) {
01653         fail("longbitshiftleft7", __LINE__);
01654     }
01655 
01656     // bitwise shift right
01657     if (*(reinterpret_cast<const int32_t *>(output[outC++].pData)) != 1) {
01658         fail("longbitshiftright1", __LINE__);
01659     }
01660     if (*(reinterpret_cast<const int32_t *>(output[outC++].pData)) != 4) {
01661         fail("longbitshiftright2", __LINE__);
01662     }
01663 
01664     if (output[outC++].pData != NULL) {
01665         fail("longbitshiftright5", __LINE__);
01666     }
01667     if (output[outC++].pData != NULL) {
01668         fail("longbitshiftright6", __LINE__);
01669     }
01670     if (output[outC++].pData != NULL) {
01671         fail("longbitshiftright7", __LINE__);
01672     }
01673 
01674     // equal
01675     if (*(output[outBoolC++].pData) != true) {
01676         fail("longequal1", __LINE__);
01677     }
01678     if (*(output[outBoolC++].pData) != true) {
01679         fail("longequal2", __LINE__);
01680     }
01681     if (*(output[outBoolC++].pData) != true) {
01682         fail("longequal3", __LINE__);
01683     }
01684     if (*(output[outBoolC++].pData) != false) {
01685         fail("longequal4", __LINE__);
01686     }
01687     if (*(output[outBoolC++].pData) != false) {
01688         fail("longequal5", __LINE__);
01689     }
01690     if (*(output[outBoolC++].pData) != false) {
01691         fail("longequal6", __LINE__);
01692     }
01693     if (*(output[outBoolC++].pData) != false) {
01694         fail("longequal7", __LINE__);
01695     }
01696 
01697     if (output[outBoolC++].pData != NULL) {
01698         fail("longequal8", __LINE__);
01699     }
01700     if (output[outBoolC++].pData != NULL) {
01701         fail("longequal9", __LINE__);
01702     }
01703     if (output[outBoolC++].pData != NULL) {
01704         fail("longequal10", __LINE__);
01705     }
01706 
01707     // notequal
01708     if (*(output[outBoolC++].pData) != false) {
01709         fail("longnotequal1", __LINE__);
01710     }
01711     if (*(output[outBoolC++].pData) != false) {
01712         fail("longnotequal2", __LINE__);
01713     }
01714     if (*(output[outBoolC++].pData) != false) {
01715         fail("longnotequal3", __LINE__);
01716     }
01717     if (*(output[outBoolC++].pData) != true) {
01718         fail("longnotequal4", __LINE__);
01719     }
01720     if (*(output[outBoolC++].pData) != true) {
01721         fail("longnotequal5", __LINE__);
01722     }
01723     if (*(output[outBoolC++].pData) != true) {
01724         fail("longnotequal6", __LINE__);
01725     }
01726     if (*(output[outBoolC++].pData) != true) {
01727         fail("longnotequal7", __LINE__);
01728     }
01729 
01730     if (output[outBoolC++].pData != NULL) {
01731         fail("longnotequal8", __LINE__);
01732     }
01733     if (output[outBoolC++].pData != NULL) {
01734         fail("longnotequal9", __LINE__);
01735     }
01736     if (output[outBoolC++].pData != NULL) {
01737         fail("longnotequal10", __LINE__);
01738     }
01739 
01740     // greater
01741     if (*(output[outBoolC++].pData) != false) {
01742         fail("longgreater1", __LINE__);
01743     }
01744     if (*(output[outBoolC++].pData) != false) {
01745         fail("longgreater2", __LINE__);
01746     }
01747     if (*(output[outBoolC++].pData) != false) {
01748         fail("longgreater3", __LINE__);
01749     }
01750     if (*(output[outBoolC++].pData) != true) {
01751         fail("longgreater4", __LINE__);
01752     }
01753     if (*(output[outBoolC++].pData) != false) {
01754         fail("longgreater5", __LINE__);
01755     }
01756     if (*(output[outBoolC++].pData) != true) {
01757         fail("longgreater6", __LINE__);
01758     }
01759     if (*(output[outBoolC++].pData) != false) {
01760         fail("longgreater7", __LINE__);
01761     }
01762 
01763     if (output[outBoolC++].pData != NULL) {
01764         fail("longgreater8", __LINE__);
01765     }
01766     if (output[outBoolC++].pData != NULL) {
01767         fail("longgreater9", __LINE__);
01768     }
01769     if (output[outBoolC++].pData != NULL) {
01770         fail("longgreater10", __LINE__);
01771     }
01772 
01773     // greaterequal
01774     if (*(output[outBoolC++].pData) != true) {
01775         fail("longgreaterequal1", __LINE__);
01776     }
01777     if (*(output[outBoolC++].pData) != true) {
01778         fail("longgreaterequal2", __LINE__);
01779     }
01780     if (*(output[outBoolC++].pData) != true) {
01781         fail("longgreaterequal3", __LINE__);
01782     }
01783     if (*(output[outBoolC++].pData) != true) {
01784         fail("longgreaterequal4", __LINE__);
01785     }
01786     if (*(output[outBoolC++].pData) != false) {
01787         fail("longgreaterequal5", __LINE__);
01788     }
01789     if (*(output[outBoolC++].pData) != true) {
01790         fail("longgreaterequal6", __LINE__);
01791     }
01792     if (*(output[outBoolC++].pData) != false) {
01793         fail("longgreaterequal7", __LINE__);
01794     }
01795 
01796     if (output[outBoolC++].pData != NULL) {
01797         fail("longgreaterequal8", __LINE__);
01798     }
01799     if (output[outBoolC++].pData != NULL) {
01800         fail("longgreaterequal9", __LINE__);
01801     }
01802     if (output[outBoolC++].pData != NULL) {
01803         fail("longgreaterequal10", __LINE__);
01804     }
01805 
01806     // less
01807     if (*(output[outBoolC++].pData) != false) {
01808         fail("longless1", __LINE__);
01809     }
01810     if (*(output[outBoolC++].pData) != false) {
01811         fail("longless2", __LINE__);
01812     }
01813     if (*(output[outBoolC++].pData) != false) {
01814         fail("longless3", __LINE__);
01815     }
01816     if (*(output[outBoolC++].pData) != false) {
01817         fail("longless4", __LINE__);
01818     }
01819     if (*(output[outBoolC++].pData) != true) {
01820         fail("longless5", __LINE__);
01821     }
01822     if (*(output[outBoolC++].pData) != false) {
01823         fail("longless6", __LINE__);
01824     }
01825     if (*(output[outBoolC++].pData) != true) {
01826         fail("longless7", __LINE__);
01827     }
01828 
01829     if (output[outBoolC++].pData != NULL) {
01830         fail("longless8", __LINE__);
01831     }
01832     if (output[outBoolC++].pData != NULL) {
01833         fail("longless9", __LINE__);
01834     }
01835     if (output[outBoolC++].pData != NULL) {
01836         fail("longless10", __LINE__);
01837     }
01838 
01839     // lessequal
01840     if (*(output[outBoolC++].pData) != true) {
01841         fail("longlessequal1", __LINE__);
01842     }
01843     if (*(output[outBoolC++].pData) != true) {
01844         fail("longlessequal2", __LINE__);
01845     }
01846     if (*(output[outBoolC++].pData) != true) {
01847         fail("longlessequal3", __LINE__);
01848     }
01849     if (*(output[outBoolC++].pData) != false) {
01850         fail("longlessequal4", __LINE__);
01851     }
01852     if (*(output[outBoolC++].pData) != true) {
01853         fail("longlessequal5", __LINE__);
01854     }
01855     if (*(output[outBoolC++].pData) != false) {
01856         fail("longlessequal6", __LINE__);
01857     }
01858     if (*(output[outBoolC++].pData) != true) {
01859         fail("longlessequal7", __LINE__);
01860     }
01861 
01862     if (output[outBoolC++].pData != NULL) {
01863         fail("longlessequal8", __LINE__);
01864     }
01865     if (output[outBoolC++].pData != NULL) {
01866         fail("longlessequal9", __LINE__);
01867     }
01868     if (output[outBoolC++].pData != NULL) {
01869         fail("longlessequal10", __LINE__);
01870     }
01871 
01872     // isnull
01873     if (*(output[outBoolC++].pData) != false) {
01874         fail("longisnull1", __LINE__);
01875     }
01876     if (*(output[outBoolC++].pData) != true) {
01877         fail("longisnull2", __LINE__);
01878     }
01879 
01880     // isnotnull
01881     if (*(output[outBoolC++].pData) != true) {
01882         fail("longisnotnull1", __LINE__);
01883     }
01884     if (*(output[outBoolC++].pData) != false) {
01885         fail("longisnotnull2", __LINE__);
01886     }
01887 
01888     // tonull
01889     if (output[outC++].pData != NULL) {
01890         fail("longtonull1", __LINE__);
01891     }
01892 
01893     // jump
01894     if (*(reinterpret_cast<const int32_t *>(output[outC++].pData)) != 22) {
01895         fail("longjump1", __LINE__);
01896     }
01897 
01898     // jumptrue
01899     if (*(reinterpret_cast<const int32_t *>(output[outC++].pData)) != 24) {
01900         fail("longjumptrue1", __LINE__);
01901     }
01902     if (*(reinterpret_cast<const int32_t *>(output[outC++].pData)) != 26) {
01903         fail("longjumptrue2", __LINE__);
01904     }
01905     if (*(reinterpret_cast<const int32_t *>(output[outC++].pData)) != 28) {
01906         fail("longjumptrue3", __LINE__);
01907     }
01908 
01909     // jumpfalse
01910     if (*(reinterpret_cast<const int32_t *>(output[outC++].pData)) != 34) {
01911         fail("longjumpfalse1", __LINE__);
01912     }
01913     if (*(reinterpret_cast<const int32_t *>(output[outC++].pData)) != 36) {
01914         fail("longjumpfalse2", __LINE__);
01915     }
01916     if (*(reinterpret_cast<const int32_t *>(output[outC++].pData)) != 38) {
01917         fail("longjumpfalse3", __LINE__);
01918     }
01919 
01920     // jumpnull
01921     if (*(reinterpret_cast<const int32_t *>(output[outC++].pData)) != 44) {
01922         fail("longjumpnull1", __LINE__);
01923     }
01924     if (*(reinterpret_cast<const int32_t *>(output[outC++].pData)) != 46) {
01925         fail("longjumpnull2", __LINE__);
01926     }
01927     if (*(reinterpret_cast<const int32_t *>(output[outC++].pData)) != 48) {
01928         fail("longjumpnull3", __LINE__);
01929     }
01930 
01931     // jumpnotnull
01932     if (*(reinterpret_cast<const int32_t *>(output[outC++].pData)) != 64) {
01933         fail("longjumpnotnull1", __LINE__);
01934     }
01935     if (*(reinterpret_cast<const int32_t *>(output[outC++].pData)) != 66) {
01936         fail("longjumpnotnull2", __LINE__);
01937     }
01938     if (*(reinterpret_cast<const int32_t *>(output[outC++].pData)) != 68) {
01939         fail("longjumpnotnull3", __LINE__);
01940     }
01941 
01942     // return
01943     if (*(reinterpret_cast<const int32_t *>(output[outC++].pData)) != 70) {
01944         fail("longreturn", __LINE__);
01945     }
01946 
01947     cout << "Calculator Warnings: " << c.warnings() << endl;
01948 
01949     delete [] bInP;
01950     delete [] bOutP;
01951     delete [] bLoP;
01952     delete [] bLiP;
01953     delete [] bOutBoolP;
01954     delete [] bLiteralBoolP;
01955     for (i = 0; i < lastPC; i++) {
01956         delete instP[i];
01957     }
01958     delete [] instP;
01959 }
01960 
01961 
01962 void
01963 unitTestFloat()
01964 {
01965     printf("=========================================================\n");
01966     printf("=========================================================\n");
01967     printf("=====\n");
01968     printf("=====     unitTestFloat()\n");
01969     printf("=====\n");
01970     printf("=========================================================\n");
01971     printf("=========================================================\n");
01972 
01973     bool isNullable = true;    // Can tuple contain nulls?
01974     int i, registersize = 200;
01975 
01976     TupleDescriptor tupleDesc;
01977     tupleDesc.clear();
01978 
01979     // Build up a description of what we'd like the tuple to look like
01980     StandardTypeDescriptorFactory typeFactory;
01981     for (i = 0;i < registersize; i++) {
01982         // float in first "half"
01983         StoredTypeDescriptor const &typeDesc =
01984             typeFactory.newDataType(STANDARD_TYPE_REAL);
01985         tupleDesc.push_back(TupleAttributeDescriptor(typeDesc, isNullable));
01986     }
01987     for (i = 0;i < registersize; i++) {
01988         // booleans in second "half"
01989         StoredTypeDescriptor const &typeDesc =
01990             typeFactory.newDataType(STANDARD_TYPE_UINT_8);
01991         tupleDesc.push_back(TupleAttributeDescriptor(typeDesc, isNullable));
01992     }
01993 
01994     // Create a tuple accessor from the description
01995     //
01996     // Note: Must use a NOT_NULL_AND_FIXED accessor when creating a tuple out
01997     // of the air like this, otherwise unmarshal() does not know what to do. If
01998     // you need a STANDARD type tuple that supports nulls, it has to be built
01999     // as a copy.
02000     TupleAccessor tupleAccessorFixedLiteral;
02001     TupleAccessor tupleAccessorFixedInput;
02002     TupleAccessor tupleAccessorFixedOutput;
02003     TupleAccessor tupleAccessorFixedLocal;
02004     TupleAccessor tupleAccessorFixedStatus;
02005     tupleAccessorFixedLiteral.compute(tupleDesc, TUPLE_FORMAT_ALL_FIXED);
02006     tupleAccessorFixedInput.compute(tupleDesc, TUPLE_FORMAT_ALL_FIXED);
02007     tupleAccessorFixedOutput.compute(tupleDesc, TUPLE_FORMAT_ALL_FIXED);
02008     tupleAccessorFixedLocal.compute(tupleDesc, TUPLE_FORMAT_ALL_FIXED);
02009     tupleAccessorFixedStatus.compute(tupleDesc, TUPLE_FORMAT_ALL_FIXED);
02010 
02011     // Allocate memory for the tuple
02012     boost::scoped_array<FixedBuffer> pTupleBufFixedLiteral(
02013         new FixedBuffer[tupleAccessorFixedLiteral.getMaxByteCount()]);
02014     boost::scoped_array<FixedBuffer> pTupleBufFixedInput(
02015         new FixedBuffer[tupleAccessorFixedInput.getMaxByteCount()]);
02016     boost::scoped_array<FixedBuffer> pTupleBufFixedOutput(
02017         new FixedBuffer[tupleAccessorFixedOutput.getMaxByteCount()]);
02018     boost::scoped_array<FixedBuffer> pTupleBufFixedLocal(
02019         new FixedBuffer[tupleAccessorFixedLocal.getMaxByteCount()]);
02020     boost::scoped_array<FixedBuffer> pTupleBufFixedStatus(
02021         new FixedBuffer[tupleAccessorFixedStatus.getMaxByteCount()]);
02022 
02023     // Link memory to accessor
02024     tupleAccessorFixedLiteral.setCurrentTupleBuf(
02025         pTupleBufFixedLiteral.get(), false);
02026     tupleAccessorFixedInput.setCurrentTupleBuf(
02027         pTupleBufFixedInput.get(), false);
02028     tupleAccessorFixedOutput.setCurrentTupleBuf(
02029         pTupleBufFixedOutput.get(), false);
02030     tupleAccessorFixedLocal.setCurrentTupleBuf(
02031         pTupleBufFixedLocal.get(), false);
02032     tupleAccessorFixedStatus.setCurrentTupleBuf(
02033         pTupleBufFixedStatus.get(), false);
02034 
02035     // Create a vector of TupleDatum objects based on the description we built
02036     TupleData tupleDataFixedLiteral(tupleDesc);
02037     TupleData tupleDataFixedInput(tupleDesc);
02038     TupleData tupleDataFixedOutput(tupleDesc);
02039     TupleData tupleDataFixedLocal(tupleDesc);
02040     TupleData tupleDataFixedStatus(tupleDesc);
02041 
02042     // Do something mysterious. Probably binding pointers in the accessor to
02043     // items in the TupleData vector
02044     tupleAccessorFixedLiteral.unmarshal(tupleDataFixedLiteral);
02045     tupleAccessorFixedInput.unmarshal(tupleDataFixedInput);
02046     tupleAccessorFixedOutput.unmarshal(tupleDataFixedOutput);
02047     tupleAccessorFixedLocal.unmarshal(tupleDataFixedLocal);
02048     tupleAccessorFixedStatus.unmarshal(tupleDataFixedStatus);
02049 
02050     TupleData::iterator itr = tupleDataFixedLiteral.begin();
02051     int neg = registersize / 2;
02052     for (i = 0; i < registersize; i++, itr++) {
02053         // set up some nice literals for tests
02054         if (i < neg) {
02055             *(reinterpret_cast<float *>(const_cast<PBuffer>(itr->pData))) =
02056                 (float) i / 2;
02057         } else {
02058             *(reinterpret_cast<float *>(const_cast<PBuffer>(itr->pData))) =
02059                 (float) (i - neg) / -2;
02060         }
02061     }
02062     itr = tupleDataFixedInput.begin();
02063     for (i = 0; i < registersize; i++, itr++) {
02064         *(reinterpret_cast<float *>(const_cast<PBuffer>(itr->pData))) = -1;
02065     }
02066     itr = tupleDataFixedOutput.begin();
02067     for (i = 0; i < registersize; i++, itr++) {
02068         *(reinterpret_cast<float *>(const_cast<PBuffer>(itr->pData))) = -1;
02069     }
02070     itr = tupleDataFixedLocal.begin();
02071     for (i = 0; i < registersize; i++, itr++) {
02072         *(reinterpret_cast<float *>(const_cast<PBuffer>(itr->pData))) = -1;
02073     }
02074 
02075     // set up boolean literals
02076     int falseIdx = 0;
02077     int trueIdx = 1;
02078     *(reinterpret_cast<bool *>
02079       (const_cast<PBuffer>
02080        (tupleDataFixedLiteral[trueIdx + registersize].pData))) = true;
02081     *(reinterpret_cast<bool *>
02082       (const_cast<PBuffer>
02083        (tupleDataFixedLiteral[falseIdx + registersize].pData))) = false;
02084 
02085     // Create another TupleData object that will be nullable
02086     TupleData literal = tupleDataFixedLiteral;
02087     TupleData input = tupleDataFixedInput;
02088     TupleData output = tupleDataFixedOutput;
02089     TupleData local = tupleDataFixedLocal;
02090     TupleData status = tupleDataFixedStatus;
02091 
02092     // null out last element of each type
02093     int nullidx = registersize - 1;
02094     literal[nullidx].pData = NULL;
02095     input[nullidx].pData = NULL;
02096     output[nullidx].pData = NULL;
02097     local[nullidx].pData = NULL;
02098 
02099     // also make a null in the boolean part of the literal set
02100     int boolnullidx = (2 * registersize) - 1;
02101     literal[boolnullidx].pData = NULL;
02102 
02103     // Print out the nullable tuple
02104     TuplePrinter tuplePrinter;
02105     printf("Literals\n");
02106     tuplePrinter.print(cout, tupleDesc, literal);
02107     printf("\nInput\n");
02108     tuplePrinter.print(cout, tupleDesc, input);
02109     cout << endl;
02110     printf("\nOutput\n");
02111     tuplePrinter.print(cout, tupleDesc, output);
02112     cout << endl;
02113     printf("\nLocal\n");
02114     tuplePrinter.print(cout, tupleDesc, local);
02115     cout << endl;
02116 
02117     // predefine register references. a real compiler wouldn't do
02118     // something so regular and pre-determined. a compiler would
02119     // probably build these on the fly as it built each instruction.
02120     // predefine register references. a real compiler wouldn't do
02121     // something so regular and pre-determined
02122     RegisterRef<float> **fInP, **fOutP, **fLoP, **fLiP;
02123     RegisterRef<bool> **bOutP;
02124 
02125     fInP = new RegisterRef<float>*[registersize];
02126     fOutP = new RegisterRef<float>*[registersize];
02127     fLoP = new RegisterRef<float>*[registersize];
02128     fLiP = new RegisterRef<float>*[registersize];
02129     bOutP = new RegisterRef<bool>*[registersize];
02130 
02131     // Set up the Calculator
02132     DynamicParamManager dpm;
02133     Calculator c(&dpm,0,0,0,0,0,0);
02134     c.outputRegisterByReference(false);
02135 
02136     // set up register references to symbolically point to
02137     // their corresponding storage locations -- makes for easy test case
02138     // generation. again, a compiler wouldn't do things in quite
02139     // this way
02140     for (i = 0; i < registersize; i++) {
02141         fInP[i] = new RegisterRef<float>(
02142             RegisterReference::EInput,
02143             i,
02144             STANDARD_TYPE_REAL);
02145         c.appendRegRef(fInP[i]);
02146         fOutP[i] = new RegisterRef<float>(
02147             RegisterReference::EOutput,
02148             i,
02149             STANDARD_TYPE_REAL);
02150         c.appendRegRef(fOutP[i]);
02151         fLoP[i] = new RegisterRef<float>(
02152             RegisterReference::ELocal,
02153             i,
02154             STANDARD_TYPE_REAL);
02155         c.appendRegRef(fLoP[i]);
02156         fLiP[i] = new RegisterRef<float>(
02157             RegisterReference::ELiteral,
02158             i,
02159             STANDARD_TYPE_REAL);
02160         c.appendRegRef(fLiP[i]);
02161 
02162         bOutP[i] = new RegisterRef<bool>(
02163             RegisterReference::EOutput,
02164             i + registersize,
02165             STANDARD_TYPE_BOOL);
02166         c.appendRegRef(bOutP[i]);
02167     }
02168 
02169 
02170     // Set up storage for instructions
02171     // a real compiler would probably cons up instructions and insert them
02172     // directly into the calculator. keep an array of the instructions at
02173     // this level to allow printing of the program after execution, and other
02174     // debugging
02175     Instruction **instP;
02176     instP = new InstructionPtr[200];
02177     int pc = 0, outC = 0, outBoolC = 0;
02178 
02179     StandardTypeDescriptorOrdinal isFloat = STANDARD_TYPE_REAL;
02180 
02181     // add
02182     instP[pc++] = new NativeAdd<float>(
02183         fOutP[outC++], fLiP[10], fLiP[10], isFloat);
02184     instP[pc++] = new NativeAdd<float>(
02185         fOutP[outC++], fLiP[10], fLiP[9], isFloat);
02186     instP[pc++] = new NativeAdd<float>(
02187         fOutP[outC++], fLiP[0], fLiP[0], isFloat);
02188     instP[pc++] = new NativeAdd<float>(
02189         fOutP[outC++], fLiP[neg], fLiP[neg], isFloat); // -0 + -0
02190     instP[pc++] = new NativeAdd<float>(
02191         fOutP[outC++], fLiP[neg + 1], fLiP[neg + 2], isFloat);
02192 
02193     instP[pc++] = new NativeAdd<float>(
02194         fOutP[outC++], fLiP[nullidx], fLiP[9], isFloat);
02195     instP[pc++] = new NativeAdd<float>(
02196         fOutP[outC++], fLiP[10], fLiP[nullidx], isFloat);
02197     instP[pc++] = new NativeAdd<float>(
02198         fOutP[outC++], fLiP[nullidx], fLiP[nullidx], isFloat);
02199 
02200     // sub
02201     instP[pc++] = new NativeSub<float>(
02202         fOutP[outC++], fLiP[10], fLiP[9], isFloat);
02203     instP[pc++] = new NativeSub<float>(
02204         fOutP[outC++], fLiP[10], fLiP[10], isFloat);
02205     instP[pc++] = new NativeSub<float>(
02206         fOutP[outC++], fLiP[9], fLiP[0], isFloat);
02207     instP[pc++] = new NativeSub<float>(
02208         fOutP[outC++], fLiP[0], fLiP[0], isFloat);
02209     instP[pc++] = new NativeSub<float>(
02210         fOutP[outC++], fLiP[neg], fLiP[neg], isFloat);
02211     instP[pc++] = new NativeSub<float>(
02212         fOutP[outC++], fLiP[neg + 4], fLiP[neg + 1], isFloat);
02213 
02214     instP[pc++] = new NativeSub<float>(
02215         fOutP[outC++], fLiP[nullidx], fLiP[10], isFloat);
02216     instP[pc++] = new NativeSub<float>(
02217         fOutP[outC++], fLiP[10], fLiP[nullidx], isFloat);
02218     instP[pc++] = new NativeSub<float>(
02219         fOutP[outC++], fLiP[nullidx], fLiP[nullidx], isFloat);
02220 
02221     // mul
02222     instP[pc++] = new NativeMul<float>(
02223         fOutP[outC++], fLiP[4], fLiP[6], isFloat);
02224     instP[pc++] = new NativeMul<float>(
02225         fOutP[outC++], fLiP[5], fLiP[5], isFloat);
02226     instP[pc++] = new NativeMul<float>(
02227         fOutP[outC++], fLiP[0], fLiP[0], isFloat);
02228     instP[pc++] = new NativeMul<float>(
02229         fOutP[outC++], fLiP[neg], fLiP[neg], isFloat);
02230     instP[pc++] = new NativeMul<float>(
02231         fOutP[outC++], fLiP[6], fLiP[neg], isFloat);
02232     instP[pc++] = new NativeMul<float>(
02233         fOutP[outC++], fLiP[6], fLiP[0], isFloat);
02234     instP[pc++] = new NativeMul<float>(
02235         fOutP[outC++], fLiP[neg + 7], fLiP[2], isFloat);
02236 
02237     instP[pc++] = new NativeMul<float>(
02238         fOutP[outC++], fLiP[nullidx], fLiP[5], isFloat);
02239     instP[pc++] = new NativeMul<float>(
02240         fOutP[outC++], fLiP[4], fLiP[nullidx], isFloat);
02241     instP[pc++] = new NativeMul<float>(
02242         fOutP[outC++], fLiP[nullidx], fLiP[nullidx], isFloat);
02243 
02244     // div
02245     instP[pc++] = new NativeDiv<float>(
02246         fOutP[outC++], fLiP[12], fLiP[4], isFloat);
02247     instP[pc++] = new NativeDiv<float>(
02248         fOutP[outC++], fLiP[12], fLiP[3], isFloat);
02249     instP[pc++] = new NativeDiv<float>(
02250         fOutP[outC++], fLiP[0], fLiP[3], isFloat);
02251     instP[pc++] = new NativeDiv<float>(
02252         fOutP[outC++], fLiP[neg], fLiP[3], isFloat);
02253     instP[pc++] = new NativeDiv<float>(
02254         fOutP[outC++], fLiP[neg + 9], fLiP[neg + 2], isFloat);
02255     instP[pc++] = new NativeDiv<float>(
02256         fOutP[outC++], fLiP[neg + 9], fLiP[1], isFloat);
02257 
02258     instP[pc++] = new NativeDiv<float>(
02259         fOutP[outC++], fLiP[12], fLiP[nullidx], isFloat);
02260     instP[pc++] = new NativeDiv<float>(
02261         fOutP[outC++], fLiP[nullidx], fLiP[3], isFloat);
02262     instP[pc++] = new NativeDiv<float>(
02263         fOutP[outC++], fLiP[nullidx], fLiP[nullidx], isFloat);
02264     // div by zero
02265     int divbyzero = pc;
02266     instP[pc++] = new NativeDiv<float>(
02267         fOutP[outC++], fLiP[4], fLiP[0], isFloat);
02268     instP[pc++] = new NativeDiv<float>(
02269         fOutP[outC++], fLiP[4], fLiP[neg], isFloat);
02270 
02271     // neg
02272     instP[pc++] = new NativeNeg<float>(
02273         fOutP[outC++], fLiP[3], isFloat);
02274     instP[pc++] = new NativeNeg<float>(
02275         fOutP[outC++], fLiP[neg + 3], isFloat);
02276     instP[pc++] = new NativeNeg<float>(
02277         fOutP[outC++], fLiP[0], isFloat);
02278     instP[pc++] = new NativeNeg<float>(
02279         fOutP[outC++], fLiP[neg], isFloat);
02280     instP[pc++] = new NativeNeg<float>(
02281         fOutP[outC++], fLiP[nullidx], isFloat);
02282 
02283     // move
02284     instP[pc++] = new NativeMove<float>(
02285         fOutP[outC++], fLiP[3], isFloat);
02286     instP[pc++] = new NativeMove<float>(
02287         fOutP[outC++], fLiP[6], isFloat);
02288     instP[pc++] = new NativeMove<float>(
02289         fOutP[outC++], fLiP[0], isFloat);
02290     instP[pc++] = new NativeMove<float>(
02291         fOutP[outC++], fLiP[neg], isFloat);
02292     instP[pc++] = new NativeMove<float>(
02293         fOutP[outC++], fLiP[nullidx], isFloat);
02294 
02295     // equal
02296     instP[pc++] = new BoolNativeEqual<float>(
02297         bOutP[outBoolC++], fLiP[0], fLiP[0], isFloat);
02298     instP[pc++] = new BoolNativeEqual<float>(
02299         bOutP[outBoolC++], fLiP[neg], fLiP[neg], isFloat);
02300     instP[pc++] = new BoolNativeEqual<float>(
02301         bOutP[outBoolC++], fLiP[4], fLiP[4], isFloat);
02302     instP[pc++] = new BoolNativeEqual<float>(
02303         bOutP[outBoolC++], fLiP[9], fLiP[9], isFloat);
02304     instP[pc++] = new BoolNativeEqual<float>(
02305         bOutP[outBoolC++], fLiP[3], fLiP[5], isFloat);
02306     instP[pc++] = new BoolNativeEqual<float>(
02307         bOutP[outBoolC++], fLiP[5], fLiP[3], isFloat);
02308     instP[pc++] = new BoolNativeEqual<float>(
02309         bOutP[outBoolC++], fLiP[6], fLiP[2], isFloat);
02310     instP[pc++] = new BoolNativeEqual<float>(
02311         bOutP[outBoolC++], fLiP[2], fLiP[6], isFloat);
02312     instP[pc++] = new BoolNativeEqual<float>(
02313         bOutP[outBoolC++], fLiP[neg + 5], fLiP[neg + 5], isFloat);
02314     instP[pc++] = new BoolNativeEqual<float>(
02315         bOutP[outBoolC++], fLiP[neg + 5], fLiP[neg + 6], isFloat);
02316 
02317     instP[pc++] = new BoolNativeEqual<float>(
02318         bOutP[outBoolC++], fLiP[12], fLiP[nullidx], isFloat);
02319     instP[pc++] = new BoolNativeEqual<float>(
02320         bOutP[outBoolC++], fLiP[nullidx], fLiP[3], isFloat);
02321     instP[pc++] = new BoolNativeEqual<float>(
02322         bOutP[outBoolC++], fLiP[nullidx], fLiP[nullidx], isFloat);
02323 
02324     // notequal
02325     instP[pc++] = new BoolNativeNotEqual<float>(
02326         bOutP[outBoolC++], fLiP[0], fLiP[0], isFloat);
02327     instP[pc++] = new BoolNativeNotEqual<float>(
02328         bOutP[outBoolC++], fLiP[4], fLiP[4], isFloat);
02329     instP[pc++] = new BoolNativeNotEqual<float>(
02330         bOutP[outBoolC++], fLiP[9], fLiP[9], isFloat);
02331     instP[pc++] = new BoolNativeNotEqual<float>(
02332         bOutP[outBoolC++], fLiP[3], fLiP[5], isFloat);
02333     instP[pc++] = new BoolNativeNotEqual<float>(
02334         bOutP[outBoolC++], fLiP[5], fLiP[3], isFloat);
02335     instP[pc++] = new BoolNativeNotEqual<float>(
02336         bOutP[outBoolC++], fLiP[6], fLiP[2], isFloat);
02337     instP[pc++] = new BoolNativeNotEqual<float>(
02338         bOutP[outBoolC++], fLiP[2], fLiP[6], isFloat);
02339 
02340     instP[pc++] = new BoolNativeNotEqual<float>(
02341         bOutP[outBoolC++], fLiP[12], fLiP[nullidx], isFloat);
02342     instP[pc++] = new BoolNativeNotEqual<float>(
02343         bOutP[outBoolC++], fLiP[nullidx], fLiP[3], isFloat);
02344     instP[pc++] = new BoolNativeNotEqual<float>(
02345         bOutP[outBoolC++], fLiP[nullidx], fLiP[nullidx], isFloat);
02346 
02347     // greater
02348     instP[pc++] = new BoolNativeGreater<float>(
02349         bOutP[outBoolC++], fLiP[0], fLiP[0], isFloat);
02350     instP[pc++] = new BoolNativeGreater<float>(
02351         bOutP[outBoolC++], fLiP[4], fLiP[4], isFloat);
02352     instP[pc++] = new BoolNativeGreater<float>(
02353         bOutP[outBoolC++], fLiP[9], fLiP[9], isFloat);
02354     instP[pc++] = new BoolNativeGreater<float>(
02355         bOutP[outBoolC++], fLiP[3], fLiP[5], isFloat);
02356     instP[pc++] = new BoolNativeGreater<float>(
02357         bOutP[outBoolC++], fLiP[5], fLiP[3], isFloat);
02358     instP[pc++] = new BoolNativeGreater<float>(
02359         bOutP[outBoolC++], fLiP[neg + 3], fLiP[neg + 5], isFloat);
02360     instP[pc++] = new BoolNativeGreater<float>(
02361         bOutP[outBoolC++], fLiP[neg + 5], fLiP[neg + 3], isFloat);
02362     instP[pc++] = new BoolNativeGreater<float>(
02363         bOutP[outBoolC++], fLiP[neg], fLiP[neg], isFloat);
02364     instP[pc++] = new BoolNativeGreater<float>(
02365         bOutP[outBoolC++], fLiP[7], fLiP[neg + 7], isFloat);
02366     instP[pc++] = new BoolNativeGreater<float>(
02367         bOutP[outBoolC++], fLiP[neg + 7], fLiP[7], isFloat);
02368 
02369     instP[pc++] = new BoolNativeGreater<float>(
02370         bOutP[outBoolC++], fLiP[12], fLiP[nullidx], isFloat);
02371     instP[pc++] = new BoolNativeGreater<float>(
02372         bOutP[outBoolC++], fLiP[nullidx], fLiP[3], isFloat);
02373     instP[pc++] = new BoolNativeGreater<float>(
02374         bOutP[outBoolC++], fLiP[nullidx], fLiP[nullidx], isFloat);
02375 
02376     // greaterequal
02377     instP[pc++] = new BoolNativeGreaterEqual<float>(
02378         bOutP[outBoolC++], fLiP[0], fLiP[0], isFloat);
02379     instP[pc++] = new BoolNativeGreaterEqual<float>(
02380         bOutP[outBoolC++], fLiP[4], fLiP[4], isFloat);
02381     instP[pc++] = new BoolNativeGreaterEqual<float>(
02382         bOutP[outBoolC++], fLiP[9], fLiP[9], isFloat);
02383     instP[pc++] = new BoolNativeGreaterEqual<float>(
02384         bOutP[outBoolC++], fLiP[3], fLiP[5], isFloat);
02385     instP[pc++] = new BoolNativeGreaterEqual<float>(
02386         bOutP[outBoolC++], fLiP[5], fLiP[3], isFloat);
02387     instP[pc++] = new BoolNativeGreaterEqual<float>(
02388         bOutP[outBoolC++], fLiP[neg + 3], fLiP[neg + 5], isFloat);
02389     instP[pc++] = new BoolNativeGreaterEqual<float>(
02390         bOutP[outBoolC++], fLiP[neg + 5], fLiP[neg + 3], isFloat);
02391     instP[pc++] = new BoolNativeGreaterEqual<float>(
02392         bOutP[outBoolC++], fLiP[neg], fLiP[neg], isFloat);
02393     instP[pc++] = new BoolNativeGreaterEqual<float>(
02394         bOutP[outBoolC++], fLiP[7], fLiP[neg + 7], isFloat);
02395     instP[pc++] = new BoolNativeGreaterEqual<float>(
02396         bOutP[outBoolC++], fLiP[neg + 7], fLiP[7], isFloat);
02397     instP[pc++] = new BoolNativeGreaterEqual<float>(
02398         bOutP[outBoolC++], fLiP[neg + 7], fLiP[neg + 7], isFloat);
02399 
02400     instP[pc++] = new BoolNativeGreaterEqual<float>(
02401         bOutP[outBoolC++], fLiP[12], fLiP[nullidx], isFloat);
02402     instP[pc++] = new BoolNativeGreaterEqual<float>(
02403         bOutP[outBoolC++], fLiP[nullidx], fLiP[3], isFloat);
02404     instP[pc++] = new BoolNativeGreaterEqual<float>(
02405         bOutP[outBoolC++], fLiP[nullidx], fLiP[nullidx], isFloat);
02406 
02407     // less
02408     instP[pc++] = new BoolNativeLess<float>(
02409         bOutP[outBoolC++], fLiP[0], fLiP[0], isFloat);
02410     instP[pc++] = new BoolNativeLess<float>(
02411         bOutP[outBoolC++], fLiP[4], fLiP[4], isFloat);
02412     instP[pc++] = new BoolNativeLess<float>(
02413         bOutP[outBoolC++], fLiP[9], fLiP[9], isFloat);
02414     instP[pc++] = new BoolNativeLess<float>(
02415         bOutP[outBoolC++], fLiP[3], fLiP[5], isFloat);
02416     instP[pc++] = new BoolNativeLess<float>(
02417         bOutP[outBoolC++], fLiP[5], fLiP[3], isFloat);
02418     instP[pc++] = new BoolNativeLess<float>(
02419         bOutP[outBoolC++], fLiP[neg + 3], fLiP[neg + 5], isFloat);
02420     instP[pc++] = new BoolNativeLess<float>(
02421         bOutP[outBoolC++], fLiP[neg + 5], fLiP[neg + 3], isFloat);
02422 
02423     instP[pc++] = new BoolNativeLess<float>(
02424         bOutP[outBoolC++], fLiP[12], fLiP[nullidx], isFloat);
02425     instP[pc++] = new BoolNativeLess<float>(
02426         bOutP[outBoolC++], fLiP[nullidx], fLiP[3], isFloat);
02427     instP[pc++] = new BoolNativeLess<float>(
02428         bOutP[outBoolC++], fLiP[nullidx], fLiP[nullidx], isFloat);
02429 
02430     // lessequal
02431     instP[pc++] = new BoolNativeLessEqual<float>(
02432         bOutP[outBoolC++], fLiP[0], fLiP[0], isFloat);
02433     instP[pc++] = new BoolNativeLessEqual<float>(
02434         bOutP[outBoolC++], fLiP[4], fLiP[4], isFloat);
02435     instP[pc++] = new BoolNativeLessEqual<float>(
02436         bOutP[outBoolC++], fLiP[9], fLiP[9], isFloat);
02437     instP[pc++] = new BoolNativeLessEqual<float>(
02438         bOutP[outBoolC++], fLiP[3], fLiP[5], isFloat);
02439     instP[pc++] = new BoolNativeLessEqual<float>(
02440         bOutP[outBoolC++], fLiP[5], fLiP[3], isFloat);
02441     instP[pc++] = new BoolNativeLessEqual<float>(
02442         bOutP[outBoolC++], fLiP[neg + 3], fLiP[neg + 5], isFloat);
02443     instP[pc++] = new BoolNativeLessEqual<float>(
02444         bOutP[outBoolC++], fLiP[neg + 5], fLiP[neg + 3], isFloat);
02445 
02446     instP[pc++] = new BoolNativeLessEqual<float>(
02447         bOutP[outBoolC++], fLiP[12], fLiP[nullidx], isFloat);
02448     instP[pc++] = new BoolNativeLessEqual<float>(
02449         bOutP[outBoolC++], fLiP[nullidx], fLiP[3], isFloat);
02450     instP[pc++] = new BoolNativeLessEqual<float>(
02451         bOutP[outBoolC++], fLiP[nullidx], fLiP[nullidx], isFloat);
02452 
02453     // isnull
02454     instP[pc++] = new BoolNativeIsNull<float>(
02455         bOutP[outBoolC++], fLiP[12], isFloat);
02456     instP[pc++] = new BoolNativeIsNull<float>(
02457         bOutP[outBoolC++], fLiP[nullidx], isFloat);
02458     // isnotnull
02459     instP[pc++] = new BoolNativeIsNotNull<float>(
02460         bOutP[outBoolC++], fLiP[12], isFloat);
02461     instP[pc++] = new BoolNativeIsNotNull<float>(
02462         bOutP[outBoolC++], fLiP[nullidx], isFloat);
02463     // tonull
02464     instP[pc++] = new NativeToNull<float>(
02465         fOutP[outC++], isFloat);
02466 
02467     // return
02468     instP[pc++] = new NativeMove<float>(
02469         fOutP[outC], fLiP[20], isFloat);  // good flag
02470     instP[pc++] = new ReturnInstruction();
02471     instP[pc++] = new NativeMove<float>(
02472         fOutP[outC++], fLiP[10], isFloat); // bad flag
02473 
02474     int lastPC = pc;
02475 
02476     for (i = 0; i < pc; i++) {
02477         c.appendInstruction(instP[i]);
02478     }
02479 
02480     c.bind(
02481         RegisterReference::ELiteral,
02482         &literal,
02483         tupleDesc);
02484     c.bind(
02485         RegisterReference::EInput,
02486         &input,
02487         tupleDesc);
02488     c.bind(
02489         RegisterReference::EOutput,
02490         &output,
02491         tupleDesc);
02492     c.bind(
02493         RegisterReference::ELocal,
02494         &local,
02495         tupleDesc);
02496     c.bind(
02497         RegisterReference::EStatus,
02498         &status,
02499         tupleDesc);
02500     c.exec();
02501 
02502     string out;
02503     for (i = 0; i < pc; i++) {
02504         instP[i]->describe(out, true);
02505         printf("[%2d] %s\n", i, out.c_str());
02506     }
02507 
02508     // Print out the output tuple
02509     printf("Output Tuple\n");
02510     tuplePrinter.print(cout, tupleDesc, output);
02511     cout << endl;
02512 
02513     outC = 0;
02514     outBoolC = registersize;
02515     // TODO tests to add: Maxint, minint, zeros, negatives, overflow,
02516     // underflow, etc
02517 
02518     // add
02519     if (*(reinterpret_cast<const float *>(output[outC++].pData)) != 10) {
02520         fail("floatadd1", __LINE__);
02521     }
02522     if (*(reinterpret_cast<const float *>(output[outC++].pData)) != 9.5) {
02523         fail("floatadd2", __LINE__);
02524     }
02525     if (*(reinterpret_cast<const float *>(output[outC++].pData)) != 0) {
02526         fail("floatadd3", __LINE__);
02527     }
02528     if (*(reinterpret_cast<const float *>(output[outC++].pData)) != 0) {
02529         fail("floatadd4", __LINE__);
02530     }
02531     if (*(reinterpret_cast<const float *>(output[outC++].pData)) != -1.5) {
02532         fail("floatadd5", __LINE__);
02533     }
02534     if (output[outC++].pData != NULL) {
02535         fail("floatadd6", __LINE__);
02536     }
02537     if (output[outC++].pData != NULL) {
02538         fail("floatadd7", __LINE__);
02539     }
02540     if (output[outC++].pData != NULL) {
02541         fail("floatadd8", __LINE__);
02542     }
02543 
02544     // sub
02545     if (*(reinterpret_cast<const float *>(output[outC++].pData)) != 0.5) {
02546         fail("floatsub1", __LINE__);
02547     }
02548     if (*(reinterpret_cast<const float *>(output[outC++].pData)) != 0) {
02549         fail("floatsub2", __LINE__);
02550     }
02551     if (*(reinterpret_cast<const float *>(output[outC++].pData)) != 4.5) {
02552         fail("floatsub3", __LINE__);
02553     }
02554     if (*(reinterpret_cast<const float *>(output[outC++].pData)) != 0) {
02555         fail("floatsub4", __LINE__);
02556     }
02557     if (*(reinterpret_cast<const float *>(output[outC++].pData)) != 0) {
02558         fail("floatsub5", __LINE__);
02559     }
02560     if (*(reinterpret_cast<const float *>(output[outC++].pData)) != -1.5) {
02561         fail("floatsub6", __LINE__);
02562     }
02563 
02564     if (output[outC++].pData != NULL) {
02565         fail("floatsub7", __LINE__);
02566     }
02567     if (output[outC++].pData != NULL) {
02568         fail("floatsub8", __LINE__);
02569     }
02570     if (output[outC++].pData != NULL) {
02571         fail("floatsub9", __LINE__);
02572     }
02573 
02574     // mul
02575     if (*(reinterpret_cast<const float *>(output[outC++].pData)) != 6) {
02576         fail("floatmul1", __LINE__);
02577     }
02578     if (*(reinterpret_cast<const float *>(output[outC++].pData)) != 6.25) {
02579         fail("floatmul2", __LINE__);
02580     }
02581     if (*(reinterpret_cast<const float *>(output[outC++].pData)) != 0) {
02582         fail("floatmul3", __LINE__);
02583     }
02584     if (*(reinterpret_cast<const float *>(output[outC++].pData)) != 0) {
02585         fail("floatmul4", __LINE__);
02586     }
02587     if (*(reinterpret_cast<const float *>(output[outC++].pData)) != 0) {
02588         fail("floatmul5", __LINE__);
02589     }
02590     if (*(reinterpret_cast<const float *>(output[outC++].pData)) != 0) {
02591         fail("floatmul6", __LINE__);
02592     }
02593     if (*(reinterpret_cast<const float *>(output[outC++].pData)) != -3.5) {
02594         fail("floatmul7", __LINE__);
02595     }
02596 
02597     if (output[outC++].pData != NULL) {
02598         fail("floatmul8", __LINE__);
02599     }
02600     if (output[outC++].pData != NULL) {
02601         fail("floatmul9", __LINE__);
02602     }
02603     if (output[outC++].pData != NULL) {
02604         fail("floatmul10", __LINE__);
02605     }
02606 
02607     // div
02608     if (*(reinterpret_cast<const float *>(output[outC++].pData)) != 3) {
02609         fail("floatdiv1", __LINE__);
02610     }
02611     if (*(reinterpret_cast<const float *>(output[outC++].pData)) != 4) {
02612         fail("floatdiv2", __LINE__);
02613     }
02614     if (*(reinterpret_cast<const float *>(output[outC++].pData)) != 0) {
02615         fail("floatdiv3", __LINE__);
02616     }
02617     if (*(reinterpret_cast<const float *>(output[outC++].pData)) != 0) {
02618         fail("floatdiv4", __LINE__);
02619     }
02620     if (*(reinterpret_cast<const float *>(output[outC++].pData)) != 4.5) {
02621         fail("floatdiv5", __LINE__);
02622     }
02623     if (*(reinterpret_cast<const float *>(output[outC++].pData)) != -9) {
02624         fail("floatdiv6", __LINE__);
02625     }
02626 
02627     if (output[outC++].pData != NULL) {
02628         fail("floatdiv7", __LINE__);
02629     }
02630     if (output[outC++].pData != NULL) {
02631         fail("floatdiv8", __LINE__);
02632     }
02633     if (output[outC++].pData != NULL) {
02634         fail("floatdiv9", __LINE__);
02635     }
02636     // div by zero
02637     assert(outC == divbyzero);
02638     if (output[outC++].pData != NULL) {
02639         fail("floatdiv10", __LINE__);
02640     }
02641     deque<CalcMessage>::iterator iter = c.mWarnings.begin();
02642     if (iter->pc != divbyzero) {
02643         fail("floatdiv by zero failed, pc wrong\n", __LINE__);
02644     }
02645     string expectederror("22012");
02646     if (expectederror.compare(iter->str)) {
02647         fail("floatdiv by zero failed string was wrong", __LINE__);
02648     }
02649     if (output[outC++].pData != NULL) {
02650         fail("floatdiv11", __LINE__);
02651     }
02652     iter++;
02653     if (iter->pc != divbyzero + 1) {
02654         fail("floatdiv by zero failed, pc wrong\n", __LINE__);
02655     }
02656     if (expectederror.compare(iter->str)) {
02657         fail("floatdiv by zero failed string was wrong", __LINE__);
02658     }
02659 
02660     // neg
02661     if (*(reinterpret_cast<const float *>(output[outC++].pData)) != -1.5) {
02662         fail("floatneg1", __LINE__);
02663     }
02664     if (*(reinterpret_cast<const float *>(output[outC++].pData)) != 1.5) {
02665         fail("floatneg2", __LINE__);
02666     }
02667     if (*(reinterpret_cast<const float *>(output[outC++].pData)) != 0) {
02668         fail("floatneg3", __LINE__);
02669     }
02670     if (*(reinterpret_cast<const float *>(output[outC++].pData)) != 0) {
02671         fail("floatneg4", __LINE__);
02672     }
02673     if (output[outC++].pData != NULL) {
02674         fail("floatneg5", __LINE__);
02675     }
02676 
02677     // move
02678     if (*(reinterpret_cast<const float *>(output[outC++].pData)) != 1.5) {
02679         fail("floatmove1", __LINE__);
02680     }
02681     if (*(reinterpret_cast<const float *>(output[outC++].pData)) != 3) {
02682         fail("floatmove2", __LINE__);
02683     }
02684     if (*(reinterpret_cast<const float *>(output[outC++].pData)) != 0) {
02685         fail("floatmove3", __LINE__);
02686     }
02687     if (*(reinterpret_cast<const float *>(output[outC++].pData)) != 0) {
02688         fail("floatmove4", __LINE__);
02689     }
02690     if (output[outC++].pData != NULL) {
02691         fail("floatmove5", __LINE__);
02692     }
02693 
02694     // equal
02695     if (*(output[outBoolC++].pData) != true) {
02696         fail("floatequal1", __LINE__);
02697     }
02698     if (*(output[outBoolC++].pData) != true) {
02699         fail("floatequal2", __LINE__);
02700     }
02701     if (*(output[outBoolC++].pData) != true) {
02702         fail("floatequal3", __LINE__);
02703     }
02704     if (*(output[outBoolC++].pData) != true) {
02705         fail("floatequal4", __LINE__);
02706     }
02707     if (*(output[outBoolC++].pData) != false) {
02708         fail("floatequal5", __LINE__);
02709     }
02710     if (*(output[outBoolC++].pData) != false) {
02711         fail("floatequal6", __LINE__);
02712     }
02713     if (*(output[outBoolC++].pData) != false) {
02714         fail("floatequal7", __LINE__);
02715     }
02716     if (*(output[outBoolC++].pData) != false) {
02717         fail("floatequal8", __LINE__);
02718     }
02719     if (*(output[outBoolC++].pData) != true) {
02720         fail("floatequal9", __LINE__);
02721     }
02722     if (*(output[outBoolC++].pData) != false) {
02723         fail("floatequal10", __LINE__);
02724     }
02725 
02726     if (output[outBoolC++].pData != NULL) {
02727         fail("floatequal11", __LINE__);
02728     }
02729     if (output[outBoolC++].pData != NULL) {
02730         fail("floatequal12", __LINE__);
02731     }
02732     if (output[outBoolC++].pData != NULL) {
02733         fail("floatequal13", __LINE__);
02734     }
02735 
02736     // notequal
02737     if (*(output[outBoolC++].pData) != false) {
02738         fail("floatnotequal1", __LINE__);
02739     }
02740     if (*(output[outBoolC++].pData) != false) {
02741         fail("floatnotequal2", __LINE__);
02742     }
02743     if (*(output[outBoolC++].pData) != false) {
02744         fail("floatnotequal3", __LINE__);
02745     }
02746     if (*(output[outBoolC++].pData) != true) {
02747         fail("floatnotequal4", __LINE__);
02748     }
02749     if (*(output[outBoolC++].pData) != true) {
02750         fail("floatnotequal5", __LINE__);
02751     }
02752     if (*(output[outBoolC++].pData) != true) {
02753         fail("floatnotequal6", __LINE__);
02754     }
02755     if (*(output[outBoolC++].pData) != true) {
02756         fail("floatnotequal7", __LINE__);
02757     }
02758 
02759     if (output[outBoolC++].pData != NULL) {
02760         fail("floatnotequal8", __LINE__);
02761     }
02762     if (output[outBoolC++].pData != NULL) {
02763         fail("floatnotequal9", __LINE__);
02764     }
02765     if (output[outBoolC++].pData != NULL) {
02766         fail("floatnotequal10", __LINE__);
02767     }
02768 
02769     // greater
02770     if (*(output[outBoolC++].pData) != false) {
02771         fail("floatgreater1", __LINE__);
02772     }
02773     if (*(output[outBoolC++].pData) != false) {
02774         fail("floatgreater2", __LINE__);
02775     }
02776     if (*(output[outBoolC++].pData) != false) {
02777         fail("floatgreater3", __LINE__);
02778     }
02779     if (*(output[outBoolC++].pData) != false) {
02780         fail("floatgreater4", __LINE__);
02781     }
02782     if (*(output[outBoolC++].pData) != true) {
02783         fail("floatgreater5", __LINE__);
02784     }
02785     if (*(output[outBoolC++].pData) != true) {
02786         fail("floatgreater6", __LINE__);
02787     }
02788     if (*(output[outBoolC++].pData) != false) {
02789         fail("floatgreater7", __LINE__);
02790     }
02791     if (*(output[outBoolC++].pData) != false) {
02792         fail("floatgreater8", __LINE__);
02793     }
02794     if (*(output[outBoolC++].pData) != true) {
02795         fail("floatgreater9", __LINE__);
02796     }
02797     if (*(output[outBoolC++].pData) != false) {
02798         fail("floatgreater10", __LINE__);
02799     }
02800 
02801     if (output[outBoolC++].pData != NULL) {
02802         fail("floatgreater11", __LINE__);
02803     }
02804     if (output[outBoolC++].pData != NULL) {
02805         fail("floatgreater12", __LINE__);
02806     }
02807     if (output[outBoolC++].pData != NULL) {
02808         fail("floatgreater13", __LINE__);
02809     }
02810 
02811     // greaterequal
02812     if (*(output[outBoolC++].pData) != true) {
02813         fail("floatgreaterequal1", __LINE__);
02814     }
02815     if (*(output[outBoolC++].pData) != true) {
02816         fail("floatgreaterequal2", __LINE__);
02817     }
02818     if (*(output[outBoolC++].pData) != true) {
02819         fail("floatgreaterequal3", __LINE__);
02820     }
02821     if (*(output[outBoolC++].pData) != false) {
02822         fail("floatgreaterequal4", __LINE__);
02823     }
02824     if (*(output[outBoolC++].pData) != true) {
02825         fail("floatgreaterequal5", __LINE__);
02826     }
02827     if (*(output[outBoolC++].pData) != true) {
02828         fail("floatgreaterequal6", __LINE__);
02829     }
02830     if (*(output[outBoolC++].pData) != false) {
02831         fail("floatgreaterequal7", __LINE__);
02832     }
02833     if (*(output[outBoolC++].pData) != true) {
02834         fail("floatgreaterequal8", __LINE__);
02835     }
02836     if (*(output[outBoolC++].pData) != true) {
02837         fail("floatgreaterequal9", __LINE__);
02838     }
02839     if (*(output[outBoolC++].pData) != false) {
02840         fail("floatgreaterequal10", __LINE__);
02841     }
02842     if (*(output[outBoolC++].pData) != true) {
02843         fail("floatgreaterequal11", __LINE__);
02844     }
02845 
02846     if (output[outBoolC++].pData != NULL) {
02847         fail("floatgreaterequal12", __LINE__);
02848     }
02849     if (output[outBoolC++].pData != NULL) {
02850         fail("floatgreaterequal13", __LINE__);
02851     }
02852     if (output[outBoolC++].pData != NULL) {
02853         fail("floatgreaterequal14", __LINE__);
02854     }
02855 
02856     // less
02857     if (*(output[outBoolC++].pData) != false) {
02858         fail("floatless1", __LINE__);
02859     }
02860     if (*(output[outBoolC++].pData) != false) {
02861         fail("floatless2", __LINE__);
02862     }
02863     if (*(output[outBoolC++].pData) != false) {
02864         fail("floatless3", __LINE__);
02865     }
02866     if (*(output[outBoolC++].pData) != true) {
02867         fail("floatless4", __LINE__);
02868     }
02869     if (*(output[outBoolC++].pData) != false) {
02870         fail("floatless5", __LINE__);
02871     }
02872     if (*(output[outBoolC++].pData) != false) {
02873         fail("floatless6", __LINE__);
02874     }
02875     if (*(output[outBoolC++].pData) != true) {
02876         fail("floatless7", __LINE__);
02877     }
02878 
02879     if (output[outBoolC++].pData != NULL) {
02880         fail("floatless8", __LINE__);
02881     }
02882     if (output[outBoolC++].pData != NULL) {
02883         fail("floatless9", __LINE__);
02884     }
02885     if (output[outBoolC++].pData != NULL) {
02886         fail("floatless10", __LINE__);
02887     }
02888 
02889     // lessequal
02890     if (*(output[outBoolC++].pData) != true) {
02891         fail("floatlessequal1", __LINE__);
02892     }
02893     if (*(output[outBoolC++].pData) != true) {
02894         fail("floatlessequal2", __LINE__);
02895     }
02896     if (*(output[outBoolC++].pData) != true) {
02897         fail("floatlessequal3", __LINE__);
02898     }
02899     if (*(output[outBoolC++].pData) != true) {
02900         fail("floatlessequal4", __LINE__);
02901     }
02902     if (*(output[outBoolC++].pData) != false) {
02903         fail("floatlessequal5", __LINE__);
02904     }
02905     if (*(output[outBoolC++].pData) != false) {
02906         fail("floatlessequal6", __LINE__);
02907     }
02908     if (*(output[outBoolC++].pData) != true) {
02909         fail("floatlessequal7", __LINE__);
02910     }
02911 
02912     if (output[outBoolC++].pData != NULL) {
02913         fail("floatlessequal8", __LINE__);
02914     }
02915     if (output[outBoolC++].pData != NULL) {
02916         fail("floatlessequal9", __LINE__);
02917     }
02918     if (output[outBoolC++].pData != NULL) {
02919         fail("floatlessequal10", __LINE__);
02920     }
02921 
02922     // isnull
02923     if (*(output[outBoolC++].pData) != false) {
02924         fail("floatisnull1", __LINE__);
02925     }
02926     if (*(output[outBoolC++].pData) != true) {
02927         fail("floatisnull2", __LINE__);
02928     }
02929 
02930     // isnotnull
02931     if (*(output[outBoolC++].pData) != true) {
02932         fail("floatisnotnull1", __LINE__);
02933     }
02934     if (*(output[outBoolC++].pData) != false) {
02935         fail("floatisnotnull2", __LINE__);
02936     }
02937 
02938     // tonull
02939     if (output[outC++].pData != NULL) {
02940         fail("floattonull1", __LINE__);
02941     }
02942 
02943 
02944     // return
02945     if (*(reinterpret_cast<const float *>(output[outC++].pData)) != 10) {
02946         fail("floatreturn", __LINE__);
02947     }
02948 
02949     cout << "Calculator Warnings: " << c.warnings() << endl;
02950 
02951     delete [] fInP;
02952     delete [] fOutP;
02953     delete [] fLoP;
02954     delete [] fLiP;
02955     delete [] bOutP;
02956 
02957     for (i = 0; i < lastPC; i++) {
02958         delete instP[i];
02959     }
02960     delete [] instP;
02961 
02962 }
02963 
02964 void
02965 unitTestPointer()
02966 {
02967     printf("=========================================================\n");
02968     printf("=========================================================\n");
02969     printf("=====\n");
02970     printf("=====     unitTestPointer()\n");
02971     printf("=====\n");
02972     printf("=========================================================\n");
02973     printf("=========================================================\n");
02974 
02975     bool isNullable = true;    // Can tuple contain nulls?
02976     int i, registersize = 100;
02977     static uint bufferlen = 8;
02978 
02979     TupleDescriptor tupleDesc;
02980     tupleDesc.clear();
02981 
02982     // Build up a description of what we'd like the tuple to look like
02983     StandardTypeDescriptorFactory typeFactory;
02984     int idx = 0;
02985 
02986     const int pointerIdx = idx;
02987     for (i = 0;i < registersize; i++) {
02988         // pointers in first "half"
02989         StoredTypeDescriptor const &typeDesc =
02990             typeFactory.newDataType(STANDARD_TYPE_VARCHAR);
02991         // tell descriptor the size
02992         tupleDesc.push_back(
02993             TupleAttributeDescriptor(
02994                 typeDesc,
02995                 isNullable,
02996                 bufferlen));
02997         idx++;
02998     }
02999     const int ulongIdx = idx;
03000     for (i = 0;i < registersize; i++) {
03001         // unsigned longs in third "half"
03002         // will serve as PointerSizeT
03003         StoredTypeDescriptor const &typeDesc =
03004             typeFactory.newDataType(STANDARD_TYPE_UINT_32);
03005         tupleDesc.push_back(TupleAttributeDescriptor(typeDesc, isNullable));
03006         idx++;
03007     }
03008     const int boolIdx = idx;
03009     for (i = 0;i < registersize; i++) {
03010         // booleans in fourth "half"
03011         StoredTypeDescriptor const &typeDesc =
03012             typeFactory.newDataType(STANDARD_TYPE_UINT_8);
03013         tupleDesc.push_back(TupleAttributeDescriptor(typeDesc, isNullable));
03014         idx++;
03015     }
03016 
03017     // Create a tuple accessor from the description
03018     //
03019     // Note: Must use a NOT_NULL_AND_FIXED accessor when creating a tuple out
03020     // of the air like this, otherwise unmarshal() does not know what to do. If
03021     // you need a STANDARD type tuple that supports nulls, it has to be built
03022     // as a copy.
03023     TupleAccessor tupleAccessorFixedLiteral;
03024     TupleAccessor tupleAccessorFixedInput;
03025     TupleAccessor tupleAccessorFixedOutput;
03026     TupleAccessor tupleAccessorFixedLocal;
03027     TupleAccessor tupleAccessorFixedStatus;
03028     tupleAccessorFixedLiteral.compute(tupleDesc, TUPLE_FORMAT_ALL_FIXED);
03029     tupleAccessorFixedInput.compute(tupleDesc, TUPLE_FORMAT_ALL_FIXED);
03030     tupleAccessorFixedOutput.compute(tupleDesc, TUPLE_FORMAT_ALL_FIXED);
03031     tupleAccessorFixedLocal.compute(tupleDesc, TUPLE_FORMAT_ALL_FIXED);
03032     tupleAccessorFixedStatus.compute(tupleDesc, TUPLE_FORMAT_ALL_FIXED);
03033 
03034     // Allocate memory for the tuple
03035     boost::scoped_array<FixedBuffer> pTupleBufFixedLiteral(
03036         new FixedBuffer[tupleAccessorFixedLiteral.getMaxByteCount()]);
03037     boost::scoped_array<FixedBuffer> pTupleBufFixedInput(
03038         new FixedBuffer[tupleAccessorFixedInput.getMaxByteCount()]);
03039     boost::scoped_array<FixedBuffer> pTupleBufFixedOutput(
03040         new FixedBuffer[tupleAccessorFixedOutput.getMaxByteCount()]);
03041     boost::scoped_array<FixedBuffer> pTupleBufFixedLocal(
03042         new FixedBuffer[tupleAccessorFixedLocal.getMaxByteCount()]);
03043     boost::scoped_array<FixedBuffer> pTupleBufFixedStatus(
03044         new FixedBuffer[tupleAccessorFixedStatus.getMaxByteCount()]);
03045 
03046     // Link memory to accessor
03047     tupleAccessorFixedLiteral.setCurrentTupleBuf(
03048         pTupleBufFixedLiteral.get(), false);
03049     tupleAccessorFixedInput.setCurrentTupleBuf(
03050         pTupleBufFixedInput.get(), false);
03051     tupleAccessorFixedOutput.setCurrentTupleBuf(
03052         pTupleBufFixedOutput.get(), false);
03053     tupleAccessorFixedLocal.setCurrentTupleBuf(
03054         pTupleBufFixedLocal.get(), false);
03055     tupleAccessorFixedStatus.setCurrentTupleBuf(
03056         pTupleBufFixedStatus.get(), false);
03057 
03058     // Create a vector of TupleDatum objects based on the description we built
03059     TupleData tupleDataFixedLiteral(tupleDesc);
03060     TupleData tupleDataFixedInput(tupleDesc);
03061     TupleData tupleDataFixedOutput(tupleDesc);
03062     TupleData tupleDataFixedLocal(tupleDesc);
03063     TupleData tupleDataFixedStatus(tupleDesc);
03064 
03065     // Do something mysterious. Probably binding pointers in the accessor to
03066     // items in the TupleData vector
03067     tupleAccessorFixedLiteral.unmarshal(tupleDataFixedLiteral);
03068     tupleAccessorFixedInput.unmarshal(tupleDataFixedInput);
03069     tupleAccessorFixedOutput.unmarshal(tupleDataFixedOutput);
03070     tupleAccessorFixedLocal.unmarshal(tupleDataFixedLocal);
03071     tupleAccessorFixedStatus.unmarshal(tupleDataFixedStatus);
03072 
03073     // create four nullable tuples to serve as register sets
03074     TupleData literal = tupleDataFixedLiteral;
03075     TupleData input = tupleDataFixedInput;
03076     TupleData output = tupleDataFixedOutput;
03077     TupleData local = tupleDataFixedLocal;
03078     TupleData status = tupleDataFixedStatus;
03079 
03080 
03081     TupleData::iterator itr;
03082 
03083     // Set up some useful literals
03084     itr = literal.begin();
03085     for (i = 0; i < registersize; i++, itr++) {
03086         char num[16];
03087         sprintf(num, "%04d", i);
03088         char* ptr = reinterpret_cast<char *>(const_cast<PBuffer>(itr->pData));
03089         memset(ptr, 'C', bufferlen); // VARCHAR is not null terminated
03090         memcpy(ptr, num, 4); // copy number, but not null
03091     }
03092     for (i = 0; i < registersize; i++, itr++) {
03093         *(reinterpret_cast<uint32_t *>(const_cast<PBuffer>(itr->pData))) = i;
03094     }
03095     for (i = 0; i < registersize; i++, itr++) {
03096         *(reinterpret_cast<bool *>(const_cast<PBuffer>(itr->pData))) = false;
03097     }
03098 
03099     // Put some data other tuples as well
03100     itr = input.begin();
03101     for (i = 0; i < registersize; i++, itr++) {
03102         char num[16];
03103         sprintf(num, "%04d", i);
03104         char *ptr = reinterpret_cast<char *>(const_cast<PBuffer>(itr->pData));
03105         memset(ptr, 'I', bufferlen); // VARCHAR is not null terminated
03106         memcpy(ptr, num, 4); // copy number, but not null
03107     }
03108     for (i = 0; i < registersize; i++, itr++) {
03109         *(reinterpret_cast<uint32_t *>(const_cast<PBuffer>(itr->pData))) = 0;
03110     }
03111     for (i = 0; i < registersize; i++, itr++) {
03112         *(reinterpret_cast<bool *>(const_cast<PBuffer>(itr->pData))) = false;
03113     }
03114     itr = output.begin();
03115     for (i = 0; i < registersize; i++, itr++) {
03116         char* ptr = reinterpret_cast<char *>(const_cast<PBuffer>(itr->pData));
03117         memset(ptr, 'O', bufferlen); // VARCHAR is not null terminated
03118     }
03119     for (i = 0; i < registersize; i++, itr++) {
03120         *(reinterpret_cast<uint32_t *>(const_cast<PBuffer>(itr->pData))) = 0;
03121     }
03122     for (i = 0; i < registersize; i++, itr++) {
03123         *(reinterpret_cast<bool *>(const_cast<PBuffer>(itr->pData))) = false;
03124     }
03125     itr = local.begin();
03126     for (i = 0; i < registersize; i++, itr++) {
03127         char* ptr = reinterpret_cast<char *>(const_cast<PBuffer>(itr->pData));
03128         memset(ptr, 'L', bufferlen); // VARCHAR is not null terminated
03129     }
03130     for (i = 0; i < registersize; i++, itr++) {
03131         *(reinterpret_cast<uint32_t *>(const_cast<PBuffer>(itr->pData))) = 0;
03132     }
03133     for (i = 0; i < registersize; i++, itr++) {
03134         *(reinterpret_cast<bool *>(const_cast<PBuffer>(itr->pData))) = false;
03135     }
03136 
03137     // set up boolean literals
03138     int falseIdx = 0;
03139     int trueIdx = 1;
03140     *(reinterpret_cast<bool *>
03141       (const_cast<PBuffer>
03142        (literal[trueIdx + boolIdx].pData))) = true;
03143     *(reinterpret_cast<bool *>
03144       (const_cast<PBuffer>
03145        (literal[falseIdx + boolIdx].pData))) = false;
03146 
03147 
03148 
03149     // null out last element of each type
03150     int pointerNullIdx = pointerIdx + registersize - 1;
03151     int ulongNullIdx = ulongIdx + registersize - 1;
03152     int boolNullIdx = boolIdx + registersize - 1;
03153     literal[pointerNullIdx].pData = NULL;
03154     literal[ulongNullIdx].pData = NULL;
03155     literal[boolNullIdx].pData = NULL;
03156     literal[pointerNullIdx].cbData = 0;
03157     literal[ulongNullIdx].cbData = 0;
03158     literal[boolNullIdx].cbData = 0;
03159 
03160     input[pointerNullIdx].pData = NULL;
03161     input[ulongNullIdx].pData = NULL;
03162     input[boolNullIdx].pData = NULL;
03163     input[pointerNullIdx].cbData = 0;
03164     input[ulongNullIdx].cbData = 0;
03165     input[boolNullIdx].cbData = 0;
03166 
03167     output[pointerNullIdx].pData = NULL;
03168     output[ulongNullIdx].pData = NULL;
03169     output[boolNullIdx].pData = NULL;
03170     output[pointerNullIdx].cbData = 0;
03171     output[ulongNullIdx].cbData = 0;
03172     output[boolNullIdx].cbData = 0;
03173 
03174     local[pointerNullIdx].pData = NULL;
03175     local[ulongNullIdx].pData = NULL;
03176     local[boolNullIdx].pData = NULL;
03177     local[pointerNullIdx].cbData = 0;
03178     local[ulongNullIdx].cbData = 0;
03179     local[boolNullIdx].cbData = 0;
03180 
03181     // Print out the nullable tuple
03182     TuplePrinter tuplePrinter;
03183     printf("Literals\n");
03184     tuplePrinter.print(cout, tupleDesc, literal);
03185     cout << endl;
03186     printf("\nInput\n");
03187     tuplePrinter.print(cout, tupleDesc, input);
03188     cout << endl;
03189     printf("\nOutput\n");
03190     tuplePrinter.print(cout, tupleDesc, output);
03191     cout << endl;
03192     printf("\nLocal\n");
03193     tuplePrinter.print(cout, tupleDesc, local);
03194     cout << endl;
03195 
03196 
03197     // predefine register references. a real compiler wouldn't do
03198     // something so regular and pre-determined. a compiler would
03199     // probably build these on the fly as it built each instruction.
03200     // predefine register references. a real compiler wouldn't do
03201     // something so regular and pre-determined
03202     RegisterRef<char *> **cpInP, **cpOutP, **cpLoP, **cpLiP;
03203     RegisterRef<PointerOperandT> **lInP, **lOutP, **lLoP, **lLiP;
03204     RegisterRef<bool> **bInP, **bOutP, **bLoP, **bLiP;
03205 
03206     cpInP = new RegisterRef<char *>*[registersize];
03207     cpOutP = new RegisterRef<char *>*[registersize];
03208     cpLoP = new RegisterRef<char *>*[registersize];
03209     cpLiP = new RegisterRef<char *>*[registersize];
03210 
03211     lInP = new RegisterRef<PointerOperandT>*[registersize];
03212     lOutP = new RegisterRef<PointerOperandT>*[registersize];
03213     lLoP = new RegisterRef<PointerOperandT>*[registersize];
03214     lLiP = new RegisterRef<PointerOperandT>*[registersize];
03215 
03216     bInP = new RegisterRef<bool>*[registersize];
03217     bOutP = new RegisterRef<bool>*[registersize];
03218     bLoP = new RegisterRef<bool>*[registersize];
03219     bLiP = new RegisterRef<bool>*[registersize];
03220 
03221     // Set up the Calculator
03222     DynamicParamManager dpm;
03223     Calculator c(&dpm,0,0,0,0,0,0);
03224     c.outputRegisterByReference(false);
03225 
03226     // set up register references to symbolically point to
03227     // their corresponding storage locations -- makes for easy test case
03228     // generation. again, a compiler wouldn't do things in quite
03229     // this way.
03230     for (i = 0; i < registersize; i++) {
03231         cpInP[i] = new RegisterRef<char *>(
03232             RegisterReference::EInput,
03233             pointerIdx + i,
03234             STANDARD_TYPE_VARCHAR);
03235         c.appendRegRef(cpInP[i]);
03236         cpOutP[i] = new RegisterRef<char *>(
03237             RegisterReference::EOutput,
03238             pointerIdx + i,
03239             STANDARD_TYPE_VARCHAR);
03240         c.appendRegRef(cpOutP[i]);
03241         cpLoP[i] = new RegisterRef<char *>(
03242             RegisterReference::ELocal,
03243             pointerIdx + i,
03244             STANDARD_TYPE_VARCHAR);
03245         c.appendRegRef(cpLoP[i]);
03246         cpLiP[i] = new RegisterRef<char *>(
03247             RegisterReference::ELiteral,
03248             pointerIdx + i,
03249             STANDARD_TYPE_VARCHAR);
03250         c.appendRegRef(cpLiP[i]);
03251 
03252         lInP[i] = new RegisterRef<PointerOperandT>(
03253             RegisterReference::EInput,
03254             ulongIdx + i,
03255             STANDARD_TYPE_INT_32);
03256         c.appendRegRef(lInP[i]);
03257         lOutP[i] = new RegisterRef<PointerOperandT>(
03258             RegisterReference::EOutput,
03259             ulongIdx + i,
03260             STANDARD_TYPE_INT_32);
03261         c.appendRegRef(lOutP[i]);
03262         lLoP[i] = new RegisterRef<PointerOperandT>(
03263             RegisterReference::ELocal,
03264             ulongIdx + i,
03265             STANDARD_TYPE_INT_32);
03266         c.appendRegRef(lLoP[i]);
03267         lLiP[i] = new RegisterRef<PointerOperandT>(
03268             RegisterReference::ELiteral,
03269             ulongIdx + i,
03270             STANDARD_TYPE_INT_32);
03271         c.appendRegRef(lLiP[i]);
03272 
03273         bInP[i] = new RegisterRef<bool>(
03274             RegisterReference::EInput,
03275             boolIdx + i,
03276             STANDARD_TYPE_BOOL);
03277         c.appendRegRef(bInP[i]);
03278         bOutP[i] = new RegisterRef<bool>(
03279             RegisterReference::EOutput,
03280             boolIdx + i,
03281             STANDARD_TYPE_BOOL);
03282         c.appendRegRef(bOutP[i]);
03283         bLoP[i] = new RegisterRef<bool>(
03284             RegisterReference::ELocal,
03285             boolIdx + i,
03286             STANDARD_TYPE_BOOL);
03287         c.appendRegRef(bLoP[i]);
03288         bLiP[i] = new RegisterRef<bool>(
03289             RegisterReference::ELiteral,
03290             boolIdx + i,
03291             STANDARD_TYPE_BOOL);
03292         c.appendRegRef(bLiP[i]);
03293     }
03294 
03295     // Set up storage for instructions
03296     // a real compiler would probably cons up instructions and insert them
03297     // directly into the calculator. keep an array of the instructions at
03298     // this level to allow printing of the program after execution, and other
03299     // debugging
03300     Instruction **instP;
03301     instP = new InstructionPtr[200];
03302     int pc = 0, outCp = 0, outL = 0, outB = 0, localCp = 0;
03303     int nullRegister = registersize - 1;
03304 
03305     StandardTypeDescriptorOrdinal isVC = STANDARD_TYPE_VARCHAR;
03306 
03307     // add
03308     instP[pc++] = new PointerAdd<char *>(
03309         cpOutP[0], cpLiP[0], lLiP[0], isVC); // add 0
03310     instP[pc++] = new PointerAdd<char *>(
03311         cpOutP[1], cpLiP[1], lLiP[1], isVC); // add 1
03312     instP[pc++] = new PointerAdd<char *>(
03313         cpOutP[2], cpLiP[2], lLiP[2], isVC); // add 2
03314 
03315     outCp = 3;
03316     instP[pc++] = new PointerAdd<char *>(
03317         cpOutP[outCp++], cpLiP[nullRegister], lLiP[2], isVC);
03318     instP[pc++] = new PointerAdd<char *>(
03319         cpOutP[outCp++], cpLiP[0], lLiP[nullRegister], isVC);
03320     instP[pc++] = new PointerAdd<char *>(
03321         cpOutP[outCp++], cpLiP[nullRegister], lLiP[nullRegister], isVC);
03322 
03323     // sub
03324 
03325     // refer to previously added values in output buffer so that
03326     // results are always valid (as opposed to pointing before the
03327     // legally allocated strings
03328     instP[pc++] = new PointerSub<char *>(
03329         cpOutP[outCp++], cpLiP[0], lLiP[0], isVC);  // sub 0
03330     instP[pc++] = new PointerSub<char *>(
03331         cpOutP[outCp++], cpOutP[1], lLiP[1], isVC); // sub 1
03332     instP[pc++] = new PointerSub<char *>(
03333         cpOutP[outCp++], cpOutP[2], lLiP[2], isVC); // sub 2
03334 
03335     instP[pc++] = new PointerSub<char *>(
03336         cpOutP[outCp++], cpLiP[nullRegister], lLiP[2], isVC);
03337     instP[pc++] = new PointerSub<char *>(
03338         cpOutP[outCp++], cpLiP[0], lLiP[nullRegister], isVC);
03339     instP[pc++] = new PointerSub<char *>(
03340         cpOutP[outCp++], cpLiP[nullRegister], lLiP[nullRegister], isVC);
03341 
03342     // move
03343     instP[pc++] = new PointerMove<char *>(
03344         cpOutP[outCp++], cpLiP[2], isVC);
03345     instP[pc++] = new PointerMove<char *>(
03346         cpOutP[outCp++], cpLiP[nullRegister], isVC);
03347     // move a valid pointer over a null pointer
03348     instP[pc++] = new PointerMove<char *>(
03349         cpOutP[outCp], cpLiP[nullRegister], isVC);
03350     instP[pc++] = new PointerMove<char *>(
03351         cpOutP[outCp++], cpLiP[3], isVC);
03352     // move a null pointer to a null pointer
03353     instP[pc++] = new PointerMove<char *>(
03354         cpOutP[outCp], cpLiP[nullRegister], isVC);
03355     instP[pc++] = new PointerMove<char *>(
03356         cpOutP[outCp++], cpLiP[nullRegister], isVC);
03357 
03358     // equal
03359     instP[pc++] = new BoolPointerEqual<char *>(
03360         bOutP[outB++], cpLiP[0], cpLiP[0], isVC);
03361     instP[pc++] = new BoolPointerEqual<char *>(
03362         bOutP[outB++], cpLiP[0], cpLiP[1], isVC);
03363     instP[pc++] = new BoolPointerEqual<char *>(
03364         bOutP[outB++], cpLiP[1], cpLiP[0], isVC);
03365     instP[pc++] = new BoolPointerEqual<char *>(
03366         bOutP[outB++], cpLiP[nullRegister], cpLiP[1], isVC);
03367     instP[pc++] = new BoolPointerEqual<char *>(
03368         bOutP[outB++], cpLiP[0], cpLiP[nullRegister], isVC);
03369     instP[pc++] = new BoolPointerEqual<char *>(
03370         bOutP[outB++], cpLiP[nullRegister], cpLiP[nullRegister], isVC);
03371 
03372     // notequal
03373     instP[pc++] = new BoolPointerNotEqual<char *>(
03374         bOutP[outB++], cpLiP[0], cpLiP[0], isVC);
03375     instP[pc++] = new BoolPointerNotEqual<char *>(
03376         bOutP[outB++], cpLiP[0], cpLiP[1], isVC);
03377     instP[pc++] = new BoolPointerNotEqual<char *>(
03378         bOutP[outB++], cpLiP[1], cpLiP[0], isVC);
03379     instP[pc++] = new BoolPointerNotEqual<char *>(
03380         bOutP[outB++], cpLiP[nullRegister], cpLiP[1], isVC);
03381     instP[pc++] = new BoolPointerNotEqual<char *>(
03382         bOutP[outB++], cpLiP[0], cpLiP[nullRegister], isVC);
03383     instP[pc++] = new BoolPointerNotEqual<char *>(
03384         bOutP[outB++], cpLiP[nullRegister], cpLiP[nullRegister], isVC);
03385 
03386     // greater
03387     // assume that values allocated later are larger
03388     assert(output[pointerIdx].pData < output[pointerIdx + 1].pData);
03389     instP[pc++] = new BoolPointerGreater<char *>(
03390         bOutP[outB++], cpLiP[0], cpLiP[0], isVC);
03391     instP[pc++] = new BoolPointerGreater<char *>(
03392         bOutP[outB++], cpLiP[0], cpLiP[1], isVC);
03393     instP[pc++] = new BoolPointerGreater<char *>(
03394         bOutP[outB++], cpLiP[1], cpLiP[0], isVC);
03395 
03396     instP[pc++] = new BoolPointerGreater<char *>(
03397         bOutP[outB++], cpLiP[nullRegister], cpLiP[1], isVC);
03398     instP[pc++] = new BoolPointerGreater<char *>(
03399         bOutP[outB++], cpLiP[0], cpLiP[nullRegister], isVC);
03400     instP[pc++] = new BoolPointerGreater<char *>(
03401         bOutP[outB++], cpLiP[nullRegister], cpLiP[nullRegister], isVC);
03402 
03403     // greaterequal
03404     // assume that values allocated later are larger
03405     assert(output[pointerIdx].pData < output[pointerIdx + 1].pData);
03406     instP[pc++] = new BoolPointerGreaterEqual<char *>(
03407         bOutP[outB++], cpLiP[0], cpLiP[0], isVC);
03408     instP[pc++] = new BoolPointerGreaterEqual<char *>(
03409         bOutP[outB++], cpLiP[0], cpLiP[1], isVC);
03410     instP[pc++] = new BoolPointerGreaterEqual<char *>(
03411         bOutP[outB++], cpLiP[1], cpLiP[0], isVC);
03412 
03413     instP[pc++] = new BoolPointerGreaterEqual<char *>(
03414         bOutP[outB++], cpLiP[nullRegister], cpLiP[1], isVC);
03415     instP[pc++] = new BoolPointerGreaterEqual<char *>(
03416         bOutP[outB++], cpLiP[0], cpLiP[nullRegister], isVC);
03417     instP[pc++] = new BoolPointerGreaterEqual<char *>(
03418         bOutP[outB++], cpLiP[nullRegister], cpLiP[nullRegister], isVC);
03419 
03420     // less
03421     // assume that values allocated later are larger
03422     assert(output[pointerIdx].pData < output[pointerIdx + 1].pData);
03423     instP[pc++] = new BoolPointerLess<char *>(
03424         bOutP[outB++], cpLiP[0], cpLiP[0], isVC);
03425     instP[pc++] = new BoolPointerLess<char *>(
03426         bOutP[outB++], cpLiP[0], cpLiP[1], isVC);
03427     instP[pc++] = new BoolPointerLess<char *>(
03428         bOutP[outB++], cpLiP[1], cpLiP[0], isVC);
03429     instP[pc++] = new BoolPointerLess<char *>(
03430         bOutP[outB++], cpLiP[nullRegister], cpLiP[1], isVC);
03431     instP[pc++] = new BoolPointerLess<char *>(
03432         bOutP[outB++], cpLiP[0], cpLiP[nullRegister], isVC);
03433     instP[pc++] = new BoolPointerLess<char *>(
03434         bOutP[outB++], cpLiP[nullRegister], cpLiP[nullRegister], isVC);
03435 
03436     // lessequal
03437     // assume that values allocated later are larger
03438     assert(output[pointerIdx].pData < output[pointerIdx + 1].pData);
03439     instP[pc++] = new BoolPointerLessEqual<char *>(
03440         bOutP[outB++], cpLiP[0], cpLiP[0], isVC);
03441     instP[pc++] = new BoolPointerLessEqual<char *>(
03442         bOutP[outB++], cpLiP[0], cpLiP[1], isVC);
03443     instP[pc++] = new BoolPointerLessEqual<char *>(
03444         bOutP[outB++], cpLiP[1], cpLiP[0], isVC);
03445     instP[pc++] = new BoolPointerLessEqual<char *>(
03446         bOutP[outB++], cpLiP[nullRegister], cpLiP[1], isVC);
03447     instP[pc++] = new BoolPointerLessEqual<char *>(
03448         bOutP[outB++], cpLiP[0], cpLiP[nullRegister], isVC);
03449     instP[pc++] = new BoolPointerLessEqual<char *>(
03450         bOutP[outB++], cpLiP[nullRegister], cpLiP[nullRegister], isVC);
03451 
03452     // isnull
03453     instP[pc++] = new BoolPointerIsNull<char *>(
03454         bOutP[outB++], cpLiP[0], isVC);
03455     instP[pc++] = new BoolPointerIsNull<char *>(
03456         bOutP[outB++], cpLiP[nullRegister], isVC);
03457 
03458     // isnotnull
03459     instP[pc++] = new BoolPointerIsNotNull<char *>(
03460         bOutP[outB++], cpLiP[0], isVC);
03461     instP[pc++] = new BoolPointerIsNotNull<char *>(
03462         bOutP[outB++], cpLiP[nullRegister], isVC);
03463 
03464     // tonull
03465     instP[pc++] = new PointerToNull<char *>(cpOutP[outCp++], isVC);
03466 
03467     // putsize
03468     instP[pc++] = new PointerPutSize<char *>(cpOutP[outCp], lLiP[0], isVC);
03469     instP[pc++] = new PointerPutSize<char *>(cpOutP[outCp+1], lLiP[1], isVC);
03470     instP[pc++] = new PointerPutSize<char *>(cpOutP[outCp+2], lLiP[2], isVC);
03471     // putsize w/round trip through cached register set
03472     instP[pc++] = new PointerPutSize<char *>(cpLoP[localCp], lLiP[0], isVC);
03473 
03474     // getsize
03475     instP[pc++] = new PointerGetSize<char *>(
03476         lOutP[outL++], cpOutP[outCp], isVC);
03477     instP[pc++] = new PointerGetSize<char *>(
03478         lOutP[outL++], cpOutP[outCp + 1], isVC);
03479     instP[pc++] = new PointerGetSize<char *>(
03480         lOutP[outL++], cpOutP[outCp + 2], isVC);
03481     instP[pc++] = new PointerGetSize<char *>(
03482         lOutP[outL++], cpLiP[0], isVC);
03483     // getsize w/round trip through cached register set
03484     instP[pc++] = new PointerGetSize<char *>(
03485         lOutP[outL++], cpLoP[localCp], isVC);
03486     instP[pc++] = new PointerGetSize<char *>(
03487         lOutP[outL++], cpLoP[localCp + 1], isVC);
03488 
03489     // getmaxsize
03490     instP[pc++] = new PointerGetMaxSize<char *>(
03491         lOutP[outL++], cpOutP[outCp], isVC);
03492     instP[pc++] = new PointerGetMaxSize<char *>(
03493         lOutP[outL++], cpLiP[0], isVC);
03494     // getmaxsize w/round trip through cached register set
03495     instP[pc++] = new PointerGetMaxSize<char *>(
03496         lOutP[outL++], cpLoP[localCp], isVC);
03497     instP[pc++] = new PointerGetMaxSize<char *>(
03498         lOutP[outL++], cpLoP[localCp + 1], isVC);
03499 
03500     outCp += 3;
03501     localCp += 2;
03502 
03503     instP[pc++] = new ReturnInstruction();
03504     int lastPC = pc;
03505 
03506     for (i = 0; i < pc; i++) {
03507         c.appendInstruction(instP[i]);
03508     }
03509 
03510     c.bind(
03511         RegisterReference::ELiteral,
03512         &literal,
03513         tupleDesc);
03514     c.bind(
03515         RegisterReference::EInput,
03516         &input,
03517         tupleDesc);
03518     c.bind(
03519         RegisterReference::EOutput,
03520         &output,
03521         tupleDesc);
03522     c.bind(
03523         RegisterReference::ELocal,
03524         &local,
03525         tupleDesc);
03526     c.bind(
03527         RegisterReference::EStatus,
03528         &status,
03529         tupleDesc);
03530     c.exec();
03531 
03532     string out;
03533     for (i = 0; i < pc; i++) {
03534         instP[i]->describe(out, true);
03535         printf("[%2d] %s\n", i, out.c_str());
03536     }
03537 
03538     // Print out the output tuple
03539     printf("Output Tuple\n");
03540     tuplePrinter.print(cout, tupleDesc, output);
03541     cout << endl;
03542 
03543     outCp = 0;       // now indexes into output tuple, not outputregisterref
03544     outB = boolIdx;  // now indexes into output tuple, not outputregisterref
03545     outL = ulongIdx; // now indexes into output tuple, not outputregisterref
03546 
03547     // add
03548     if (output[outCp].pData != literal[pointerIdx + 0].pData) {
03549         fail("pointeradd1", __LINE__);
03550     }
03551     if (output[outCp++].cbData != bufferlen - 0) {
03552         fail("pointeradd2", __LINE__);
03553     }
03554 
03555     if ((reinterpret_cast<const char *>(output[outCp].pData)) !=
03556         ((reinterpret_cast<const char *>(literal[pointerIdx + 1].pData)) +
03557          *(reinterpret_cast<const int32_t *>(literal[ulongIdx + 1].pData))))
03558         {
03559         fail("pointeradd3", __LINE__);
03560         }
03561     if (output[outCp++].cbData !=
03562         bufferlen - *(reinterpret_cast<const int32_t *>(
03563             literal[ulongIdx + 1].pData)))
03564     {
03565         fail("pointeradd4", __LINE__);
03566     }
03567 
03568     if ((reinterpret_cast<const char *>(output[outCp].pData)) !=
03569         ((reinterpret_cast<const char *>(literal[pointerIdx + 2].pData)) +
03570          *(reinterpret_cast<const int32_t *>(literal[ulongIdx + 2].pData))))
03571         {
03572         fail("pointeradd5", __LINE__);
03573         }
03574     if (output[outCp++].cbData !=
03575         bufferlen - *(reinterpret_cast<const int32_t *>(
03576             literal[ulongIdx + 2].pData)))
03577     {
03578         fail("pointeradd6", __LINE__);
03579     }
03580 
03581     if (output[outCp].pData != NULL) {
03582         fail("pointeradd7", __LINE__);
03583     }
03584     if (output[outCp++].cbData != 0) {
03585         fail("pointeradd8", __LINE__);
03586     }
03587     if (output[outCp].pData != NULL) {
03588         fail("pointeradd9", __LINE__);
03589     }
03590     if (output[outCp++].cbData != 0) {
03591         fail("pointeradd10", __LINE__);
03592     }
03593     if (output[outCp].pData != NULL) {
03594         fail("pointeradd11", __LINE__);
03595     }
03596     if (output[outCp++].cbData != 0) {
03597         fail("pointeradd12", __LINE__);
03598     }
03599 
03600     // sub
03601     if (output[outCp].pData != literal[pointerIdx + 0].pData) {
03602         fail("pointersub1", __LINE__);
03603     }
03604     if (output[outCp++].cbData != bufferlen + 0) {
03605         fail("pointersub2", __LINE__);
03606     }
03607 
03608     if ((reinterpret_cast<const char *>(output[outCp].pData)) !=
03609         ((reinterpret_cast<const char *>(literal[pointerIdx + 1].pData))))
03610         {
03611         fail("pointersub3", __LINE__);
03612         }
03613     if (output[outCp++].cbData != bufferlen) {
03614         fail("pointersub4", __LINE__);
03615     }
03616 
03617     if ((reinterpret_cast<const char *>(output[outCp].pData)) !=
03618         ((reinterpret_cast<const char *>(literal[pointerIdx + 2].pData))))
03619         {
03620         fail("pointersub5", __LINE__);
03621         }
03622     if (output[outCp++].cbData != bufferlen) {
03623         fail("pointersub6", __LINE__);
03624     }
03625 
03626     if (output[outCp].pData != NULL) {
03627         fail("pointersub7", __LINE__);
03628     }
03629     if (output[outCp++].cbData != 0) {
03630         fail("pointersub8", __LINE__);
03631     }
03632     if (output[outCp].pData != NULL) {
03633         fail("pointersub9", __LINE__);
03634     }
03635     if (output[outCp++].cbData != 0) {
03636         fail("pointersub10", __LINE__);
03637     }
03638     if (output[outCp].pData != NULL) {
03639         fail("pointersub11", __LINE__);
03640     }
03641     if (output[outCp++].cbData != 0) {
03642         fail("pointersub12", __LINE__);
03643     }
03644 
03645     // move
03646     if (output[outCp].pData != literal[pointerIdx + 2].pData) {
03647         fail("pointermove1", __LINE__);
03648     }
03649     if (output[outCp++].cbData != bufferlen) {
03650         fail("pointermove2", __LINE__);
03651     }
03652 
03653     if (output[outCp].pData != NULL) {
03654         fail("pointermove3", __LINE__);
03655     }
03656     if (output[outCp++].cbData != 0) {
03657         fail("pointermove4", __LINE__);
03658     }
03659 
03660     if ((reinterpret_cast<const char *>(output[outCp].pData)) !=
03661         ((reinterpret_cast<const char *>(literal[pointerIdx + 3].pData))))
03662         {
03663         fail("pointermove5", __LINE__);
03664         }
03665     if (output[outCp++].cbData != bufferlen) {
03666         fail("pointermove6", __LINE__);
03667     }
03668 
03669     if (output[outCp].pData != NULL) {
03670         fail("pointermove7", __LINE__);
03671     }
03672     if (output[outCp++].cbData != 0) {
03673         fail("pointermove8", __LINE__);
03674     }
03675 
03676 
03677     // equal
03678     if (*(output[outB++].pData) != true) {
03679         fail("pointerequal1", __LINE__);
03680     }
03681     if (*(output[outB++].pData) != false) {
03682         fail("pointerequal2", __LINE__);
03683     }
03684     if (*(output[outB++].pData) != false) {
03685         fail("pointerequal3", __LINE__);
03686     }
03687 
03688     if (output[outB++].pData != NULL) {
03689         fail("pointerequal4", __LINE__);
03690     }
03691     if (output[outB++].pData != NULL) {
03692         fail("pointerequal5", __LINE__);
03693     }
03694     if (output[outB++].pData != NULL) {
03695         fail("pointerequal6", __LINE__);
03696     }
03697 
03698     // notequal
03699     if (*(output[outB++].pData) != false) {
03700         fail("pointernotequal1", __LINE__);
03701     }
03702     if (*(output[outB++].pData) != true) {
03703         fail("pointernotequal2", __LINE__);
03704     }
03705     if (*(output[outB++].pData) != true) {
03706         fail("pointernotequal3", __LINE__);
03707     }
03708 
03709     if (output[outB++].pData != NULL) {
03710         fail("pointernotequal4", __LINE__);
03711     }
03712     if (output[outB++].pData != NULL) {
03713         fail("pointernotequal5", __LINE__);
03714     }
03715     if (output[outB++].pData != NULL) {
03716         fail("pointernotequal6", __LINE__);
03717     }
03718 
03719     // greater
03720     if (*(output[outB++].pData) != false) {
03721         fail("pointergreater1", __LINE__);
03722     }
03723     if (*(output[outB++].pData) != false) {
03724         fail("pointergreater2", __LINE__);
03725     }
03726     if (*(output[outB++].pData) != true) {
03727         fail("pointergreater3", __LINE__);
03728     }
03729 
03730     if (output[outB++].pData != NULL) {
03731         fail("pointergreater11", __LINE__);
03732     }
03733     if (output[outB++].pData != NULL) {
03734         fail("pointergreater12", __LINE__);
03735     }
03736     if (output[outB++].pData != NULL) {
03737         fail("pointergreater13", __LINE__);
03738     }
03739 
03740     // greaterequal
03741     if (*(output[outB++].pData) != true) {
03742         fail("pointergreaterequal1", __LINE__);
03743     }
03744     if (*(output[outB++].pData) != false) {
03745         fail("pointergreaterequal2", __LINE__);
03746     }
03747     if (*(output[outB++].pData) != true) {
03748         fail("pointergreaterequal3", __LINE__);
03749     }
03750 
03751     if (output[outB++].pData != NULL) {
03752         fail("pointergreaterequal14", __LINE__);
03753     }
03754     if (output[outB++].pData != NULL) {
03755         fail("pointergreaterequal15", __LINE__);
03756     }
03757     if (output[outB++].pData != NULL) {
03758         fail("pointergreaterequal16", __LINE__);
03759     }
03760 
03761     // less
03762     if (*(output[outB++].pData) != false) {
03763         fail("pointerless1", __LINE__);
03764     }
03765     if (*(output[outB++].pData) != true) {
03766         fail("pointerless2", __LINE__);
03767     }
03768     if (*(output[outB++].pData) != false) {
03769         fail("pointerless3", __LINE__);
03770     }
03771 
03772     if (output[outB++].pData != NULL) {
03773         fail("pointerless4", __LINE__);
03774     }
03775     if (output[outB++].pData != NULL) {
03776         fail("pointerless5", __LINE__);
03777     }
03778     if (output[outB++].pData != NULL) {
03779         fail("pointerless6", __LINE__);
03780     }
03781 
03782     // lessequal
03783     if (*(output[outB++].pData) != true) {
03784         fail("pointerlessequal1", __LINE__);
03785     }
03786     if (*(output[outB++].pData) != true) {
03787         fail("pointerlessequal2", __LINE__);
03788     }
03789     if (*(output[outB++].pData) != false) {
03790         fail("pointerlessequal3", __LINE__);
03791     }
03792 
03793     if (output[outB++].pData != NULL) {
03794         fail("pointerlessequal5", __LINE__);
03795     }
03796     if (output[outB++].pData != NULL) {
03797         fail("pointerlessequal6", __LINE__);
03798     }
03799     if (output[outB++].pData != NULL) {
03800         fail("pointerlessequal7", __LINE__);
03801     }
03802 
03803     // isnull
03804     if (*(output[outB++].pData) != false) {
03805         fail("pointerisnull1", __LINE__);
03806     }
03807     if (*(output[outB++].pData) != true) {
03808         fail("pointerisnull2", __LINE__);
03809     }
03810 
03811     // isnotnull
03812     if (*(output[outB++].pData) != true) {
03813         fail("pointerisnotnull1", __LINE__);
03814     }
03815     if (*(output[outB++].pData) != false) {
03816         fail("pointerisnotnull2", __LINE__);
03817     }
03818 
03819     // tonull
03820     if (output[outCp].pData != NULL) {
03821         fail("pointertonull1", __LINE__);
03822     }
03823     if (output[outCp++].cbData != 0) {
03824         fail("pointertonull2", __LINE__);
03825     }
03826 
03827     // putsize
03828     // getsize
03829     if (*(output[outL++].pData) != 0) {
03830         fail("pointergetsize1", __LINE__);
03831     }
03832     if (*(output[outL++].pData) != 1) {
03833         fail("pointergetsize2", __LINE__);
03834     }
03835     if (*(output[outL++].pData) != 2) {
03836         fail("pointergetsize3", __LINE__);
03837     }
03838     if (*(output[outL++].pData) != bufferlen) {
03839         fail("pointergetsize4", __LINE__);
03840     }
03841     if (*(output[outL++].pData) != 0) {
03842         fail("pointergetsize5", __LINE__);
03843     }
03844     if (*(output[outL++].pData) != bufferlen) {
03845         fail("pointergetsize6", __LINE__);
03846     }
03847 
03848     // getmaxsize
03849     if (*(output[outL++].pData) != bufferlen) {
03850         fail("pointergetsize7", __LINE__);
03851     }
03852     if (*(output[outL++].pData) != bufferlen) {
03853         fail("pointergetsize8", __LINE__);
03854     }
03855     if (*(output[outL++].pData) != bufferlen) {
03856         fail("pointergetsize9", __LINE__);
03857     }
03858     if (*(output[outL++].pData) != bufferlen) {
03859         fail("pointergetsize10", __LINE__);
03860     }
03861 
03862 
03863     cout << "Calculator Warnings: " << c.warnings() << endl;
03864 
03865     delete [] cpInP;
03866     delete [] cpOutP;
03867     delete [] cpLoP;
03868     delete [] cpLiP;
03869     delete [] lInP;
03870     delete [] lOutP;
03871     delete [] lLoP;
03872     delete [] lLiP;
03873     delete [] bInP;
03874     delete [] bOutP;
03875     delete [] bLoP;
03876     delete [] bLiP;
03877     for (i = 0; i < lastPC; i++) {
03878         delete instP[i];
03879     }
03880     delete [] instP;
03881 }
03882 
03883 void
03884 unitTestWarnings()
03885 {
03886     printf("=========================================================\n");
03887     printf("=========================================================\n");
03888     printf("=====\n");
03889     printf("=====     unitTestWarnings()\n");
03890     printf("=====\n");
03891     printf("=========================================================\n");
03892     printf("=========================================================\n");
03893 
03894     bool isNullable = true;    // Can tuple contain nulls?
03895     int i, registersize = 3;
03896 
03897     TupleDescriptor tupleDesc;
03898     tupleDesc.clear();
03899 
03900     // Build up a description of what we'd like the tuple to look like
03901     StandardTypeDescriptorFactory typeFactory;
03902     int idx = 0;
03903 
03904     int floatIdx = idx;
03905     for (i = 0;i < registersize; i++) {
03906         // floats
03907         StoredTypeDescriptor const &typeDesc =
03908             typeFactory.newDataType(STANDARD_TYPE_REAL);
03909         tupleDesc.push_back(TupleAttributeDescriptor(typeDesc, isNullable));
03910         idx++;
03911     }
03912 
03913     // Create a tuple accessor from the description
03914     //
03915     // Note: Must use a NOT_NULL_AND_FIXED accessor when creating a tuple out
03916     // of the air like this, otherwise unmarshal() does not know what to do. If
03917     // you need a STANDARD type tuple that supports nulls, it has to be built
03918     // as a copy.
03919     TupleAccessor tupleAccessorFixedLiteral;
03920     TupleAccessor tupleAccessorFixedInput;
03921     TupleAccessor tupleAccessorFixedOutput;
03922     TupleAccessor tupleAccessorFixedLocal;
03923     TupleAccessor tupleAccessorFixedStatus;
03924     tupleAccessorFixedLiteral.compute(tupleDesc, TUPLE_FORMAT_ALL_FIXED);
03925     tupleAccessorFixedInput.compute(tupleDesc, TUPLE_FORMAT_ALL_FIXED);
03926     tupleAccessorFixedOutput.compute(tupleDesc, TUPLE_FORMAT_ALL_FIXED);
03927     tupleAccessorFixedLocal.compute(tupleDesc, TUPLE_FORMAT_ALL_FIXED);
03928     tupleAccessorFixedStatus.compute(tupleDesc, TUPLE_FORMAT_ALL_FIXED);
03929 
03930     // Allocate memory for the tuple
03931     boost::scoped_array<FixedBuffer> pTupleBufFixedLiteral(
03932         new FixedBuffer[tupleAccessorFixedLiteral.getMaxByteCount()]);
03933     boost::scoped_array<FixedBuffer> pTupleBufFixedInput(
03934         new FixedBuffer[tupleAccessorFixedInput.getMaxByteCount()]);
03935     boost::scoped_array<FixedBuffer> pTupleBufFixedOutput(
03936         new FixedBuffer[tupleAccessorFixedOutput.getMaxByteCount()]);
03937     boost::scoped_array<FixedBuffer> pTupleBufFixedLocal(
03938         new FixedBuffer[tupleAccessorFixedLocal.getMaxByteCount()]);
03939     boost::scoped_array<FixedBuffer> pTupleBufFixedStatus(
03940         new FixedBuffer[tupleAccessorFixedStatus.getMaxByteCount()]);
03941 
03942     // Link memory to accessor
03943     tupleAccessorFixedLiteral.setCurrentTupleBuf(
03944         pTupleBufFixedLiteral.get(), false);
03945     tupleAccessorFixedInput.setCurrentTupleBuf(
03946         pTupleBufFixedInput.get(), false);
03947     tupleAccessorFixedOutput.setCurrentTupleBuf(
03948         pTupleBufFixedOutput.get(), false);
03949     tupleAccessorFixedLocal.setCurrentTupleBuf(
03950         pTupleBufFixedLocal.get(), false);
03951     tupleAccessorFixedStatus.setCurrentTupleBuf(
03952         pTupleBufFixedStatus.get(), false);
03953 
03954     // Create a vector of TupleDatum objects based on the description we built
03955     TupleData tupleDataFixedLiteral(tupleDesc);
03956     TupleData tupleDataFixedInput(tupleDesc);
03957     TupleData tupleDataFixedOutput(tupleDesc);
03958     TupleData tupleDataFixedLocal(tupleDesc);
03959     TupleData tupleDataFixedStatus(tupleDesc);
03960 
03961     // Do something mysterious. Probably binding pointers in the accessor to
03962     // items in the TupleData vector
03963     tupleAccessorFixedLiteral.unmarshal(tupleDataFixedLiteral);
03964     tupleAccessorFixedInput.unmarshal(tupleDataFixedInput);
03965     tupleAccessorFixedOutput.unmarshal(tupleDataFixedOutput);
03966     tupleAccessorFixedLocal.unmarshal(tupleDataFixedLocal);
03967     tupleAccessorFixedStatus.unmarshal(tupleDataFixedStatus);
03968 
03969     // create four nullable tuples to serve as register sets
03970     TupleData literal = tupleDataFixedLiteral;
03971     TupleData input = tupleDataFixedInput;
03972     TupleData output = tupleDataFixedOutput;
03973     TupleData local = tupleDataFixedLocal;
03974     TupleData status = tupleDataFixedStatus;
03975 
03976     // Set up some useful literals
03977     for (i = 0; i < registersize; i++) {
03978         *(reinterpret_cast<float *>(const_cast<PBuffer>(literal[i].pData))) =
03979             i * 0.5;
03980         *(reinterpret_cast<float *>(const_cast<PBuffer>(output[i].pData))) =
03981             i * 2 + 1;
03982         *(reinterpret_cast<float *>(const_cast<PBuffer>(input[i].pData))) =
03983             i * 5.5 + 1;
03984         *(reinterpret_cast<float *>(const_cast<PBuffer>(local[i].pData))) =
03985             i * 3.3 + 1;
03986     }
03987 
03988     // Print out the nullable tuple
03989     TuplePrinter tuplePrinter;
03990     printf("Literals\n");
03991     tuplePrinter.print(cout, tupleDesc, literal);
03992     cout << endl;
03993     printf("\nInput\n");
03994     tuplePrinter.print(cout, tupleDesc, input);
03995     cout << endl;
03996     printf("\nOutput\n");
03997     tuplePrinter.print(cout, tupleDesc, output);
03998     cout << endl;
03999     printf("\nLocal\n");
04000     tuplePrinter.print(cout, tupleDesc, local);
04001     cout << endl;
04002 
04003 
04004     // predefine register references. a real compiler wouldn't do
04005     // something so regular and pre-determined. a compiler would
04006     // probably build these on the fly as it built each instruction.
04007     // predefine register references. a real compiler wouldn't do
04008     // something so regular and pre-determined
04009     RegisterRef<float> **fInP, **fOutP, **fLoP, **fLiP;
04010 
04011     fInP = new RegisterRef<float>*[registersize];
04012     fOutP = new RegisterRef<float>*[registersize];
04013     fLoP = new RegisterRef<float>*[registersize];
04014     fLiP = new RegisterRef<float>*[registersize];
04015 
04016     // Set up the Calculator
04017     DynamicParamManager dpm;
04018     Calculator c(&dpm,0,0,0,0,0,0);
04019     c.outputRegisterByReference(false);
04020 
04021     // set up register references to symbolically point to
04022     // their corresponding storage locations -- makes for easy test case
04023     // generation. again, a compiler wouldn't do things in quite
04024     // this way.
04025     for (i = 0; i < registersize; i++) {
04026         fInP[i] = new RegisterRef<float>(
04027             RegisterReference::EInput,
04028             floatIdx + i,
04029             STANDARD_TYPE_REAL);
04030         c.appendRegRef(fInP[i]);
04031         fOutP[i] = new RegisterRef<float>(
04032             RegisterReference::EOutput,
04033             floatIdx + i,
04034             STANDARD_TYPE_REAL);
04035         c.appendRegRef(fOutP[i]);
04036         fLoP[i] = new RegisterRef<float>(
04037             RegisterReference::ELocal,
04038             floatIdx + i,
04039             STANDARD_TYPE_REAL);
04040         c.appendRegRef(fLoP[i]);
04041         fLiP[i] = new RegisterRef<float>(
04042             RegisterReference::ELiteral,
04043             floatIdx + i,
04044             STANDARD_TYPE_REAL);
04045         c.appendRegRef(fLiP[i]);
04046     }
04047 
04048 
04049     // Set up storage for instructions
04050     // a real compiler would probably cons up instructions and insert them
04051     // directly into the calculator. keep an array of the instructions at
04052     // this level to allow printing of the program after execution, and other
04053     // debugging
04054     Instruction **instP;
04055     instP = new InstructionPtr[200];
04056     int pc = 0, outF = 0;
04057 
04058     StandardTypeDescriptorOrdinal isFloat = STANDARD_TYPE_REAL;
04059 
04060     // Force a warning
04061     instP[pc++] = new NativeDiv<float>(
04062         fOutP[outF++], fLiP[2], fLiP[0], isFloat);
04063     int lastPC = pc;
04064 
04065     for (i = 0; i < pc; i++) {
04066         c.appendInstruction(instP[i]);
04067     }
04068 
04069     c.bind(
04070         RegisterReference::ELiteral,
04071         &literal,
04072         tupleDesc);
04073     c.bind(
04074         RegisterReference::EInput,
04075         &input,
04076         tupleDesc);
04077     c.bind(
04078         RegisterReference::EOutput,
04079         &output,
04080         tupleDesc);
04081     c.bind(
04082         RegisterReference::ELocal,
04083         &local,
04084         tupleDesc);
04085     c.bind(
04086         RegisterReference::EStatus,
04087         &status,
04088         tupleDesc);
04089     c.exec();
04090 
04091     string out;
04092     for (i = 0; i < pc; i++) {
04093         instP[i]->describe(out, true);
04094         printf("[%2d] %s\n", i, out.c_str());
04095     }
04096 
04097     // Print out the output tuple
04098     printf("Output Tuple\n");
04099     tuplePrinter.print(cout, tupleDesc, output);
04100     cout << endl;
04101 
04102     cout << "Calculator Warnings: " << c.warnings() << endl;
04103 
04104     deque<CalcMessage>::iterator iter = c.mWarnings.begin();
04105     if (iter->pc != 0) {
04106         fail("warning:pc", __LINE__);
04107     }
04108     string expectederror("22012");
04109     if (expectederror.compare(iter->str)) {
04110         fail("warning:div by zero failed string wasn't as expected", __LINE__);
04111     }
04112     string expectedwarningstring("[0]:PC=0 Code=22012 ");
04113     cout << "|" << expectedwarningstring << "|" << endl;
04114 
04115     if (expectedwarningstring.compare(c.warnings())) {
04116         fail("warning:warning string wasn't as expected", __LINE__);
04117     }
04118 
04119     // Replace the literal '0' with something benign
04120     pc = 0;
04121     outF = 0;
04122     instP[pc++] = new NativeDiv<float>(
04123         fOutP[outF++], fLiP[2], fLiP[2], isFloat);
04124     *(reinterpret_cast<float *>(const_cast<PBuffer>(literal[0].pData))) = 2;
04125 
04126     // Out[0] is now null, due to the div by zero error
04127     // Hack output tuple to something re-runable
04128     float horriblehack = 88;
04129     // JR 6/15.07 - no longer works:
04130     // reinterpret_cast<float *>(const_cast<PBuffer>(output[0].pData)) =
04131     //     &horriblehack;
04132     output[0].pData = reinterpret_cast<const uint8_t *>(&horriblehack);
04133 
04134     printf("Rerunning calculator\n");
04135 
04136     c.bind(&input, &output);
04137     c.exec();
04138 
04139     cout << "Calculator Warnings: " << c.warnings() << endl;
04140 
04141     if (!c.mWarnings.empty()) {
04142         fail("warning:warning deque has data", __LINE__);
04143     }
04144     if (c.warnings().compare("")) {
04145         fail("warning:warning string empty", __LINE__);
04146     }
04147 
04148     delete [] fInP;
04149     delete [] fOutP;
04150     delete [] fLoP;
04151     delete [] fLiP;
04152 
04153     for (i = 0; i < lastPC; i++) {
04154         delete instP[i];
04155     }
04156     delete [] instP;
04157 
04158 }
04159 
04160 void
04161 unitTestPointerCache()
04162 {
04163     printf("=========================================================\n");
04164     printf("=========================================================\n");
04165     printf("=====\n");
04166     printf("=====     unitTestPointerCache()\n");
04167     printf("=====\n");
04168     printf("=========================================================\n");
04169     printf("=========================================================\n");
04170 
04171     bool isNullable = true;    // Can tuple contain nulls?
04172     int i, registersize = 10;
04173 
04174     TupleDescriptor tupleDesc;
04175     tupleDesc.clear();
04176 
04177     // Build up a description of what we'd like the tuple to look like
04178     StandardTypeDescriptorFactory typeFactory;
04179     int idx = 0;
04180 
04181     int doubleIdx = idx;
04182     for (i = 0;i < registersize; i++) {
04183         // doubles
04184         StoredTypeDescriptor const &typeDesc =
04185             typeFactory.newDataType(STANDARD_TYPE_DOUBLE);
04186         tupleDesc.push_back(TupleAttributeDescriptor(typeDesc, isNullable));
04187         idx++;
04188     }
04189 
04190     // Create a tuple accessor from the description
04191     //
04192     // Note: Must use a NOT_NULL_AND_FIXED accessor when creating a tuple out
04193     // of the air like this, otherwise unmarshal() does not know what to do. If
04194     // you need a STANDARD type tuple that supports nulls, it has to be built
04195     // as a copy.
04196     TupleAccessor tupleAccessorFixedLiteral;
04197     TupleAccessor tupleAccessorFixedInput;
04198     TupleAccessor tupleAccessorFixedOutput;
04199     TupleAccessor tupleAccessorFixedLocal;
04200     TupleAccessor tupleAccessorFixedStatus;
04201     tupleAccessorFixedLiteral.compute(tupleDesc, TUPLE_FORMAT_ALL_FIXED);
04202     tupleAccessorFixedInput.compute(tupleDesc, TUPLE_FORMAT_ALL_FIXED);
04203     tupleAccessorFixedOutput.compute(tupleDesc, TUPLE_FORMAT_ALL_FIXED);
04204     tupleAccessorFixedLocal.compute(tupleDesc, TUPLE_FORMAT_ALL_FIXED);
04205     tupleAccessorFixedStatus.compute(tupleDesc, TUPLE_FORMAT_ALL_FIXED);
04206 
04207     // Allocate memory for the tuple
04208     boost::scoped_array<FixedBuffer> pTupleBufFixedLiteral(
04209         new FixedBuffer[tupleAccessorFixedLiteral.getMaxByteCount()]);
04210     boost::scoped_array<FixedBuffer> pTupleBufFixedInput(
04211         new FixedBuffer[tupleAccessorFixedInput.getMaxByteCount()]);
04212     boost::scoped_array<FixedBuffer> pTupleBufFixedOutput(
04213         new FixedBuffer[tupleAccessorFixedOutput.getMaxByteCount()]);
04214     boost::scoped_array<FixedBuffer> pTupleBufFixedLocal(
04215         new FixedBuffer[tupleAccessorFixedLocal.getMaxByteCount()]);
04216     boost::scoped_array<FixedBuffer> pTupleBufFixedStatus(
04217         new FixedBuffer[tupleAccessorFixedStatus.getMaxByteCount()]);
04218 
04219     // Link memory to accessor
04220     tupleAccessorFixedLiteral.setCurrentTupleBuf(
04221         pTupleBufFixedLiteral.get(), false);
04222     tupleAccessorFixedInput.setCurrentTupleBuf(
04223         pTupleBufFixedInput.get(), false);
04224     tupleAccessorFixedOutput.setCurrentTupleBuf(
04225         pTupleBufFixedOutput.get(), false);
04226     tupleAccessorFixedLocal.setCurrentTupleBuf(
04227         pTupleBufFixedLocal.get(), false);
04228     tupleAccessorFixedStatus.setCurrentTupleBuf(
04229         pTupleBufFixedStatus.get(), false);
04230 
04231     // Create a vector of TupleDatum objects based on the description we built
04232     TupleData tupleDataFixedLiteral(tupleDesc);
04233     TupleData tupleDataFixedInput(tupleDesc);
04234     TupleData tupleDataFixedOutput(tupleDesc);
04235     TupleData tupleDataFixedLocal(tupleDesc);
04236     TupleData tupleDataFixedStatus(tupleDesc);
04237 
04238     // Do something mysterious. Probably binding pointers in the accessor to
04239     // items in the TupleData vector
04240     tupleAccessorFixedLiteral.unmarshal(tupleDataFixedLiteral);
04241     tupleAccessorFixedInput.unmarshal(tupleDataFixedInput);
04242     tupleAccessorFixedOutput.unmarshal(tupleDataFixedOutput);
04243     tupleAccessorFixedLocal.unmarshal(tupleDataFixedLocal);
04244     tupleAccessorFixedStatus.unmarshal(tupleDataFixedStatus);
04245 
04246     // create four nullable tuples to serve as register sets
04247     TupleData literal = tupleDataFixedLiteral;
04248     TupleData input = tupleDataFixedInput;
04249     TupleData output = tupleDataFixedOutput;
04250     TupleData local = tupleDataFixedLocal;
04251     TupleData status = tupleDataFixedStatus;
04252 
04253     // Set up some useful literals
04254     for (i = 0; i < registersize; i++) {
04255         *(reinterpret_cast<double *>(const_cast<PBuffer>(literal[i].pData))) =
04256             i * 0.5;
04257         *(reinterpret_cast<double *>(const_cast<PBuffer>(output[i].pData))) =
04258             i * 2 + 1;
04259         *(reinterpret_cast<double *>(const_cast<PBuffer>(input[i].pData))) =
04260             i * 5.5 + 1;
04261         *(reinterpret_cast<double *>(const_cast<PBuffer>(local[i].pData))) =
04262             i * 3.3 + 1;
04263     }
04264 
04265     // Print out the nullable tuple
04266     TuplePrinter tuplePrinter;
04267     printf("Literals\n");
04268     tuplePrinter.print(cout, tupleDesc, literal);
04269     cout << endl;
04270     printf("\nInput\n");
04271     tuplePrinter.print(cout, tupleDesc, input);
04272     cout << endl;
04273     printf("\nOutput\n");
04274     tuplePrinter.print(cout, tupleDesc, output);
04275     cout << endl;
04276     printf("\nLocal\n");
04277     tuplePrinter.print(cout, tupleDesc, local);
04278     cout << endl;
04279 
04280 
04281     // predefine register references. a real compiler wouldn't do
04282     // something so regular and pre-determined. a compiler would
04283     // probably build these on the fly as it built each instruction.
04284     // predefine register references. a real compiler wouldn't do
04285     // something so regular and pre-determined
04286     RegisterRef<double> **fInP, **fOutP, **fLoP, **fLiP;
04287 
04288     fInP = new RegisterRef<double>*[registersize];
04289     fOutP = new RegisterRef<double>*[registersize];
04290     fLoP = new RegisterRef<double>*[registersize];
04291     fLiP = new RegisterRef<double>*[registersize];
04292 
04293     // Set up the Calculator
04294     DynamicParamManager dpm;
04295     Calculator c(&dpm,0,0,0,0,0,0);
04296     c.outputRegisterByReference(false);
04297 
04298     // set up register references to symbolically point to
04299     // their corresponding storage locations -- makes for easy test case
04300     // generation. again, a compiler wouldn't do things in quite
04301     // this way.
04302     for (i = 0; i < registersize; i++) {
04303         fInP[i] = new RegisterRef<double>(
04304             RegisterReference::EInput,
04305             doubleIdx + i,
04306             STANDARD_TYPE_DOUBLE);
04307         c.appendRegRef(fInP[i]);
04308         fOutP[i] = new RegisterRef<double>(
04309             RegisterReference::EOutput,
04310             doubleIdx + i,
04311             STANDARD_TYPE_DOUBLE);
04312         c.appendRegRef(fOutP[i]);
04313         fLoP[i] = new RegisterRef<double>(
04314             RegisterReference::ELocal,
04315             doubleIdx + i,
04316             STANDARD_TYPE_DOUBLE);
04317         c.appendRegRef(fLoP[i]);
04318         fLiP[i] = new RegisterRef<double>(
04319             RegisterReference::ELiteral,
04320             doubleIdx + i,
04321             STANDARD_TYPE_DOUBLE);
04322         c.appendRegRef(fLiP[i]);
04323     }
04324 
04325 
04326     // Set up storage for instructions
04327     // a real compiler would probably cons up instructions and insert them
04328     // directly into the calculator. keep an array of the instructions at
04329     // this level to allow printing of the program after execution, and other
04330     // debugging
04331     Instruction **instP;
04332     instP = new InstructionPtr[200];
04333     int pc = 0, outF = 0, liF = 0;
04334 
04335 
04336     StandardTypeDescriptorOrdinal isDouble = STANDARD_TYPE_DOUBLE;
04337 
04338     // copy some of the literals into the output register
04339     for (i = 0; i < (registersize / 2) - 1 ; i++) {
04340         instP[pc++] = new NativeMove<double>(
04341             fOutP[outF++], fLiP[liF++], isDouble);
04342     }
04343     // copy some of the locals into the output register
04344     for (i = 0; i < (registersize / 2) - 1 ; i++) {
04345         instP[pc++] = new NativeMove<double>(
04346             fOutP[outF++], fLoP[liF++], isDouble);
04347     }
04348     int lastPC = pc;
04349 
04350     for (i = 0; i < pc; i++) {
04351         c.appendInstruction(instP[i]);
04352     }
04353 
04354     c.bind(
04355         RegisterReference::ELiteral,
04356         &literal,
04357         tupleDesc);
04358     c.bind(
04359         RegisterReference::EInput,
04360         &input,
04361         tupleDesc);
04362     c.bind(
04363         RegisterReference::EOutput,
04364         &output,
04365         tupleDesc);
04366     c.bind(
04367         RegisterReference::ELocal,
04368         &local,
04369         tupleDesc);
04370     c.bind(
04371         RegisterReference::EStatus,
04372         &status,
04373         tupleDesc);
04374     c.exec();
04375 
04376     string out;
04377     for (i = 0; i < pc; i++) {
04378         instP[i]->describe(out, true);
04379         printf("[%2d] %s\n", i, out.c_str());
04380     }
04381 
04382     // Print out the output tuple
04383     printf("Output Tuple\n");
04384     tuplePrinter.print(cout, tupleDesc, output);
04385     cout << endl;
04386 
04387     cout << "Calculator Warnings: " << c.warnings() << endl;
04388 
04389     outF = liF = 0;
04390     for (i = 0; i < (registersize / 2) - 1 ; i++) {
04391         if (*(reinterpret_cast<double *>(const_cast<PBuffer>(
04392             output[outF++].pData)))
04393             != (i * 0.5))
04394         {
04395             fail("pointercache1", __LINE__);
04396         }
04397     }
04398     for (i = 0; i < (registersize / 2) - 1 ; i++) {
04399         if ((*(reinterpret_cast<double *>(const_cast<PBuffer>(
04400             output[outF++].pData)))
04401              - (outF * 3.3 + 1))
04402             > 0.000001)
04403         {
04404             fail("pointercache2", __LINE__);
04405         }
04406     }
04407 
04408     // OK, now be mean and yank the literals right out from under
04409     // Calculator. The memory is still allocated and available
04410     // for the cached pointers. Note that the calculator will have
04411     // no reason to reset these pointers as they weren't re-pointed
04412     // or set to null
04413     for (i = 0; i < registersize; i++) {
04414         literal[i].pData = NULL;
04415         local[i].pData = NULL;
04416     }
04417 
04418     printf("Rerunning calculator\n");
04419 
04420     c.bind(&input, &output);
04421     c.exec();
04422 
04423     outF = liF = 0;
04424     for (i = 0; i < (registersize / 2) - 1 ; i++) {
04425         if (*(reinterpret_cast<double *>(const_cast<PBuffer>(
04426             output[outF++].pData)))
04427             != (i * 0.5))
04428         {
04429             fail("pointercache3", __LINE__);
04430         }
04431     }
04432     for (i = 0; i < (registersize / 2) - 1 ; i++) {
04433         if ((*(reinterpret_cast<double *>(const_cast<PBuffer>(
04434             output[outF++].pData)))
04435              - (outF * 3.3 + 1)) > 0.000001)
04436         {
04437             fail("pointercache4", __LINE__);
04438         }
04439     }
04440 
04441     cout << "Calculator Warnings: " << c.warnings() << endl;
04442 
04443     delete [] fInP;
04444     delete [] fOutP;
04445     delete [] fLoP;
04446     delete [] fLiP;
04447 
04448     for (i = 0; i < lastPC; i++) {
04449         delete instP[i];
04450     }
04451     delete [] instP;
04452 
04453 }
04454 
04455 void
04456 unitTestNullableLocal()
04457 {
04458     printf("=========================================================\n");
04459     printf("=========================================================\n");
04460     printf("=====\n");
04461     printf("=====     unitTestNullableLocal()\n");
04462     printf("=====\n");
04463     printf("=========================================================\n");
04464     printf("=========================================================\n");
04465 
04466     bool isNullable = true;    // Can tuple contain nulls?
04467     int i, registersize = 10;
04468     static int bufferlen = 8;
04469 
04470     TupleDescriptor tupleDesc;
04471     tupleDesc.clear();
04472 
04473     // Build up a description of what we'd like the tuple to look like
04474     StandardTypeDescriptorFactory typeFactory;
04475     int idx = 0;
04476 
04477     const int pointerIdx = idx;
04478     for (i = 0;i < registersize; i++) {
04479         // pointers in first "half"
04480         StoredTypeDescriptor const &typeDesc =
04481             typeFactory.newDataType(STANDARD_TYPE_VARCHAR);
04482         // tell descriptor the size
04483         tupleDesc.push_back(
04484             TupleAttributeDescriptor(
04485                 typeDesc,
04486                 isNullable,
04487                 bufferlen));
04488         idx++;
04489     }
04490     const int boolIdx = idx;
04491     for (i = 0;i < registersize; i++) {
04492         // booleans in second "half"
04493         StoredTypeDescriptor const &typeDesc =
04494             typeFactory.newDataType(STANDARD_TYPE_UINT_8);
04495         tupleDesc.push_back(TupleAttributeDescriptor(typeDesc, isNullable));
04496         idx++;
04497     }
04498 
04499     // Create a tuple accessor from the description
04500     //
04501     // Note: Must use a NOT_NULL_AND_FIXED accessor when creating a tuple out
04502     // of the air like this, otherwise unmarshal() does not know what to do. If
04503     // you need a STANDARD type tuple that supports nulls, it has to be built
04504     // as a copy.
04505     TupleAccessor tupleAccessorFixedLiteral;
04506     TupleAccessor tupleAccessorFixedInput;
04507     TupleAccessor tupleAccessorFixedOutput;
04508     TupleAccessor tupleAccessorFixedLocal;
04509     TupleAccessor tupleAccessorFixedStatus;
04510     tupleAccessorFixedLiteral.compute(tupleDesc, TUPLE_FORMAT_ALL_FIXED);
04511     tupleAccessorFixedInput.compute(tupleDesc, TUPLE_FORMAT_ALL_FIXED);
04512     tupleAccessorFixedOutput.compute(tupleDesc, TUPLE_FORMAT_ALL_FIXED);
04513     tupleAccessorFixedLocal.compute(tupleDesc, TUPLE_FORMAT_ALL_FIXED);
04514     tupleAccessorFixedStatus.compute(tupleDesc, TUPLE_FORMAT_ALL_FIXED);
04515 
04516     // Allocate memory for the tuple
04517     boost::scoped_array<FixedBuffer> pTupleBufFixedLiteral(
04518         new FixedBuffer[tupleAccessorFixedLiteral.getMaxByteCount()]);
04519     boost::scoped_array<FixedBuffer> pTupleBufFixedInput(
04520         new FixedBuffer[tupleAccessorFixedInput.getMaxByteCount()]);
04521     boost::scoped_array<FixedBuffer> pTupleBufFixedOutput(
04522         new FixedBuffer[tupleAccessorFixedOutput.getMaxByteCount()]);
04523     boost::scoped_array<FixedBuffer> pTupleBufFixedLocal(
04524         new FixedBuffer[tupleAccessorFixedLocal.getMaxByteCount()]);
04525     boost::scoped_array<FixedBuffer> pTupleBufFixedStatus(
04526         new FixedBuffer[tupleAccessorFixedStatus.getMaxByteCount()]);
04527 
04528     // Link memory to accessor
04529     tupleAccessorFixedLiteral.setCurrentTupleBuf(
04530         pTupleBufFixedLiteral.get(), false);
04531     tupleAccessorFixedInput.setCurrentTupleBuf(
04532         pTupleBufFixedInput.get(), false);
04533     tupleAccessorFixedOutput.setCurrentTupleBuf(
04534         pTupleBufFixedOutput.get(), false);
04535     tupleAccessorFixedLocal.setCurrentTupleBuf(
04536         pTupleBufFixedLocal.get(), false);
04537     tupleAccessorFixedStatus.setCurrentTupleBuf(
04538         pTupleBufFixedStatus.get(), false);
04539 
04540     // Create a vector of TupleDatum objects based on the description we built
04541     TupleData tupleDataFixedLiteral(tupleDesc);
04542     TupleData tupleDataFixedInput(tupleDesc);
04543     TupleData tupleDataFixedOutput(tupleDesc);
04544     TupleData tupleDataFixedLocal(tupleDesc);
04545     TupleData tupleDataFixedStatus(tupleDesc);
04546 
04547     // Do something mysterious. Probably binding pointers in the accessor to
04548     // items in the TupleData vector
04549     tupleAccessorFixedLiteral.unmarshal(tupleDataFixedLiteral);
04550     tupleAccessorFixedInput.unmarshal(tupleDataFixedInput);
04551     tupleAccessorFixedOutput.unmarshal(tupleDataFixedOutput);
04552     tupleAccessorFixedLocal.unmarshal(tupleDataFixedLocal);
04553     tupleAccessorFixedStatus.unmarshal(tupleDataFixedStatus);
04554 
04555     // create four nullable tuples to serve as register sets
04556     TupleData literal = tupleDataFixedLiteral;
04557     TupleData input = tupleDataFixedInput;
04558     TupleData output = tupleDataFixedOutput;
04559     TupleData local = tupleDataFixedLocal;
04560     TupleData status = tupleDataFixedStatus;
04561 
04562     // Set up some useful literals
04563     for (i = 0; i < registersize; i++) {
04564         char num[16];
04565         sprintf(num, "%04d", i);
04566         char* ptr =
04567             reinterpret_cast<char *>(const_cast<PBuffer>(literal[i].pData));
04568         memset(ptr, 'C', bufferlen); // VARCHAR is not null terminated
04569         memcpy(ptr, num, 4); // copy number, but not null
04570 
04571         // Put some data other tuples as well
04572         ptr = reinterpret_cast<char *>(const_cast<PBuffer>(input[i].pData));
04573         memset(ptr, 'I', bufferlen); // VARCHAR is not null terminated
04574         memcpy(ptr, num, 4); // copy number, but not null
04575 
04576         ptr = reinterpret_cast<char *>(const_cast<PBuffer>(output[i].pData));
04577         memset(ptr, 'O', bufferlen); // VARCHAR is not null terminated
04578         memcpy(ptr, num, 4); // copy number, but not null
04579 
04580         ptr = reinterpret_cast<char *>(const_cast<PBuffer>(local[i].pData));
04581         memset(ptr, 'L', bufferlen); // VARCHAR is not null terminated
04582         memcpy(ptr, num, 4); // copy number, but not null
04583     }
04584 
04585     int falseIdx = 0;
04586     int trueIdx = 1;
04587     i = registersize;
04588     *(reinterpret_cast<bool *>(const_cast<PBuffer>(literal[i].pData))) = false;
04589     for (i++; i < registersize*2; i++) {
04590         *(reinterpret_cast<bool *>(const_cast<PBuffer>(literal[i].pData))) =
04591             true;
04592     }
04593 
04594     // null out last element of each type
04595     int nullidx = registersize-1;
04596     literal[nullidx].pData = NULL;
04597     input[nullidx].pData = NULL;
04598     output[nullidx].pData = NULL;
04599     local[nullidx].pData = NULL;
04600 
04601     // Print out the nullable tuple
04602     TuplePrinter tuplePrinter;
04603     printf("Literals\n");
04604     tuplePrinter.print(cout, tupleDesc, literal);
04605     cout << endl;
04606     printf("\nInput\n");
04607     tuplePrinter.print(cout, tupleDesc, input);
04608     cout << endl;
04609     printf("\nOutput\n");
04610     tuplePrinter.print(cout, tupleDesc, output);
04611     cout << endl;
04612     printf("\nLocal\n");
04613     tuplePrinter.print(cout, tupleDesc, local);
04614     cout << endl;
04615 
04616     // predefine register references. a real compiler wouldn't do
04617     // something so regular and pre-determined. a compiler would
04618     // probably build these on the fly as it built each instruction.
04619     // predefine register references. a real compiler wouldn't do
04620     // something so regular and pre-determined
04621     RegisterRef<char *> **cpInP, **cpOutP, **cpLiP;
04622     RegisterRef<bool> **bInP, **bOutP, **bLiP;
04623 
04624     RegisterRef<char *> **cpLoP;
04625     RegisterRef<bool> **bLoP;
04626 
04627     cpInP = new RegisterRef<char *>*[registersize];
04628     cpOutP = new RegisterRef<char *>*[registersize];
04629     cpLoP = new RegisterRef<char *>*[registersize];
04630     cpLiP = new RegisterRef<char *>*[registersize];
04631 
04632     bInP = new RegisterRef<bool>*[registersize];
04633     bOutP = new RegisterRef<bool>*[registersize];
04634     bLoP = new RegisterRef<bool>*[registersize];
04635     bLiP = new RegisterRef<bool>*[registersize];
04636 
04637     // Set up the Calculator
04638     DynamicParamManager dpm;
04639     Calculator c(&dpm,0,0,0,0,0,0);
04640     c.outputRegisterByReference(false);
04641 
04642     // set up register references to symbolically point to
04643     // their corresponding storage locations -- makes for easy test case
04644     // generation. again, a compiler wouldn't do things in quite
04645     // this way.
04646     for (i = 0; i < registersize; i++) {
04647         cpInP[i] = new RegisterRef<char *>(
04648             RegisterReference::EInput,
04649             pointerIdx + i,
04650             STANDARD_TYPE_VARCHAR);
04651         c.appendRegRef(cpInP[i]);
04652         cpOutP[i] = new RegisterRef<char *>(
04653             RegisterReference::EOutput,
04654             pointerIdx + i,
04655             STANDARD_TYPE_VARCHAR);
04656         c.appendRegRef(cpOutP[i]);
04657         cpLoP[i] = new RegisterRef<char *>(
04658             RegisterReference::ELocal,
04659             pointerIdx + i,
04660             STANDARD_TYPE_VARCHAR);
04661         c.appendRegRef(cpLoP[i]);
04662         cpLiP[i] = new RegisterRef<char *>(
04663             RegisterReference::ELiteral,
04664             pointerIdx + i,
04665             STANDARD_TYPE_VARCHAR);
04666         c.appendRegRef(cpLiP[i]);
04667 
04668         bInP[i] = new RegisterRef<bool>(
04669             RegisterReference::EInput,
04670             boolIdx + i,
04671             STANDARD_TYPE_BOOL);
04672         c.appendRegRef(bInP[i]);
04673         bOutP[i] = new RegisterRef<bool>(
04674             RegisterReference::EOutput,
04675             boolIdx + i,
04676             STANDARD_TYPE_BOOL);
04677         c.appendRegRef(bOutP[i]);
04678         bLoP[i] = new RegisterRef<bool>(
04679             RegisterReference::ELocal,
04680             boolIdx + i,
04681             STANDARD_TYPE_BOOL);
04682         c.appendRegRef(bLoP[i]);
04683         bLiP[i] = new RegisterRef<bool>(
04684             RegisterReference::ELiteral,
04685             boolIdx + i,
04686             STANDARD_TYPE_BOOL);
04687         c.appendRegRef(bLiP[i]);
04688     }
04689 
04690     // Set up storage for instructions
04691     // a real compiler would probably cons up instructions and insert them
04692     // directly into the calculator. keep an array of the instructions at
04693     // this level to allow printing of the program after execution, and other
04694     // debugging
04695     Instruction **instP;
04696     instP = new InstructionPtr[200];
04697     int pc = 0, outCp = 0, outB = 0;
04698     StandardTypeDescriptorOrdinal isVC = STANDARD_TYPE_VARCHAR;
04699 
04700     // set success flag to false
04701     instP[pc++] = new BoolMove(bOutP[0], bLiP[falseIdx]);
04702 
04703     // test booleans and thus all natives
04704 
04705     // check that boolean local register 0 is not null
04706     instP[pc++] = new BoolIsNotNull(bLoP[1], bLoP[0]);
04707     instP[pc] = new JumpTrue(pc + 2, bLoP[1]);
04708     pc++;
04709     instP[pc++] = new ReturnInstruction();
04710     // write something into non-null 0
04711     // will cause crash if 0 happened to be null
04712     instP[pc++] = new BoolMove(bLoP[0], bLiP[trueIdx]);
04713     // set local 0 to null
04714     instP[pc++] = new BoolToNull(bLoP[0]);
04715     // check local 0 is null
04716     instP[pc++] = new BoolIsNull(bLoP[2], bLoP[0]);
04717     instP[pc] = new JumpTrue(pc + 2, bLoP[2]);
04718     pc++;
04719     instP[pc++] = new ReturnInstruction();
04720 
04721     // test pointers
04722 
04723     // check that pointer local register 0 is not null
04724     instP[pc++] = new BoolPointerIsNotNull<char *>(bLoP[3], cpLoP[0], isVC);
04725     instP[pc] = new JumpTrue(pc + 2, bLoP[3]);
04726     pc++;
04727     instP[pc++] = new ReturnInstruction();
04728     // copy local 0 to output register, so we can see it
04729     instP[pc++] = new PointerMove<char *>(cpOutP[0], cpLoP[0], isVC);
04730     // write something into non-null 0
04731     // will cause crash if 0 happened to be null
04732     instP[pc++] = new PointerMove<char *>(cpLoP[0], cpLiP[1], isVC);
04733     // set local 0 to null
04734     instP[pc++] = new PointerToNull<char *>(cpLoP[0], isVC);
04735     // copy local 0 to output register, so we can see it
04736     instP[pc++] = new PointerMove<char *>(cpOutP[1], cpLoP[0], isVC);
04737     // check local 0 is null
04738     instP[pc++] = new BoolPointerIsNull<char *>(bLoP[4], cpLoP[0], isVC);
04739     instP[pc] = new JumpTrue(pc + 2, bLoP[4]);
04740     pc++;
04741     instP[pc++] = new ReturnInstruction();
04742 
04743     // set success
04744     instP[pc++] = new BoolMove(bOutP[0], bLiP[trueIdx]);
04745     instP[pc++] = new ReturnInstruction();
04746     int lastPC = pc;
04747 
04748     for (i = 0; i < pc; i++) {
04749         c.appendInstruction(instP[i]);
04750     }
04751 
04752     printf("first run\n");
04753 
04754     c.bind(
04755         RegisterReference::ELiteral,
04756         &literal,
04757         tupleDesc);
04758     c.bind(
04759         RegisterReference::EInput,
04760         &input,
04761         tupleDesc);
04762     c.bind(
04763         RegisterReference::EOutput,
04764         &output,
04765         tupleDesc);
04766     c.bind(
04767         RegisterReference::ELocal,
04768         &local,
04769         tupleDesc);
04770     c.bind(
04771         RegisterReference::EStatus,
04772         &status,
04773         tupleDesc);
04774     c.exec();
04775 
04776     printf("after first run\n");
04777 
04778     string out;
04779     for (i = 0; i < pc; i++) {
04780         instP[i]->describe(out, true);
04781         printf("[%2d] %s\n", i, out.c_str());
04782     }
04783 
04784     // Print out the output tuple
04785     printf("Output Tuple\n");
04786     tuplePrinter.print(cout, tupleDesc, output);
04787     cout << endl;
04788     printf("Local Tuple\n");
04789     tuplePrinter.print(cout, tupleDesc, local);
04790     cout << endl;
04791 
04792     outCp = 0; // now indexes into output tuple, not outputregisterref
04793     outB = boolIdx;  // now indexs into output tuple, not outputregisterref
04794 
04795     // check status flag in output
04796     if (*(output[boolIdx].pData) != true) {
04797         fail("nullablelocal1", __LINE__);
04798     }
04799     // check that actual pointer was not nulled out
04800     if (local[boolIdx].pData == NULL) {
04801         fail("nullablelocal2", __LINE__);
04802     }
04803 
04804     // make sure that previously null pointers weren't somehow 'un-nulled'
04805     if (literal[nullidx].pData != NULL) {
04806         fail("nullablelocal3", __LINE__);
04807     }
04808     if (input[nullidx].pData != NULL) {
04809         fail("nullablelocal4", __LINE__);
04810     }
04811     if (output[nullidx].pData != NULL) {
04812         fail("nullablelocal5", __LINE__);
04813     }
04814     if (local[nullidx].pData != NULL) {
04815         fail("nullablelocal6", __LINE__);
04816     }
04817 
04818 
04819     printf("second run\n");
04820 
04821     c.bind(&input, &output);
04822     c.exec();
04823 
04824     printf("after second run\n");
04825 
04826     // Print out the output tuple
04827     printf("Output Tuple\n");
04828     tuplePrinter.print(cout, tupleDesc, output);
04829     cout << endl;
04830     printf("Local Tuple\n");
04831     tuplePrinter.print(cout, tupleDesc, local);
04832     cout << endl;
04833 
04834 
04835     // check status flag in output
04836     if (*(output[boolIdx].pData) != true) {
04837         fail("nullablelocal7", __LINE__);
04838     }
04839     // check that actual pointer was not nulled out
04840     if (local[boolIdx].pData == NULL) {
04841         fail("nullablelocal8", __LINE__);
04842     }
04843 
04844     // make sure that previously null pointers weren't somehow 'un-nulled'
04845     if (literal[nullidx].pData != NULL) {
04846         fail("nullablelocal9", __LINE__);
04847     }
04848     if (input[nullidx].pData != NULL) {
04849         fail("nullablelocal10", __LINE__);
04850     }
04851     if (output[nullidx].pData != NULL) {
04852         fail("nullablelocal11", __LINE__);
04853     }
04854     if (local[nullidx].pData != NULL) {
04855         fail("nullablelocal12", __LINE__);
04856     }
04857 
04858     delete [] cpInP;
04859     delete [] cpOutP;
04860     delete [] cpLoP;
04861     delete [] cpLiP;
04862 
04863     delete [] bInP;
04864     delete [] bOutP;
04865     delete [] bLoP;
04866     delete [] bLiP;
04867     for (i = 0; i < lastPC; i++) {
04868         delete instP[i];
04869     }
04870     delete [] instP;
04871 }
04872 
04873 void
04874 unitTestStatusRegister()
04875 {
04876     printf("=========================================================\n");
04877     printf("=========================================================\n");
04878     printf("=====\n");
04879     printf("=====     unitTestStatusRegister()\n");
04880     printf("=====\n");
04881     printf("=========================================================\n");
04882     printf("=========================================================\n");
04883 
04884     bool isNullable = true;    // Can tuple contain nulls?
04885     int i, registersize = 10;
04886 
04887     TupleDescriptor tupleDesc;
04888     tupleDesc.clear();
04889 
04890     // Build up a description of what we'd like the tuple to look like
04891     StandardTypeDescriptorFactory typeFactory;
04892     int idx = 0;
04893 
04894     int u_int16Idx = idx;
04895     for (i = 0;i < registersize; i++) {
04896         // u_int16 (short)
04897         StoredTypeDescriptor const &typeDesc =
04898             typeFactory.newDataType(STANDARD_TYPE_UINT_16);
04899         tupleDesc.push_back(TupleAttributeDescriptor(typeDesc, isNullable));
04900         idx++;
04901     }
04902 
04903     // Create a tuple accessor from the description
04904     //
04905     // Note: Must use a NOT_NULL_AND_FIXED accessor when creating a tuple out
04906     // of the air like this, otherwise unmarshal() does not know what to do. If
04907     // you need a STANDARD type tuple that supports nulls, it has to be built
04908     // as a copy.
04909     TupleAccessor tupleAccessorFixedLiteral;
04910     TupleAccessor tupleAccessorFixedInput;
04911     TupleAccessor tupleAccessorFixedOutput;
04912     TupleAccessor tupleAccessorFixedLocal;
04913     TupleAccessor tupleAccessorFixedStatus;
04914     tupleAccessorFixedLiteral.compute(tupleDesc, TUPLE_FORMAT_ALL_FIXED);
04915     tupleAccessorFixedInput.compute(tupleDesc, TUPLE_FORMAT_ALL_FIXED);
04916     tupleAccessorFixedOutput.compute(tupleDesc, TUPLE_FORMAT_ALL_FIXED);
04917     tupleAccessorFixedLocal.compute(tupleDesc, TUPLE_FORMAT_ALL_FIXED);
04918     tupleAccessorFixedStatus.compute(tupleDesc, TUPLE_FORMAT_ALL_FIXED);
04919 
04920     // Allocate memory for the tuple
04921     boost::scoped_array<FixedBuffer> pTupleBufFixedLiteral(
04922         new FixedBuffer[tupleAccessorFixedLiteral.getMaxByteCount()]);
04923     boost::scoped_array<FixedBuffer> pTupleBufFixedInput(
04924         new FixedBuffer[tupleAccessorFixedInput.getMaxByteCount()]);
04925     boost::scoped_array<FixedBuffer> pTupleBufFixedOutput(
04926         new FixedBuffer[tupleAccessorFixedOutput.getMaxByteCount()]);
04927     boost::scoped_array<FixedBuffer> pTupleBufFixedLocal(
04928         new FixedBuffer[tupleAccessorFixedLocal.getMaxByteCount()]);
04929     boost::scoped_array<FixedBuffer> pTupleBufFixedStatus(
04930         new FixedBuffer[tupleAccessorFixedStatus.getMaxByteCount()]);
04931 
04932     // Link memory to accessor
04933     tupleAccessorFixedLiteral.setCurrentTupleBuf(
04934         pTupleBufFixedLiteral.get(), false);
04935     tupleAccessorFixedInput.setCurrentTupleBuf(
04936         pTupleBufFixedInput.get(), false);
04937     tupleAccessorFixedOutput.setCurrentTupleBuf(
04938         pTupleBufFixedOutput.get(), false);
04939     tupleAccessorFixedLocal.setCurrentTupleBuf(
04940         pTupleBufFixedLocal.get(), false);
04941     tupleAccessorFixedStatus.setCurrentTupleBuf(
04942         pTupleBufFixedStatus.get(), false);
04943 
04944     // Create a vector of TupleDatum objects based on the description we built
04945     TupleData tupleDataFixedLiteral(tupleDesc);
04946     TupleData tupleDataFixedInput(tupleDesc);
04947     TupleData tupleDataFixedOutput(tupleDesc);
04948     TupleData tupleDataFixedLocal(tupleDesc);
04949     TupleData tupleDataFixedStatus(tupleDesc);
04950 
04951     // Do something mysterious. Probably binding pointers in the accessor to
04952     // items in the TupleData vector
04953     tupleAccessorFixedLiteral.unmarshal(tupleDataFixedLiteral);
04954     tupleAccessorFixedInput.unmarshal(tupleDataFixedInput);
04955     tupleAccessorFixedOutput.unmarshal(tupleDataFixedOutput);
04956     tupleAccessorFixedLocal.unmarshal(tupleDataFixedLocal);
04957     tupleAccessorFixedStatus.unmarshal(tupleDataFixedStatus);
04958 
04959     // create four nullable tuples to serve as register sets
04960     TupleData literal = tupleDataFixedLiteral;
04961     TupleData input = tupleDataFixedInput;
04962     TupleData output = tupleDataFixedOutput;
04963     TupleData local = tupleDataFixedLocal;
04964     TupleData status = tupleDataFixedStatus;
04965 
04966     // Set up some useful literals
04967     for (i = 0; i < registersize; i++) {
04968         *(reinterpret_cast<uint16_t *>(const_cast<PBuffer>(literal[i].pData))) =
04969             i;
04970         *(reinterpret_cast<uint16_t *>(const_cast<PBuffer>(output[i].pData))) =
04971             i * 2 + 1;
04972         *(reinterpret_cast<uint16_t *>(const_cast<PBuffer>(input[i].pData))) =
04973             i * 5 + 2;
04974         *(reinterpret_cast<uint16_t *>(const_cast<PBuffer>(local[i].pData))) =
04975             i * 10 + 3;
04976         *(reinterpret_cast<uint16_t *>(const_cast<PBuffer>(status[i].pData))) =
04977             i * 15 + 4;
04978     }
04979 
04980     // Print out the nullable tuple
04981     TuplePrinter tuplePrinter;
04982     printf("Literals\n");
04983     tuplePrinter.print(cout, tupleDesc, literal);
04984     cout << endl;
04985     printf("\nInput\n");
04986     tuplePrinter.print(cout, tupleDesc, input);
04987     cout << endl;
04988     printf("\nOutput\n");
04989     tuplePrinter.print(cout, tupleDesc, output);
04990     cout << endl;
04991     printf("\nLocal\n");
04992     tuplePrinter.print(cout, tupleDesc, local);
04993     printf("\nStatus\n");
04994     tuplePrinter.print(cout, tupleDesc, status);
04995     cout << endl;
04996 
04997 
04998     // predefine register references. a real compiler wouldn't do
04999     // something so regular and pre-determined. a compiler would
05000     // probably build these on the fly as it built each instruction.
05001     // predefine register references. a real compiler wouldn't do
05002     // something so regular and pre-determined
05003     RegisterRef<uint16_t> **fInP, **fOutP, **fLoP, **fLiP, **fStP;
05004 
05005     fInP = new RegisterRef<uint16_t>*[registersize];
05006     fOutP = new RegisterRef<uint16_t>*[registersize];
05007     fLoP = new RegisterRef<uint16_t>*[registersize];
05008     fLiP = new RegisterRef<uint16_t>*[registersize];
05009     fStP = new RegisterRef<uint16_t>*[registersize];
05010 
05011     // Set up the Calculator
05012     DynamicParamManager dpm;
05013     Calculator c(&dpm,0,0,0,0,0,0);
05014     c.outputRegisterByReference(false);
05015 
05016     // set up register references to symbolically point to
05017     // their corresponding storage locations -- makes for easy test case
05018     // generation. again, a compiler wouldn't do things in quite
05019     // this way.
05020     for (i = 0; i < registersize; i++) {
05021         fInP[i] = new RegisterRef<uint16_t>(
05022             RegisterReference::EInput,
05023             u_int16Idx + i,
05024             STANDARD_TYPE_UINT_16);
05025         c.appendRegRef(fInP[i]);
05026         fOutP[i] = new RegisterRef<uint16_t>(
05027             RegisterReference::EOutput,
05028             u_int16Idx + i,
05029             STANDARD_TYPE_UINT_16);
05030         c.appendRegRef(fOutP[i]);
05031         fLoP[i] = new RegisterRef<uint16_t>(
05032             RegisterReference::ELocal,
05033             u_int16Idx + i,
05034             STANDARD_TYPE_UINT_16);
05035         c.appendRegRef(fLoP[i]);
05036         fLiP[i] = new RegisterRef<uint16_t>(
05037             RegisterReference::ELiteral,
05038             u_int16Idx + i,
05039             STANDARD_TYPE_UINT_16);
05040         c.appendRegRef(fLiP[i]);
05041         fStP[i] = new RegisterRef<uint16_t>(
05042             RegisterReference::EStatus,
05043             u_int16Idx + i,
05044             STANDARD_TYPE_UINT_16);
05045         c.appendRegRef(fStP[i]);
05046     }
05047 
05048 
05049     // Set up storage for instructions
05050     // a real compiler would probably cons up instructions and insert them
05051     // directly into the calculator. keep an array of the instructions at
05052     // this level to allow printing of the program after execution, and other
05053     // debugging
05054     Instruction **instP;
05055     instP = new InstructionPtr[200];
05056     int pc = 0, statusS = 0, liS = 0;
05057 
05058     StandardTypeDescriptorOrdinal isU_Int16 = STANDARD_TYPE_UINT_16;
05059 
05060     // copy some of the literals into the status register
05061     for (i = 0; i < registersize - 1 ; i++) {
05062         instP[pc++] = new NativeMove<uint16_t>(
05063             fStP[statusS++], fLiP[liS++], isU_Int16);
05064     }
05065 
05066     int lastPC = pc;
05067 
05068     for (i = 0; i < pc; i++) {
05069         c.appendInstruction(instP[i]);
05070     }
05071 
05072     c.bind(
05073         RegisterReference::ELiteral,
05074         &literal,
05075         tupleDesc);
05076     c.bind(
05077         RegisterReference::EInput,
05078         &input,
05079         tupleDesc);
05080     c.bind(
05081         RegisterReference::EOutput,
05082         &output,
05083         tupleDesc);
05084     c.bind(
05085         RegisterReference::ELocal,
05086         &local,
05087         tupleDesc);
05088     c.bind(
05089         RegisterReference::EStatus,
05090         &status,
05091         tupleDesc);
05092     c.exec();
05093 
05094     string out;
05095     for (i = 0; i < pc; i++) {
05096         instP[i]->describe(out, true);
05097         printf("[%2d] %s\n", i, out.c_str());
05098     }
05099 
05100     // Print out the output tuple
05101     printf("Output Tuple\n");
05102     tuplePrinter.print(cout, tupleDesc, output);
05103     cout << endl;
05104     printf("Status Tuple\n");
05105     tuplePrinter.print(cout, tupleDesc, status);
05106     cout << endl;
05107 
05108     cout << "Calculator Warnings: " << c.warnings() << endl;
05109 
05110     statusS = liS = 0;
05111     for (i = 0; i < registersize - 1 ; i++) {
05112         if (*(reinterpret_cast<uint16_t *>(const_cast<PBuffer>(
05113             status[statusS++].pData)))
05114             != static_cast<uint16_t>(i))
05115         {
05116             fail("statusregister1", __LINE__);
05117         }
05118     }
05119 
05120     delete [] fInP;
05121     delete [] fOutP;
05122     delete [] fLoP;
05123     delete [] fLiP;
05124     delete [] fStP;
05125 
05126     for (i = 0; i < lastPC; i++) {
05127         delete instP[i];
05128     }
05129     delete [] instP;
05130 
05131 }
05132 
05133 int main(int argc, char* argv[])
05134 {
05135     ProgramName = argv[0];
05136 
05137     CalcInit::instance();
05138 
05139     unitTestBool();
05140     unitTestLong();
05141     unitTestFloat();
05142     unitTestWarnings();
05143     unitTestPointer();
05144     unitTestPointerCache();
05145     unitTestNullableLocal();
05146     unitTestStatusRegister();
05147 
05148     printf("all tests passed\n");
05149     exit(0);
05150 }
05151 
05152 boost::unit_test_framework::test_suite *init_unit_test_suite(int,char **)
05153 {
05154     return NULL;
05155 }
05156 
05157 #else
05158 
05159 int main(int argc, char* argv[])
05160 {
05161     return 0;
05162 }
05163 
05164 #endif
05165 
05166 // End testCalc.cpp

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