uitools_plat/cdl_api/inc/CdlCompilerToolkit/CdlTkProcess.h
author Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
Mon, 18 Jan 2010 21:13:05 +0200
changeset 1 b700e12870ca
parent 0 f58d6ec98e88
permissions -rw-r--r--
Revision: 201001 Kit: 201003

/*
* 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:
*
*/
#ifndef CDLTKPROCESS_H
#define CDLTKPROCESS_H

#include <CdlCompilerToolkit/CdlTkInterface.h>
#include <CdlCompilerToolkit/CdlTkInstance.h>
#include <fstream>
#include <memory>

namespace CdlCompilerToolkit {
class CCdlTkApi;
class CCdlTkInterface;

/**
* CCdlTkProcess
* Does very little yet.
*/
class CCdlTkProcess
	{
public:
	/**
    * destructor
    */
	virtual ~CCdlTkProcess();
	/**
    * virtual method to invoke processing
    */
	virtual void Process() = 0;

public:
	static std::string CdlBaseNameAndPath(const CCdlTkInterface& aCdl);
	static void AssertInterfaceNotExtended(const CCdlTkInterface& aCdl);
	};


/**
* Base class for processes that write source files
*/
class CCdlTkSourceFileWriter : public CCdlTkProcess
	{
public:
	/**
    * destructor
    */
	~CCdlTkSourceFileWriter();

protected:
	/**
    * Writes an opening namespace declaration for a CDL interface to a stream
    * @param aCdl the CDL interface defining the namespace
	* @param aStream the stream to write to
    */
	void WriteNamespaceStart(const CCdlTkInterface& aCdl, std::ofstream& aStream) const;
	/**
    * Writes a closing namespace declaration for a CDL interface to a stream
    * @param aCdl the CDL interface defining the namespace
	* @param aStream the stream to write to
    */
	void WriteNamespaceEnd(const CCdlTkInterface& aCdl, std::ofstream& aStream) const;
	/**
    * Calculates a header guard identifier for a file
    * @param aFileName the file to be protected by the header guard
    * @return the header guard identifer
    */
	std::string HeaderGuardName(const std::string& aFileName) const;
	/**
    * Writes the starting declarations for a header file guard
    * @param aName the file to be protected by the header guard
	* @param aStream the stream to write to
    * @return 
    */
	void WriteHeaderGuardStart(const std::string& aName, std::ofstream& aStream) const;
	/**
    * Writes the ending declaration for a header file guard
    * @param aName the file to be protected by the header guard
	* @param aStream the stream to write to
    * @return 
    */
	void WriteHeaderGuardEnd(const std::string& aName, std::ofstream& aStream) const;
	};


/**
* Process for writing a common definitions header file (.cdl.common.h)
*/
class CCdlTkWriteCommonDefs : public CCdlTkSourceFileWriter
	{
public:
	static void ExportCommonDefs(const CCdlTkInterface& aCdl, const std::string& aFileName);

private:
	/**
    * constructor
    * @param aCdl the interface to write. 
	* @param aStream the stream to write to
    */
	CCdlTkWriteCommonDefs(const CCdlTkInterface& aCdl, std::ofstream& aStream, const std::string& aFileName);
	/**
    * Creates and writes a common definitions header file (.cdl.common.h)
    */
	void Process();
	void ProcessHRH(std::ofstream& aStream);

private:
	void WriteApiEnum();
	void WriteApiTypedefs();
	std::string TypedefForApi(const CCdlTkApi& aApi) const;
	std::ofstream& Stream();

private:
	const CCdlTkInterface& iCdl;
	std::ofstream* iStream;
	const std::string& iFileName;
	};


/**
* Process for writing a C++ client header file for a C++ interface
*/
class CCdlTkWriteClientHeader : public CCdlTkSourceFileWriter
	{
public:
	/**
    * constructor
    * @param aCdl The interface to write
    */
	CCdlTkWriteClientHeader(const CCdlTkInterface& aCdl);
	/**
    * destructor
    */
	~CCdlTkWriteClientHeader();
	/**
    * Creates and writes the header files required by a C++ client to use
	* a CDL interface.
    */
	void Process();

protected:
	std::string ClientReturnType(const CCdlTkApi& aApi) const;

private:
	void ProcessApi(std::ofstream& aStream, const std::string& aFileName) const;
	void WriteApi(const CCdlTkApi& aApi, std::ofstream& aStream, bool aCInstanceMember, const std::string& aIndent) const;

protected:
	const CCdlTkInterface& iCdl;
	};


/**
* Process for syntax checking a CDL interface
*/
class CCdlTkSyntaxCheck : public CCdlTkWriteClientHeader
	{
	/**
    * constructor
    * @param aCdl the interface to check
    */
	CCdlTkSyntaxCheck(const CCdlTkInterface& aCdl);
	/**
    * destructor
    */
	~CCdlTkSyntaxCheck();
	/**
    * Sets parameters to pass to the C++ compiler which will do the syntax check
    * @param aParams the parameters for the compiler
    */
	void SetParams(std::string aParams);
	/**
    * Runs the syntax checking process
    */
	void Process();

private: // syntax checking
	void WriteSyntaxCheckCpp(std::string aName) const;
	void DoSyntaxCheckBuild(std::string aName) const;
	void WriteSyntaxCheckApi(const CCdlTkApi& aApi, std::ofstream& aStream) const;

private:
	std::string iParams;
	};


/**
* A process for writing a customisation instance to C++ source files
*/
class CCdlTkWriteInstance : public CCdlTkSourceFileWriter
	{
public:
	/**
    * constructor
    * @param aInstance The instance to write
    */
	CCdlTkWriteInstance(const CCdlTkInstance& aInstance);
	/**
    * destructor
    */
	~CCdlTkWriteInstance();
	/**
    * Run the process of creating and writing the C++ source files for a
	* customisation instance.
    */
	void Process();

private:
	void ProcessCdl() const;
	void ProcessInstanceApi(std::ofstream& aStream, const std::string& aFileName) const;
	void ProcessInstance(std::ofstream& aStream, const std::string& aHeaderName) const;
	void ProcessInstanceHeader(std::ofstream& aStream, const std::string& aFileName) const;
	void ProcessInstanceHrh(std::ofstream& aStream, const std::string& aFileName) const;
	void InitReplace(const std::string& aHeaderName);

private:
	const CCdlTkInstance& iInstance;
	const CCdlTkInterface& iCdl;
	CdlTkUtil::CReplaceSet iReplace;
	};


/**
* A process to write the source and build files for a DLL
*/
class CCdlTkWriteDll : public CCdlTkSourceFileWriter
	{
public:
	/**
    * constructor
    * @param aDll the DLL to create source and build files for
    */
	CCdlTkWriteDll(const CCdlTkDll& aDll);
	/**
    * destructor
    */
	~CCdlTkWriteDll();
	/**
    * Runs the process of creating and writing source and build files for a DLL
    */
	void Process();

private:
	void WriteBldInf() const;
	void WriteMmp() const;
	void WriteMainCpp() const;
	void WriteInstanceIdHeader() const;
	void WriteEcomRss() const;
	void WriteEcomDetailRss() const;

private:
	const CCdlTkDll& iDll;
	};


/**
* Process for writing a CDL file
*/
class CCdlTkWriteCdlFile : public CCdlTkProcess
	{
public:
	/**
    * constructor
    * @param aCdl the CDL interface to write
    */
	CCdlTkWriteCdlFile(const CCdlTkInterface& aCdl);
	/**
    * destructor
    */
	~CCdlTkWriteCdlFile();
	/**
    * Run the process of writing the CDL interface to a CDL file
    */
	void Process();

private:
	void WriteHeaderComment();
	void WriteHeader();
	void WriteSeparator(const std::string& aSection);
	void WriteCpp();
	void WriteTranslation();
	void WriteApi();

private:
	const CCdlTkInterface* iCdl;
	std::ofstream iOut;
	};


/**
* A process for reading a CDL file
*/
class CCdlTkCdlFileParser : public CCdlTkProcess
	{
public:
	/**
    * constructor
    * @param aFileName the name of the CDL file to be read
    * @return 
    */
	CCdlTkCdlFileParser(const std::string& aFileName);
	/**
    * destructor
    */
	~CCdlTkCdlFileParser();
	/**
    * Loads and parses a CDL file
    * @param aMergeExtensions tells the parser whether to merge and interface
	* extensions to form a monolithic API
    * @return an auto pointer to the CDL interface read from the CDL file
    */
	std::auto_ptr<CCdlTkInterface> LoadAndParse(bool aMergeExtensions);
	/**
    * virtual Process method from CCdlTkProcess
	* this function is not to be used
    */
	void Process();

private:
	enum TParseState {EHeader, ECpp, ETranslation, EApi, EEnd, EParseStateCount};

private:
	void OpenStream();
	void ParseStream(CCdlTkInterface& aCdl);
	void CloseStream();

