// Copyright (c) 1996-2009 Nokia Corporation and/or its subsidiary(-ies).
// All rights reserved.
// This component and the accompanying materials are made available
// under the terms of the License "Eclipse Public License v1.0"
// which accompanies this distribution, and is available
// at the URL "http://www.eclipse.org/legal/epl-v10.html".
//
// Initial Contributors:
// Nokia Corporation - initial contribution.
//
// Contributors:
//
// Description:
// f32test\math\t_gen32.cpp
// Generates files to be used in testing whether arithmetic in TReal32 gives
// exactly the same results using the MSDEV complier as on the rack.
// 
//

#include <f32file.h>
#include <e32svr.h>
#include "t_math.h"
#include "../server/t_server.h"

#if defined(__VC32__)
//
// Some symbols generated by the VC++ compiler for floating point stuff.
//
extern "C" {
GLDEF_D TInt _adj_fdiv_m32;
}
#endif

GLDEF_D RTest test(_L("T_GEN32"));

LOCAL_D	RFile f;
LOCAL_D const TFileName fileName32 = _L("T_REAL32.H");

LOCAL_D const TFileName pathName = _L("C:\\E32-MATH\\");
LOCAL_D	TBuf<0x100> buf;
LOCAL_D TBuf8<0x100> buf8;

// Data for tests from T_R32DTA.cpp 
GLREF_D TReal32 addInput[];
GLREF_D TReal32 subInput[];
GLREF_D TReal32 multInput[];
GLREF_D TReal32 divInput[];
//GLREF_D TApprox32 subApprox[];
GLREF_D TReal32 unaryInput[];
GLREF_D TReal32 incDecInput[];
GLREF_D TInt sizeAdd;
GLREF_D TInt sizeSub;
GLREF_D TInt sizeMult;
GLREF_D TInt sizeDiv;
//GLREF_D TInt sizeSubApprox;
GLREF_D TInt sizeUnary;
GLREF_D TInt sizeIncDec;

LOCAL_C void appendStart()
	{
	f.Write(_L8("// Generated by \\E32\\TMATH\\T_GEN32.MAK\n\n"));
	f.Write(_L8("#include <e32std.h>\n\n"));
	f.Write(_L8("#if defined(__WINS__)\n#include \"t_vals.hwg\"\n"));
	f.Write(_L8("#else\n#include \"t_vals.hag\"\n#endif\n"));
	}

LOCAL_C void appendArrayName32(TPtrC aName)
	{
	buf=_L("");
	buf.AppendFormat(_L("const TInt32x %S[] = \n{\n"),&aName);
	buf8.Copy(buf);
	f.Write(buf8);
	}

LOCAL_C void appendValue32(TReal32* aVal)
	{
	buf=_L("");
	buf.AppendFormat(_L("	TInt32x(0x%x),\n"),*(TUint32*)aVal);
	buf8.Copy(buf);
	f.Write(buf8);
	}

LOCAL_C void appendArrayTerm()
	{
	buf8=_L8("};\n\n");
	f.Write(buf8);
	}

LOCAL_C void createAddArray()
//
// Writes an array of results of additions to the header file
//
	{
	TInt ii;
	TReal32 ff;

	appendArrayName32(_L("addArray"));
	for (ii=0; ii<sizeAdd-1; ii++)
		{
		ff=addInput[ii]+addInput[ii+1];
		appendValue32(&ff);
		}
	appendArrayTerm();
	}

LOCAL_C void createSubArray()
//
// Writes an array of results of subtractions to the header file
//
	{
	TInt ii;
	TReal32 ff;

	appendArrayName32(_L("subArray"));
	for (ii=0; ii<sizeSub-1; ii++)
		{
		ff=subInput[ii]-subInput[ii+1];
		appendValue32(&ff);
		}
	appendArrayTerm();

	/*
	appendArrayName32(_L("subApproxArray"));
	for (ii=0; ii<sizeSubApprox; ii++)
		{
		ff=subApprox[ii].f-subApprox[ii].g;
		appendValue32(&ff);
		}
	appendArrayTerm();
	*/
	} 

