/*
* Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
* All rights reserved.
* This component and the accompanying materials are made available
* under the terms of "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:
*
*/
#include "CdlCompilerToolkit/CdlTkProcess.h"
#include <iomanip>
using namespace std;
namespace CdlCompilerToolkit {
//
// CleanupResetPtr
//
class CleanupResetPtr
{
public:
CleanupResetPtr(const CCdlTkInterface*& aPtr) : iPtr(aPtr), iValue(aPtr) {}
~CleanupResetPtr() { iPtr = iValue; }
private:
const CCdlTkInterface*& iPtr;
const CCdlTkInterface* iValue;
};
//
// CCdlTkWriteCdlFile
//
CCdlTkWriteCdlFile::CCdlTkWriteCdlFile(const CCdlTkInterface& aCdl)
: iCdl(&aCdl)
{
}
CCdlTkWriteCdlFile::~CCdlTkWriteCdlFile()
{
}
void CCdlTkWriteCdlFile::Process()
{
// this function modifies iCdl, but CleanupResetPtr will restore it at the end (it's also exception safe)
CleanupResetPtr resetPtr(iCdl);
CCdlTkFileCleanup tempFile;
CdlTkUtil::OpenTempOutput(iOut, tempFile);
string targetName = iCdl->FileName();
WriteHeaderComment();
int count = 0;
while (iCdl)
{
if (count++)
WriteSeparator("Header");
WriteHeader();
if (!iCdl->Cpp().empty())
{
WriteSeparator("C++");
WriteCpp();
}
if (!iCdl->DataTypeTranslations().empty())
{
WriteSeparator("Translation");
WriteTranslation();
}
if (!iCdl->ApiList().empty())
{
WriteSeparator("API");
WriteApi();
}
iCdl = iCdl->Extension();
}
iOut.close();
CdlTkUtil::ExportFile(tempFile, targetName);
// resetPtr dtor will restore iCdl to original value
}
void CCdlTkWriteCdlFile::WriteHeaderComment()
{
iOut << "// " << iCdl->FileName() << endl;
iOut << "// This file was generated by:" << endl;
iOut << "// " << CdlTkUtil::CommandLine() << endl;
iOut << iCdl->AdditionalComment() << endl;
}
void CCdlTkWriteCdlFile::WriteHeader()
{
const CCdlTkInterfaceHeader& header = iCdl->Header();
if (!header.Name().empty())
iOut << "Name: " << header.Name() << endl;
iOut << "Version: " << header.Version().Major() << "." << header.Version().Minor() << endl;
if (header.Uid())
iOut << "UID: 0x" << setbase(16) << setw(8) << setfill('0') << header.Uid() << endl;
const CCdlTkInterfaceHeader::CFlags& flags = header.Flags();
for (int ii=0; ii<flags.Count(); ii++)
{
if (flags.IsSet(ii))
iOut << "Flag: " << flags.FlagName(ii) << endl;
}
}
void CCdlTkWriteCdlFile::WriteSeparator(const string& aSection)
{
iOut << endl;
iOut << "%% " << aSection << endl;
iOut << endl;
}
void CCdlTkWriteCdlFile::WriteCpp()
{
const CCdlTkCpp& cpp = iCdl->Cpp();
if(cpp.size())
{
CCdlTkCpp::const_iterator pStart = cpp.begin();
CCdlTkCpp::const_iterator pFinish = cpp.end() ;
// ignore the first line if it's empty
if(pStart->empty())
++pStart;
// if the last line isn't empty, move the iterator back to the end
if(!(--pFinish)->empty())
++pFinish;
for (CCdlTkCpp::const_iterator pLine = pStart; pLine != pFinish; ++pLine)
{
iOut << *pLine << endl;
}
}
}
void CCdlTkWriteCdlFile::WriteTranslation()
{
const CCdlTkDataTypeTranslations& translations = iCdl->DataTypeTranslations();
for (CCdlTkDataTypeTranslations::const_iterator pTrans = translations.begin(); pTrans != translations.end(); ++pTrans)
{
if (pTrans->Source() == CCdlTkDataTypeTranslation::EFromCdl)
{
iOut << pTrans->Type() << " # " << pTrans->Definition() << " # " << pTrans->PointerReference() << endl;
}
}
}
void CCdlTkWriteCdlFile::WriteApi()
{
const CCdlTkApiList& apiList = iCdl->ApiList();
for (CCdlTkApiList::const_iterator pApi = apiList.begin(); pApi != apiList.end(); ++pApi)
{
CCdlTkApi& api = **pApi;
iOut << api.Comment();
iOut << api.ReturnType() << " " << api.Name() << api.ParamsTypeAndNameList() << ";" << endl;
iOut << endl;
}
}
} // end of namespace CdlCompilerToolkit