	void ParseHeader(CCdlTkInterface& aCdl, const std::string& aLine);
	void ParseCpp(CCdlTkInterface& aCdl, const std::string& aLine);
	void ParseTranslationLine(CCdlTkInterface& aCdl, const std::string& aLine);
	void ParseApi(CCdlTkInterface& aCdl, const std::string& aLine);
	std::auto_ptr<CCdlTkApi> CreateApi(CCdlTkInterface& aCdl, std::string& aLine);
	void ParseApiParams(CCdlTkApiParams& aParams, std::string& aList);
	void ParseNameTypeAndDefaultValue(std::string& aStr, std::string& aName, std::string& aType, std::string& aDefaultValue);
	void ParseTranslationText(CCdlTkDataTypeTranslation& aTrans, std::string& aLine);

	std::string GetLine();
	bool IsSectionBoundary(const std::string& aLine, TParseState& aState);
	bool MatchLineStart(const std::string& aLine, const std::string& aHeader, std::string& aVal);
	void StripComments(std::string& aStr, std::string& aComment);

	void SyntaxError(const std::string& aErr);

private:
	std::string iFileName;
	std::ifstream iIn;
	TParseState iState;
	int iCurrentSourceLineNum;
	std::string iApiBuf;			// buffer for collecting API declarations
	std::string iComment;			// buffer for collecting comments
	};


/**
* Observer mixin interface for the interface checking process
*/
class MCdlTkApiCheckObserver
	{
public:
	/**
    * Called when an interface check is started
    */
	virtual void StartCheck() = 0;
	/**
    * Called when an interface check is complete
    */
	virtual void CheckComplete() = 0;
	/**
    * Called when an API is found that appears in both interfaces
    */
	virtual void ApiInBoth(const CCdlTkApi& aApi) = 0;
	/**
    * Called when an API is found that is only in the right hand interface
    */
	virtual void ApiNotInLeft(const CCdlTkApi& aApi) = 0;
	/**
    * Called when an API is found that is only in the left hand interface
    */
	virtual void ApiNotInRight(const CCdlTkApi& aApi) = 0;

