williamr@4: /** williamr@4: * @file testscripts.h Defines classes for reading a configuration file williamr@4: * williamr@4: * @note Configuration File Format: williamr@4: * williamr@4: * [Defaults] williamr@4: * defaults= another_config_file.txt williamr@4: * williamr@4: * [SectionName] williamr@4: * variable= value williamr@4: * variable2= value2 williamr@4: * variable= value3 williamr@4: * williamr@4: * [SectionName2] williamr@4: * variable= value williamr@4: * williamr@4: * endscript williamr@4: * williamr@4: * williamr@4: * @note Explanation: williamr@4: * williamr@4: * A configuration file is made up of a number of "sections", each of which can contain a number of "items" (name, value combination). williamr@4: * williamr@4: * "Sections" must have a name and be surrounded by square backets, e.g.: williamr@4: * williamr@4: * [SectionName] williamr@4: * williamr@4: * williamr@4: * Each "item" consists of consists of a name, followed by an equals sign, followed by blank space, followed by the value to assign to that variable. williamr@4: * williamr@4: * The value can be of any length, contain whitespace and span multiple lines. The value ends when the next item or section is found. E.g: williamr@4: * williamr@4: * Simple Item: williamr@4: * williamr@4: * variable= value williamr@4: * williamr@4: * Two items on one line: williamr@4: * williamr@4: * variable= value variable2= value2 williamr@4: * williamr@4: * Multi-line item: williamr@4: * williamr@4: * variable= This variable williamr@4: * spans multiple williamr@4: * lines williamr@4: * williamr@4: * williamr@4: * @note Parsing stops at End-Of-File or if the tag "endscript" (without the quotes) appears in the file. williamr@4: * williamr@4: * @note A section may take some default values from another section or config file williamr@4: * williamr@4: * To specify default values for all sections, add a section at the start of the config file called [Defaults], e.g.: williamr@4: * williamr@4: * [Defaults] williamr@4: * sc= +447785016005 williamr@4: * williamr@4: * To read default values from another config file, add an item with name "defaults" and value is the name of the file. E.g.: williamr@4: * williamr@4: * defaults= another_config_file.txt williamr@4: williamr@4: */ williamr@4: williamr@4: williamr@4: #ifndef __TEST_CONFIG_FILE_PARSER_H__ williamr@4: #define __TEST_CONFIG_FILE_PARSER_H__ williamr@4: williamr@4: #include williamr@4: #include williamr@4: williamr@4: class CTestConfigSection; williamr@4: class CTestConfigItem; williamr@4: class RFs; williamr@4: class TParse; williamr@4: class RFile; williamr@4: williamr@4: _LIT(KScriptPanic, "TEST-SCRIPT"); williamr@4: _LIT(KScriptPathSep,"\\"); williamr@4: _LIT8(KScriptSectionStart, "["); williamr@4: _LIT8(KScriptSectionEnd, "]"); williamr@4: _LIT8(KScriptCRLF, "\r\n"); williamr@4: _LIT8(KScriptCRLF8, "\r\n"); williamr@4: _LIT8(KScriptLF, "\n"); williamr@4: _LIT8(KScriptCR, "\r"); williamr@4: _LIT8(KScriptItemEnd, "="); williamr@4: _LIT8(KScriptItemEnd8, "="); williamr@4: _LIT8(KScriptSpace8, " "); williamr@4: _LIT8(KScriptDefaults, "Defaults"); williamr@4: _LIT8(KScriptDefault1, "Def"); williamr@4: _LIT8(KScriptDefault2, "Default"); williamr@4: _LIT8(KScriptCommentStart, "#"); williamr@4: const TInt KScriptLFChar = '\n'; williamr@4: const TInt KScriptCRChar = '\r'; williamr@4: williamr@4: class CTestConfig : public CBase williamr@4: /** williamr@4: * @internalComponent williamr@4: * @deprecated williamr@4: */ williamr@4: { williamr@4: public: williamr@4: IMPORT_C static CTestConfig* NewLC(RFs& aFs, const TDesC& aComponent, const TDesC& aScriptFile); williamr@4: IMPORT_C static CTestConfig* NewLC(RFs& aFs, const TDesC& aComponent); williamr@4: IMPORT_C ~CTestConfig(); williamr@4: williamr@4: IMPORT_C const TDesC8& ItemValue(const TDesC8& aSection, const TDesC8& aItem, const TDesC8& aDefault) const; williamr@4: IMPORT_C TInt ItemValue(const TDesC8& aSection, const TDesC8& aItem, const TInt aDefault) const; williamr@4: williamr@4: IMPORT_C void ReadScriptL(const TDesC& aScript); williamr@4: williamr@4: inline const RPointerArray& Sections() const; williamr@4: inline RPointerArray& Sections(); williamr@4: williamr@4: IMPORT_C const CTestConfigSection* Section(const TDesC8& aSectionName) const; //return NULL if section not found williamr@4: IMPORT_C CTestConfigSection* Section(const TDesC8& aSectionName); //return NULL if section not found williamr@4: inline const CTestConfigSection& operator[](TInt aIndex) const {return *iSections[aIndex];} williamr@4: inline CTestConfigSection& operator[](TInt aIndex) {return *iSections[aIndex];} williamr@4: williamr@4: IMPORT_C static TInt CountElements(const TDesC8& aInput, TChar aDelimiter); williamr@4: IMPORT_C static TInt GetElement(const TDesC8& aInput, TChar aDelimiter, TInt aIndex, TInt& aOutput); williamr@4: IMPORT_C static TInt GetElement(const TDesC8& aInput, TChar aDelimiter, TInt aIndex, TPtrC8& aOutput, TBool aTrimOutput = ETrue); williamr@4: IMPORT_C static TPtrC8 Trim(const TDesC8& aInput); williamr@4: IMPORT_C static TPtrC8 TrimLeft(const TDesC8& aInput); williamr@4: IMPORT_C static TPtrC8 TrimRight(const TDesC8& aInput); williamr@4: williamr@4: IMPORT_C static HBufC8* ReplaceLC(const TDesC8& aOld, const TDesC8& aNew, const TDesC8& aOldString); williamr@4: IMPORT_C static TInt ResolveFile(RFs& aFs, const TDesC& aComponent, const TDesC& aFileName, TParse& aParseOut); williamr@4: williamr@4: IMPORT_C void WriteFileL(const TDesC& aFileName); williamr@4: IMPORT_C TBool operator==(const CTestConfig& aFile) const; williamr@4: williamr@4: IMPORT_C void AddSectionL(CTestConfigSection& aSection); williamr@4: williamr@4: protected: williamr@4: williamr@4: CTestConfig(RFs& aFs); williamr@4: void ConstructL(const TDesC& aComponent); williamr@4: williamr@4: TPtrC8 ParseValue(const TDesC8& aText, const TLex8& aInput, TInt aCurrentItemStart) const; williamr@4: void ParseAndSetItemValueL(const TDesC8& aText, const TLex8& aInput, TInt aCurrentItemStart, CTestConfigItem*& arCurrentItem); williamr@4: void CopyInDefaultsL(CTestConfigSection& aSection, const TDesC& aDefaultFile); williamr@4: williamr@4: HBufC8* ReadFileL(const TDesC& aFile) const; williamr@4: williamr@4: TBool IsDefaultSection(const TDesC8& aSectionName) const; williamr@4: static TInt GetNextElement(TLex8& aInput, TChar aDelimiter, TPtrC8& aOutput); williamr@4: TBool IsNewSection(const TDesC8& aSource, const TLex8& aInput) const; williamr@4: TBool IsNewItem(const TDesC8& aSource, const TLex8& aLex, TPtrC8& aItem, TInt& aStartOfValue) const; williamr@4: TBool IsNewComment(const TDesC8& aSource, const TLex8& aLex) const; williamr@4: TBool IsAtStartOfNewLine(const TDesC8& aSource, const TLex8& aLex, TBool aIgnoreSpaces) const; williamr@4: void SkipToNextLine(TLex8& aInput) const; williamr@4: williamr@4: williamr@4: protected: williamr@4: williamr@4: RFs& iFs; williamr@4: HBufC* iComponent; williamr@4: RPointerArray iSections; williamr@4: }; williamr@4: williamr@4: class CTestConfigSection : public CBase williamr@4: /** williamr@4: * @internalComponent williamr@4: * @deprecated williamr@4: */ williamr@4: { williamr@4: friend class CTestConfig; williamr@4: williamr@4: public: williamr@4: IMPORT_C static CTestConfigSection* NewLC(const TDesC8& aSectionName); williamr@4: IMPORT_C static CTestConfigSection* NewLC(const TDesC8& aSectionName, CTestConfigSection& aDefaults); williamr@4: IMPORT_C ~CTestConfigSection(); williamr@4: williamr@4: inline const TDesC8& SectionName() const; williamr@4: williamr@4: IMPORT_C const CTestConfigItem* Item(const TDesC8& aItemTag) const; //return NULL if the item does not exist williamr@4: IMPORT_C CTestConfigItem* Item(const TDesC8& aItemTag); //return NULL if the item does not exist williamr@4: IMPORT_C const CTestConfigItem* Item(const TDesC8& aItemTag,TInt aIndex) const; //return NULL if the item does not exist williamr@4: IMPORT_C CTestConfigItem* Item(const TDesC8& aItemTag,TInt aIndex); //return NULL if the item does not exist williamr@4: williamr@4: IMPORT_C const TDesC8& ItemValue(const TDesC8& aItemTag, const TDesC8& aDefault) const; williamr@4: IMPORT_C TInt ItemValue(const TDesC8& aItemTag, TInt aDefault) const; williamr@4: williamr@4: IMPORT_C CTestConfigItem& AddItemL(const TDesC8& aItemTag, const TDesC8& aValue); williamr@4: IMPORT_C void DeleteItemsL(const TDesC8& aItem); williamr@4: williamr@4: inline const RPointerArray& Items() const {return iItems;} williamr@4: inline RPointerArray& Items() {return iItems;} williamr@4: williamr@4: IMPORT_C TInt ItemCount(const TDesC8& aItemTag) const; williamr@4: IMPORT_C void ItemsL(RPointerArray& aArray, const TDesC8& aItemTag); williamr@4: IMPORT_C void ItemsL(RPointerArray& aArray, const TDesC8& aItemTag) const; williamr@4: williamr@4: inline const CTestConfigItem& operator[](TInt aIndex) const {return *iItems[aIndex];} williamr@4: williamr@4: inline void SetDefaultsL(const CTestConfigSection& aDefaults); williamr@4: inline CTestConfigSection* Defaults() const {return iDefaults;} williamr@4: williamr@4: IMPORT_C CTestConfigSection* CopyLC() const; williamr@4: williamr@4: void WriteL(RFile& aFile) const; williamr@4: TBool operator==(const CTestConfigSection& aFile) const; williamr@4: williamr@4: private: williamr@4: void ConstructL(const TDesC8& aSectionName); williamr@4: CTestConfigSection(); williamr@4: RPointerArray iItems; williamr@4: HBufC8* iSectionName; williamr@4: CTestConfigSection* iDefaults; williamr@4: }; williamr@4: williamr@4: class CTestConfigItem : public CBase williamr@4: /** williamr@4: * @internalComponent williamr@4: * @deprecated williamr@4: */ williamr@4: { williamr@4: friend class CTestConfigSection; williamr@4: friend class CTestConfig; williamr@4: williamr@4: public: williamr@4: IMPORT_C static CTestConfigItem* NewLC(CTestConfigSection& aParent, const TDesC8& aItem, const TDesC8& aValue); williamr@4: inline CTestConfigItem* CopyLC() const; williamr@4: williamr@4: IMPORT_C ~CTestConfigItem(); williamr@4: inline const TDesC8& Item() const; williamr@4: inline const TDesC8& Value() const; williamr@4: williamr@4: void WriteL(RFile& aFile) const; williamr@4: TBool operator==(const CTestConfigItem& aItem) const {return Item() == aItem.Item() && Value() == aItem.Value();} williamr@4: williamr@4: public: williamr@4: williamr@4: CTestConfigSection& iParent; williamr@4: williamr@4: private: williamr@4: CTestConfigItem(CTestConfigSection& aParent); williamr@4: void ConstructL(const TDesC8& aItem, const TDesC8& aValue); williamr@4: HBufC8* iItem; williamr@4: HBufC8* iValue; williamr@4: }; williamr@4: williamr@4: #include "testconfigfileparser.inl" williamr@4: williamr@4: #endif