LOCAL_C void createMultArray()
//
// Writes an array of results of multiplications to the header file
//
	{
	TInt ii;
	TReal32 ff;

	appendArrayName32(_L("multArray"));
	for (ii=0; ii<sizeMult-1; ii++)
		{
		ff=multInput[ii]*multInput[ii+1];
		appendValue32(&ff);
		}
	appendArrayTerm();
	} 

LOCAL_C void createDivArray()
//
// Writes an array of results of divisions to the header file
//
	{
	TInt ii;
	TReal32 ff;

	appendArrayName32(_L("divArray"));
	for (ii=0; ii<sizeDiv-1; ii++)
		{
		if (divInput[ii+1]!=0)
			{
			ff=divInput[ii]/divInput[ii+1];
			appendValue32(&ff);
			}
		}
	appendArrayTerm();
	} 

LOCAL_C void createUnaryArray()
//
// Writes an array of results of unary operations to the header file
//
	{
	TReal32 f;

	appendArrayName32(_L("unaryArray"));
	for (TInt ii=0; ii<sizeUnary; ii++)
		{
		f=-unaryInput[ii];
		appendValue32(&f);
		}
	appendArrayTerm();
	} 

LOCAL_C void createIncDecArrays()
//
// Writes an array of results of pre and post increment and decrement operations to the
// header file
//
	{
	TInt ii;
	TReal32 f;

	appendArrayName32(_L("preIncArray1"));
	for (ii=0; ii<sizeIncDec; ii++)
		{
		f=incDecInput[ii];
		++f;
		appendValue32(&f);
		}
	appendArrayTerm();

	appendArrayName32(_L("preIncArray2"));
	for (ii=0; ii<sizeIncDec; ii++)
		{
		f=incDecInput[ii];
		++f;
		++f;
		appendValue32(&f);
		}
	appendArrayTerm();

	appendArrayName32(_L("preDecArray1"));
	for (ii=0; ii<sizeIncDec; ii++)
		{
		f=incDecInput[ii];
		--f;
		appendValue32(&f);
		}
	appendArrayTerm();

	appendArrayName32(_L("preDecArray2"));
	for (ii=0; ii<sizeIncDec; ii++)
		{
		f=incDecInput[ii];
		--f;
		--f;
		appendValue32(&f);
		}
	appendArrayTerm();

	appendArrayName32(_L("postIncArray1"));
	for (ii=0; ii<sizeIncDec; ii++)
		{
		f=incDecInput[ii];
		f++;
		appendValue32(&f);
		}
	appendArrayTerm();

	appendArrayName32(_L("postIncArray2"));
	for (ii=0; ii<sizeIncDec; ii++)
		{
		f=incDecInput[ii];
		f++;
		f++;
		appendValue32(&f);
		}
	appendArrayTerm();

	appendArrayName32(_L("postDecArray1"));
	for (ii=0; ii<sizeIncDec; ii++)
		{
		f=incDecInput[ii];
		f--;
		appendValue32(&f);
		}
	appendArrayTerm();
	
	appendArrayName32(_L("postDecArray2"));
	for (ii=0; ii<sizeIncDec; ii++)
		{
		f=incDecInput[ii];
		f--;
		f--;
		appendValue32(&f);
		}
	appendArrayTerm();
	} 

LOCAL_C void createArrays()
//
// Create and append to header file all arrays required for T_R32.CPP tests
//
	{
	createAddArray();
	createSubArray();
	createMultArray();
	createDivArray();
	createUnaryArray();
	createIncDecArrays();
	}

GLDEF_C void CallTestsL(void)
//
// Generate TReal32s (and special values if required) and write to header files
//
    {

	test.Title();

	TFileName msg;
	msg=_L("Generating Maths constants to header files:\n ");
	msg+=pathName;
	msg+=fileName32;
	test.Start(msg);

	test.Next(_L("Making directory"));
	TInt r=TheFs.MkDirAll(pathName);
	test(r==KErrNone || r==KErrAlreadyExists);
	test(TheFs.SetSessionPath(pathName)==KErrNone);

	test(f.Replace(TheFs,fileName32,EFileWrite)==KErrNone);
	test.Next(_L("Generating TReal32s"));
	appendStart();
	createArrays();
	f.Close();

	test.End();

	return;
    }