	virtual ~MCdlTkApiCheckObserver(){}
	};

/**
* process for checking (diffing) two CDL interfaces' APIs
*/
class CCdlTkApiChecker : public CCdlTkProcess
	{
public:
	/**
    * constructor
    * @param aLeft a CDL interface to check
    * @param aRight another CDL interface to check
    * @param aObserver the observer of the results of the check
    */
	CCdlTkApiChecker(const CCdlTkInterface& aLeft, 
					 const CCdlTkInterface& aRight, 
					 MCdlTkApiCheckObserver& aObserver);
	/**
    * destructor
    */
	~CCdlTkApiChecker();
	/**
    * Run the process of checking the interfaces' APIs
    */
	void Process();

private:
	typedef CCdlTkApiList::const_iterator CApiListIter;
	void FailLeft(CApiListIter& aFrom, const CApiListIter& aTo) const;
	void FailRight(CApiListIter& aFrom, const CApiListIter& aTo) const;
	void ReSync(CApiListIter& posLeft, CApiListIter& posRight, 
				const CApiListIter& leftEnd, const CApiListIter& rightEnd) const;

private:
	const CCdlTkInterface& iLeft;
	const CCdlTkInterface& iRight;
	MCdlTkApiCheckObserver& iObserver;
	};

}	// end of namespace CdlCompilerToolkit

#endif