Fix merging bug where downstream items somtimes got ignored if they appear after an upstream-only item. Also, reduce the severity of the validation error if a tech-domain is not recognised on a non-Foundation package.
/*
* Copyright (c) 2005-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:
*
*/
#include "main.h"
#include "localise.h"
#ifdef __VC32__
#pragma warning( push, 1 ) // MS STL libraries do not compile cleanly, temporarily set warning level to 1
#pragma warning( disable : 4710 ) // function not inlined.
#pragma warning( disable : 4530 ) // function not inlined.
#endif
#include <stdio.h>
#include <iostream>
#include "ERRORHAN.H"
#if defined(__MSVCDOTNET__) || defined(__TOOLS2__)
using std::ifstream;
using std::cerr;
using std::endl;
#endif //__MSVCDOTNET__
/******************************************************************************************
**
** RlsItemRequirements
**
******************************************************************************************/
RlsItemRequirements::RlsItemRequirements(String aRlsName, int aRequirement)
:iRlsName(aRlsName),
iRequirement(aRequirement)
{}
RlsItemRequirements::RlsItemRequirements(const RlsItemRequirements & aRlsItemRequirements)
:iRlsName(aRlsItemRequirements.iRlsName),
iRequirement(aRlsItemRequirements.iRequirement)
{}
RlsItemRequirements::~RlsItemRequirements()
{}
/******************************************************************************************
**
** CommandRequirementsHolder
**
******************************************************************************************/
CommandRequirementsHolder::CommandRequirementsHolder(String aCommandName)
:iCommandName(aCommandName)
{
iRlsRequirements.clear();
}
CommandRequirementsHolder::CommandRequirementsHolder(const CommandRequirementsHolder & aCommandRequirmentsHolder)
:iCommandName(aCommandRequirmentsHolder.iCommandName)
{
for(unsigned int j = 0; j < aCommandRequirmentsHolder.iRlsRequirements.size() ; j++)
{
iRlsRequirements.push_back(aCommandRequirmentsHolder.iRlsRequirements[j]);
}
}
CommandRequirementsHolder::~CommandRequirementsHolder()
{}
/******************************************************************************************
**
** TagParameterData
**
******************************************************************************************/
TagParameterData::TagParameterData(String aTagParameter)
:iTagParameter(aTagParameter)
{}
TagParameterData::TagParameterData(const TagParameterData & aTagParameterData)
:iTagParameter(aTagParameterData.iTagParameter)
{}
TagParameterData::~TagParameterData()
{}
void TagParameterData::SetTagParameter(String aTagParameter)
{
iTagParameter = aTagParameter;
}
String TagParameterData::GetTagParameter()
{
return iTagParameter;
}
/******************************************************************************************
**
** CommentRequirement
**
******************************************************************************************/
CommentRequirement::CommentRequirement(int aRequirementStatus, String aDefaultParameter)
:iRequirementStatus(aRequirementStatus),
iDefaultParameter(aDefaultParameter)
{
}
CommentRequirement::CommentRequirement(const CommentRequirement & aCommentRequirement)
:iRequirementStatus(aCommentRequirement.iRequirementStatus),
iDefaultParameter(aCommentRequirement.iDefaultParameter)
{
}
CommentRequirement::~CommentRequirement()
{}
String CommentRequirement::GetDefault()
{
return iDefaultParameter;
}
int CommentRequirement::GetRequirementStatus()
{
return iRequirementStatus;
}
/******************************************************************************************
**
** CommentRequirementPair
**
******************************************************************************************/
CommentRequirementPair::CommentRequirementPair(String aRlsItem, int aStatus, String aDefault)
:iRlsItem(aRlsItem),
iCommentRequirementData(aStatus, aDefault)
{
}
CommentRequirementPair::CommentRequirementPair(const CommentRequirementPair & aCommentRequirementPair)
:iRlsItem(aCommentRequirementPair.iRlsItem),
iCommentRequirementData(aCommentRequirementPair.iCommentRequirementData)
{}
CommentRequirementPair::~CommentRequirementPair()
{}
int CommentRequirementPair::GetRequirementStatus()
{
return iCommentRequirementData.GetRequirementStatus();
}
String CommentRequirementPair::CheckIfOptionalAndHasDefault(String aRlsTypeName, String aCommandName)
{ // returns a String containing a line which needs to be written out to the rpp file, or returns ""
String optionalLineToAdd = "";
if(iRlsItem == aRlsTypeName)
{
int requirementStatus = iCommentRequirementData.GetRequirementStatus();
if(requirementStatus == EOptionalWithDefault)
{
String defaultValue = iCommentRequirementData.GetDefault();
if(defaultValue.Length()) // will only return true if a default exists
{
optionalLineToAdd = "@";
optionalLineToAdd += aCommandName;
String tempString(" ");
optionalLineToAdd += tempString;
optionalLineToAdd += defaultValue;
tempString = "\n";
optionalLineToAdd += tempString;
}
}
}
return optionalLineToAdd;
}
String CommentRequirementPair::GetRlsItem()
{
return iRlsItem;
}
void CommentRequirementPair::SetRlsItem(String aRlsItem)
{
iRlsItem = aRlsItem;
}
/******************************************************************************************
**
** CommentTag
**
******************************************************************************************/
CommentTag::CommentTag(String aTagType, bool aTagDeclared)
:iTagDeclared( aTagDeclared ),
iParameterType( aTagType )
{
iPermissibleParameters.clear();
iRequirements.clear();
}
CommentTag::CommentTag(const CommentTag & aCommentTag)
:iTagDeclared( aCommentTag.iTagDeclared ),
iParameterType( aCommentTag.iParameterType )
{
unsigned int j;
for(j=0; j< aCommentTag.iPermissibleParameters.size(); j++)
{
iPermissibleParameters.push_back(aCommentTag.iPermissibleParameters[j]);
}
for(j=0; j< aCommentTag.iRequirements.size(); j++)
{
iRequirements.push_back(aCommentTag.iRequirements[j]);
}
}
CommentTag::~CommentTag()
{}
String CommentTag::CheckIfOptionalAndHasDefault(String aRlsTypeName, String aCommandName)
{
if(iTagDeclared)
{
for(unsigned int j=0; j<iRequirements.size(); j++)
{
String defaultParameter = iRequirements[j].CheckIfOptionalAndHasDefault(aRlsTypeName, aCommandName);
if(defaultParameter.Length())
return defaultParameter; // returns default parameter if it exists
}
}
return ""; // returns "" if no default parameter exists
}
int CommentTag::GetRequirementStatus(String aRlsItem)
{
for(unsigned int j=0; j<iRequirements.size(); j++)
{
if(iRequirements[j].GetRlsItem() == aRlsItem)
{
int requirementStatus = iRequirements[j].GetRequirementStatus();
return requirementStatus;
}
}
return EForbidden;
}
bool CommentTag::IsTagLegalForRlsType(String aRlsTypeName)
{
for(unsigned int j=0; j<iRequirements.size(); j++)
{
if(iRequirements[j].GetRlsItem() == aRlsTypeName)
{
return iRequirements[j].GetRequirementStatus() != EForbidden ? true : false;
}
}
return false;
}
bool CommentTag::IsParameterAlreadyDeclared(String aTagParameter)
{
for(int j=0; j<GetNumberOfPermissibleParameters(); j++)
{
if(iPermissibleParameters[j].GetTagParameter() == aTagParameter)
{
return true; // returns true if the given parameter is already declared
}
}
return false;
}
String CommentTag::GetPermissibleParameter(int aIndex) // returns pointer to aIndex-th parameter
{
return iPermissibleParameters[aIndex].GetTagParameter();
}
int CommentTag::GetNumberOfPermissibleParameters()
{
return iPermissibleParameters.size();
}
bool CommentTag::IsTagDeclared()
{
return iTagDeclared;
}
void CommentTag::SetDeclared()
{
iTagDeclared = true;
}
void CommentTag::SetParameterType(String aParameterType)
{
iParameterType = aParameterType;
}
String CommentTag::GetParameterType()
{
return iParameterType;
}
void CommentTag::AddTagParameterData(String aTagParameterData)
{
TagParameterData dataToAdd( aTagParameterData );
iPermissibleParameters.push_back( dataToAdd );
}
void CommentTag::AddRequirements(String aRlsItem, int aRequired, String aDefault)
{
CommentRequirementPair commentRequirementPair( aRlsItem, aRequired, aDefault );
iRequirements.push_back( commentRequirementPair );
}
/******************************************************************************************
**
** CommentTag
**
******************************************************************************************/
CommentTagPair::CommentTagPair(String aCommandName, String aParameterType, bool aTagDeclared)
:iCommandName(aCommandName),
iTagVariables(aParameterType, aTagDeclared)
{}
CommentTagPair::CommentTagPair(const CommentTagPair & aCommentTagPair)
:iCommandName(aCommentTagPair.iCommandName),
iTagVariables(aCommentTagPair.iTagVariables)
{}
CommentTagPair::~CommentTagPair()
{}
String CommentTagPair::CheckIfOptionalAndHasDefault(String aRlsTypeName)
{
return iTagVariables.CheckIfOptionalAndHasDefault(aRlsTypeName, iCommandName);
}
int CommentTagPair::GetRequirementStatus(String aRlsItem)
{
return iTagVariables.GetRequirementStatus( aRlsItem );
}
bool CommentTagPair::IsTagLegalForRlsType(String aRlsTypeName)
{
return iTagVariables.IsTagLegalForRlsType(aRlsTypeName);
}
bool CommentTagPair::IsParameterAlreadyDeclared(String aTagParameter)
{
return iTagVariables.IsParameterAlreadyDeclared(aTagParameter);
}
String CommentTagPair::GetPermissibleParameter(int aIndex)
{
return iTagVariables.GetPermissibleParameter(aIndex);
}
int CommentTagPair::GetNumberOfPermissibleParameters()
{
return iTagVariables.GetNumberOfPermissibleParameters();
}
void CommentTagPair::SetCommandName(String aCommandName)
{
iCommandName = aCommandName;
}
String CommentTagPair::GetCommandName()
{
return iCommandName;
}
void CommentTagPair::SetTagDeclared()
{
iTagVariables.SetDeclared();
}
bool CommentTagPair::TagDeclared()
{
return iTagVariables.IsTagDeclared();
}
String CommentTagPair::GetParameterType()
{
return iTagVariables.GetParameterType();
}
void CommentTagPair::AddPermissibleParameter(String aPermissibleParameter)
{
iTagVariables.AddTagParameterData( aPermissibleParameter );
}
void CommentTagPair::AddRlsItem(String aRlsItem, int aRequired, String aDefault)
{
iTagVariables.AddRequirements(aRlsItem, aRequired, aDefault);
}
/******************************************************************************************
**
** LocalisationLine
**
******************************************************************************************/
LocalisationLine::LocalisationLine(String aFileName, int aFirstLine)
:iAnalysed(false),
iFirstLine(aFirstLine),
iLastLine(aFirstLine),
iFileName(aFileName)
{
iData.clear();
}
LocalisationLine::LocalisationLine(const LocalisationLine & aLocalisationLine)
:iAnalysed(aLocalisationLine.iAnalysed),
iFirstLine(aLocalisationLine.iFirstLine),
iLastLine(aLocalisationLine.iLastLine),
iFileName(aLocalisationLine.iFileName)
{
for(unsigned int j=0; j<aLocalisationLine.iData.size(); j++)
{
iData.push_back(aLocalisationLine.iData[j]);
}
}
LocalisationLine::~LocalisationLine()
{}
void LocalisationLine::Reset(String aFileName, int aFirstLine)
{
iFirstLine = aFirstLine;
iLastLine = aFirstLine;
iFileName = aFileName;
iAnalysed = false;
iData.clear();
}
String LocalisationLine::GetFileName()
{
return iFileName;
}
int LocalisationLine::GetFirstLine()
{
return iFirstLine;
}
int LocalisationLine::GetLastLine()
{
return iLastLine;
}
void LocalisationLine::SetFirstLine(int aFirstLine)
{
iFirstLine = aFirstLine;
}
void LocalisationLine::SetFileName(String aFileName)
{
iFileName = aFileName;
}
unsigned int LocalisationLine::GetNumberOfTokens()
{
return iData.size();
}
String LocalisationLine::GetElement(unsigned int aIndex)
{
return iData[aIndex];
}
void LocalisationLine::AddElement(String aElement)
{
iData.push_back(aElement);
}
void LocalisationLine::SetLastLine(int aLastLine)
{
iLastLine = aLastLine;
}
void LocalisationLine::SetAnalysed(bool aParity)
{
iAnalysed = aParity;
}
void LocalisationLine::Empty()
{
iData.clear();
}
bool LocalisationLine::IsLineAnalysed()
{
return iAnalysed;
}
/******************************************************************************************
**
** LocalisationComment
**
******************************************************************************************/
LocalisationComment::LocalisationComment(LocalisationLine & aComment)
:iOriginalData(aComment)
{
iData.clear();
iOptionalLinesToAdd.clear();
}
LocalisationComment::~LocalisationComment()
{
}
String LocalisationComment::GetFileName()
{
return iOriginalData.GetFileName();
}
int LocalisationComment::GetFirstLineOfComment()
{
return iOriginalData.GetFirstLine();
}
int LocalisationComment::GetLastLineOfComment()
{
return iOriginalData.GetLastLine();
}
int LocalisationComment::GetNumberOfOptionalLinesToAdd()
{
return iOptionalLinesToAdd.size();
}
unsigned int LocalisationComment::GetNumberOfTokensInComment()
{
return iOriginalData.GetNumberOfTokens();
}
String LocalisationComment::GetOriginalElement(unsigned int aIndex)
{
return iOriginalData.GetElement(aIndex);
}
void LocalisationComment::AddDataLine(LocalisationLine aDataLine)
{
iData.push_back( aDataLine );
}
unsigned int LocalisationComment::GetNumberOfTokensInLine(unsigned int aIndex)
{
return iData[aIndex].GetNumberOfTokens();
}
LocalisationLine LocalisationComment::GetLine(unsigned int aIndex)
{
return iData[aIndex];
}
void LocalisationComment::SetAnalysed(unsigned int aIndex, bool aParity)
{
iData[aIndex].SetAnalysed(aParity);
}
void LocalisationComment::SetLastLine(int aLineNumber)
{
iOriginalData.SetLastLine(aLineNumber);
}
bool LocalisationComment::IsLineAnalysed(unsigned int aIndex)
{
return iData[aIndex].IsLineAnalysed();
}
void LocalisationComment::SetWholeTagAnalysed(bool aParity)
{
iOriginalData.SetAnalysed(aParity);
}
String LocalisationComment::GetElementFromLine(unsigned int aLine, unsigned int aElement)
{
return iData[aLine].GetElement(aElement);
}
int LocalisationComment::GetFirstLine(unsigned int aIndex)
{
return iData[aIndex].GetFirstLine();
}
void LocalisationComment::AddOptionalData(String aOptionalData)
{
iOptionalLinesToAdd.push_back(aOptionalData);
}
String LocalisationComment::GetOptionalLineToAdd(unsigned int aLine)
{
return iOptionalLinesToAdd[aLine];
}
unsigned int LocalisationComment::GetNumberOfLinesInComment()
{
return iData.size();
}
/******************************************************************************************
**
** WarningToOutput
**
******************************************************************************************/
WarningToOutput::WarningToOutput(const String aFileName, int aLineNumber, String aComment)
:iFileName(aFileName),
iLineNumber(aLineNumber),
iComment(aComment)
{}
WarningToOutput::WarningToOutput(const WarningToOutput & aWarningToOutput)
:iFileName(aWarningToOutput.iFileName),
iLineNumber(aWarningToOutput.iLineNumber),
iComment(aWarningToOutput.iComment)
{}
WarningToOutput::~WarningToOutput()
{}
const String WarningToOutput::GetFileName()
{
return iFileName;
}
int WarningToOutput::GetLineNumber()
{
return iLineNumber;
}
String WarningToOutput::GetComment()
{
return iComment;
}
WarningToOutput& WarningToOutput::operator=(const WarningToOutput& aWarningToOutput)
{
if(&aWarningToOutput==this)
return *this;
iFileName = aWarningToOutput.iFileName;
iLineNumber = aWarningToOutput.iLineNumber;
iComment = aWarningToOutput.iComment;
return *this;
}
/******************************************************************************************
**
** GlobalLocalisationData
**
******************************************************************************************/
GlobalLocalisationData::GlobalLocalisationData()
:iCommentStarted(true)
{
iTypes[0] = "single";
iTypes[1] = "multiple";
iTypes[2] = "void";
iTypes[3] = "text";
iRlsTypes[0] = "rls_string";
iRlsTypes[1] = "rls_string8";
iRlsTypes[2] = "rls_byte";
iRlsTypes[3] = "rls_word";
iRlsTypes[4] = "rls_long";
iRlsTypes[5] = "rls_double";
iRlsTypes[6] = "RESOURCE";
iCommentTagStore.clear();
iCommentDefinitions.clear();
iWarningStore.clear();
}
GlobalLocalisationData::~GlobalLocalisationData()
{
}
int GlobalLocalisationData::NeedToAddDefaultData(String aFileName, int aFileLine)
{
for(unsigned int j=0; j<iCommentTagStore.size(); j++)
{
String fileName = iCommentTagStore[j].GetFileName();
if(fileName == aFileName)
{
int lastLine = iCommentTagStore[j].GetLastLineOfComment();
if(lastLine == aFileLine)
{
if(iCommentTagStore[j].GetNumberOfOptionalLinesToAdd())
return j; // returns the index of the localisation comment which needs default data adding
else
return -1; // if default data doesn't need adding for this rls item then returns -1
}
}
}
return -1;
}
void GlobalLocalisationData::AddCommentToStore()
{
LocalisationComment aLocalisationComment( iTempCommentStore );
iCommentTagStore.push_back(aLocalisationComment);
}
void GlobalLocalisationData::SetStart(String aFileName, int aLineNumber)
{
if(iCommentStarted == false) //means that any time other than first time, contents will be added to Store
{
AddCommentToStore();
iTempCommentStore.Reset(aFileName, aLineNumber); // empties the temporary comment store
}
else
{
iTempCommentStore.SetFirstLine( aLineNumber );
iTempCommentStore.SetFileName( aFileName );
}
iCommentStarted = false;
}
void GlobalLocalisationData::AnalyseLocalisationData()
{
for(unsigned int i = 0; i < iCommentTagStore.size(); i++)
{
ParseCommentTags(i);
}
CheckIfCommentTagsFullyAnalysed();
CheckRlsEntries();
}
void GlobalLocalisationData::ParseCommentTags(unsigned int i)
{
LocalisationLine tagCommandLine;
int newLinesSeen = 0;
int currentIndex;
int state = EStartOfComment;
tagCommandLine.SetFileName(iCommentTagStore[i].GetFileName());
int startLineNumber = iCommentTagStore[i].GetFirstLineOfComment();
// parse all the comment tags to find definitions and values
unsigned int originalNumberOfTokensInComment = iCommentTagStore[i].GetNumberOfTokensInComment();
for(unsigned int j = 0; j < originalNumberOfTokensInComment; j++)
{
bool wordIsNewLine = iCommentTagStore[i].GetOriginalElement(j) == "\n" ? true : false;
switch(state)
{
case(EStartOfComment):
switch(wordIsNewLine)
{
case(true):
state = ENewLineAtStart;
newLinesSeen++;
break;
default:
state = EAfterFirstWordOfTag;
tagCommandLine.SetFirstLine(startLineNumber + newLinesSeen);
tagCommandLine.SetLastLine(tagCommandLine.GetFirstLine());
tagCommandLine.AddElement(iCommentTagStore[i].GetOriginalElement(j));
}
break;
case(EAfterFirstWordOfTag):
switch(wordIsNewLine)
{
case(true):
state = ENewLineInTag;
newLinesSeen++;
break;
default:
state = EInTag;
tagCommandLine.AddElement( iCommentTagStore[i].GetOriginalElement(j) );
}
break;
case(ENewLineAtStart):
switch(wordIsNewLine)
{
case(true):
newLinesSeen++;
break;
default:
state = EAfterFirstWordOfTag;
tagCommandLine.SetFirstLine(startLineNumber + newLinesSeen);
tagCommandLine.SetLastLine( tagCommandLine.GetFirstLine() );
tagCommandLine.AddElement( iCommentTagStore[i].GetOriginalElement(j) );
}
break;
case(EInTag):
switch(wordIsNewLine)
{
case(true):
state = ENewLineInTag;
newLinesSeen++;
break;
default:
state = EInTag;
tagCommandLine.AddElement( iCommentTagStore[i].GetOriginalElement(j) );
}
break;
case(ENewLineInTag):
{
if(wordIsNewLine)
{
newLinesSeen++;
}
else if( iCommentTagStore[i].GetOriginalElement(j).FindSubString("@")==0)
{
iCommentTagStore[i].AddDataLine( tagCommandLine );
currentIndex = iCommentTagStore[i].GetNumberOfLinesInComment()-1;
Process(i, currentIndex);
tagCommandLine.Empty();
tagCommandLine.AddElement(iCommentTagStore[i].GetOriginalElement(j));
tagCommandLine.SetFirstLine( startLineNumber + newLinesSeen );
tagCommandLine.SetLastLine( tagCommandLine.GetFirstLine() );
state = EAfterFirstWordOfTag;
}
else
{
state = EInTag;
tagCommandLine.AddElement(iCommentTagStore[i].GetOriginalElement(j));
tagCommandLine.SetLastLine( startLineNumber + newLinesSeen );
}
}
}
}
if( tagCommandLine.GetNumberOfTokens() )
{
iCommentTagStore[i].AddDataLine( tagCommandLine );
currentIndex = iCommentTagStore[i].GetNumberOfLinesInComment()-1;
Process( i, currentIndex ); // process the current tag and parameters
}
iCommentTagStore[i].SetLastLine( startLineNumber + newLinesSeen );
}
void GlobalLocalisationData::CheckIfCommentTagsFullyAnalysed()
{
for(unsigned int i = 0; i < iCommentTagStore.size(); i++) //for each of the original comments sets whether or not all parts analysed
{
bool allAnalysed = true; //set to true then see if any are not analysed in which case will set to false
unsigned int numberOfLinesInComment = iCommentTagStore[i].GetNumberOfLinesInComment();
for(unsigned int j=0;j < numberOfLinesInComment && allAnalysed; j++)
{
if(iCommentTagStore[i].IsLineAnalysed(j) == false)
allAnalysed = false;
}
if(allAnalysed)
{
iCommentTagStore[i].SetWholeTagAnalysed( true );
}
}
}
void GlobalLocalisationData::CheckRlsEntries()
{
// check each rls item to see if there is a localisation comment before it
TNameIndex::iterator end = pG->RlsNameIndex.end();
String rlsTypeName;
for (TNameIndex::iterator k = pG->RlsNameIndex.begin(); k != end; ++k)
{
int index = k->second;
int rlsLineNumber = pG->RlsValues[index].iLineNumber;
switch(pG->RlsValues[index].iType)
{
case(ERlsString):
case(ERlsStringChar):
rlsTypeName = iRlsTypes[0];
break;
case(ERlsString8):
rlsTypeName = iRlsTypes[1];
break;
case(ERlsByte):
case(ERlsByteChar):
rlsTypeName = iRlsTypes[2];
break;
case(ERlsWord):
case(ERlsWordChar):
rlsTypeName = iRlsTypes[3];
break;
case(ERlsLong):
case(ERlsLongChar):
rlsTypeName = iRlsTypes[4];
break;
case(ERlsDouble):
rlsTypeName = iRlsTypes[5];
break;
default:
rlsTypeName="";
}
const String rlsFileName = *(pG->RlsValues[index].iFileName);
int commentOfInterest = FindIndex(rlsFileName, rlsLineNumber);
if(commentOfInterest == -1) // signifies there is no comment before rls declaration
{
Message * message = pG->Messages.GetEntry(LT_005);
if(message->GetActivated())
{
pGL->AddWarningToStore(rlsFileName, rlsLineNumber, message->GetMessageOutput());
}
}
else //know that there exists a tag directly before the rls item
{
CheckCommands(rlsTypeName, commentOfInterest);
}
}
}
bool GlobalLocalisationData::LocalisationCommentsExist()
{
return (iCommentTagStore.size()) ? true : false;
}
void GlobalLocalisationData::CheckCommands(String aRlsTypeName, int aCommentOfInterest)
{
std::vector<String> commentsSeen;
unsigned int numberOfLines = iCommentTagStore[aCommentOfInterest].GetNumberOfLinesInComment();
for(unsigned int j=0; j<numberOfLines; j++) // for each command in the particular comment
{
if(iCommentTagStore[aCommentOfInterest].IsLineAnalysed(j) == false)
{
iCommentTagStore[aCommentOfInterest].SetAnalysed( j, true );
String commandName = iCommentTagStore[aCommentOfInterest].GetElementFromLine( j, 0 ); //gets tag value
int length = commandName.Length();
String tempCommandName = commandName.ExtractSubString(1, length-1); //strips off @ symbol
int definitionNumber = iCommentDefinitions.size();
for(int k=0; k<definitionNumber; k++) // finds tempCommandName in iCommentDefinitions
if(iCommentDefinitions[k].GetCommandName() == tempCommandName)
definitionNumber = k;
if(definitionNumber == (int)iCommentDefinitions.size()) // if tempCommandName not found
{
Message * message = pG->Messages.GetEntry(LT_006);
String fileName = iCommentTagStore[aCommentOfInterest].GetFileName();
int lineNumber = iCommentTagStore[aCommentOfInterest].GetFirstLine(j);
if(message->GetActivated())
{
pGL->AddWarningToStore(fileName, lineNumber, message->GetMessageOutput());
}
}
else if(iCommentDefinitions[definitionNumber].TagDeclared() == false) // if tempCommandName not declared
{
Message * message = pG->Messages.GetEntry(LT_006);
String fileName = iCommentTagStore[aCommentOfInterest].GetFileName();
int lineNumber = iCommentTagStore[aCommentOfInterest].GetFirstLine(j);
if(message->GetActivated())
{
pGL->AddWarningToStore(fileName, lineNumber, message->GetMessageOutput());
}
}
else
{
bool commentAlreadySeen=false;
unsigned int numberOfCommentsSeen = commentsSeen.size();
for(unsigned int k=0; k<numberOfCommentsSeen && commentAlreadySeen == false ;k++)
{ // checks in the commentsSeen vector for whether or not the tag has already been used
if(commandName==commentsSeen[k])
{
Message * message = pG->Messages.GetEntry(LT_007);
String fileName = iCommentTagStore[aCommentOfInterest].GetFileName();
int lineNumber = iCommentTagStore[aCommentOfInterest].GetFirstLine(j);
if(message->GetActivated())
{
pGL->AddWarningToStore(fileName, lineNumber, message->GetMessageOutput());
}
commentAlreadySeen = true;
}
}
if(commentAlreadySeen == false)
{
commentsSeen.push_back(commandName); // new tag so store it
if(iCommentDefinitions[definitionNumber].IsTagLegalForRlsType(aRlsTypeName) == false)
{
Message * message = pG->Messages.GetEntry(LT_008);
String fileName =iCommentTagStore[aCommentOfInterest].GetFileName();
int lineNumber = iCommentTagStore[aCommentOfInterest].GetFirstLine(j);
if(message->GetActivated())
{
pGL->AddWarningToStore(fileName, lineNumber, message->GetMessageOutput());
}
}
else
{
String parameterType = iCommentDefinitions[definitionNumber].GetParameterType();
int numberOfArgs = iCommentTagStore[aCommentOfInterest].GetNumberOfTokensInLine(j) - 1;
if(parameterType == "void")
{
if(numberOfArgs!=0) //void must have no arguments
{
Message * message = pG->Messages.GetEntry(LT_009);
String fileName =iCommentTagStore[aCommentOfInterest].GetFileName();
int lineNumber = iCommentTagStore[aCommentOfInterest].GetFirstLine(j);
if(message->GetActivated())
{
pGL->AddWarningToStore(fileName, lineNumber, message->GetMessageOutput());
}
}
}
else if(parameterType == "single")
{
if(numberOfArgs!=1) //single must have one argument
{
Message * message = pG->Messages.GetEntry(LT_010);
String fileName =iCommentTagStore[aCommentOfInterest].GetFileName();
int lineNumber = iCommentTagStore[aCommentOfInterest].GetFirstLine(j);
if(message->GetActivated())
{
pGL->AddWarningToStore(fileName, lineNumber, message->GetMessageOutput());
}
}
else
{
CheckParametersArePermitted(aCommentOfInterest, j, definitionNumber);
}
}
else if(parameterType == "multiple")
{
if(numberOfArgs<1) // multiple must have at least one argument
{
Message * message = pG->Messages.GetEntry(LT_011);
String fileName =iCommentTagStore[aCommentOfInterest].GetFileName();
int lineNumber = iCommentTagStore[aCommentOfInterest].GetFirstLine(j);
if(message->GetActivated())
{
pGL->AddWarningToStore(fileName, lineNumber, message->GetMessageOutput());
}
}
else
{
CheckParametersArePermitted(aCommentOfInterest, j, definitionNumber);
}
}
else if(parameterType == "text")
{
if(numberOfArgs<1) // text must have somethign after it so numberOfArgs must be >= 1
{
Message * message = pG->Messages.GetEntry(LT_012);
String fileName =iCommentTagStore[aCommentOfInterest].GetFileName();
int lineNumber = iCommentTagStore[aCommentOfInterest].GetFirstLine(j);
if(message->GetActivated())
{
pGL->AddWarningToStore(fileName, lineNumber, message->GetMessageOutput());
}
}
}
}
}
}
}
}
CheckWhetherAllCommentsPresent(aRlsTypeName, aCommentOfInterest, commentsSeen);
}
void GlobalLocalisationData::CheckWhetherAllCommentsPresent(String aRlsTypeName, int aCommentOfInterest, std::vector<String> aCommentsSeen)
{
for(unsigned int j=0; j<iCommentDefinitions.size(); j++)
{
bool commentAlreadyUsed = false;
for(unsigned int k=0; k<aCommentsSeen.size() && commentAlreadyUsed == false;k++)
{
String storedCommandName = iCommentDefinitions[j].GetCommandName();
String extractedCommandName = aCommentsSeen[k].ExtractSubString(1,aCommentsSeen[k].Length()-1);
if(storedCommandName == extractedCommandName)
{
//this command already used in the comment tag
commentAlreadyUsed = true;
}
}
if(commentAlreadyUsed == false) // if tag wasn't present in the localisation comment
{
int requirementStatus = iCommentDefinitions[j].GetRequirementStatus(aRlsTypeName);
if(iCommentDefinitions[j].GetRequirementStatus(aRlsTypeName) == ERequired) // if required emit warning
{
Message * message = pG->Messages.GetEntry(LT_013);
String fileName = iCommentTagStore[aCommentOfInterest].GetFileName();
int lineNumber = iCommentTagStore[aCommentOfInterest].GetLastLineOfComment() + 1;
if(message->GetActivated())
{
String comment = message->GetMessageOutput();
comment += iCommentDefinitions[j].GetCommandName();
pGL->AddWarningToStore(fileName, lineNumber, comment);
}
}
else if(requirementStatus == EOptionalWithDefault) // if optional check for default and add to file if default exists
{
String dataToAdd = iCommentDefinitions[j].CheckIfOptionalAndHasDefault(aRlsTypeName);
if(dataToAdd != "")
{
iCommentTagStore[aCommentOfInterest].AddOptionalData(dataToAdd);
}
}
}
}
}
void GlobalLocalisationData::CheckParametersArePermitted(int aCommentOfInterest, int aLineInComment, int aDefinitionNumber)
{
unsigned int elementsInLine = iCommentTagStore[aCommentOfInterest].GetNumberOfTokensInLine(aLineInComment);
for(unsigned int j=1; j< elementsInLine;j++)
{ // start iterating at 1 as 0th element is tag name
bool parameterPermitted = false;
unsigned int permissibleParameters = iCommentDefinitions[aDefinitionNumber].GetNumberOfPermissibleParameters();
for(unsigned int k=0; k<permissibleParameters && parameterPermitted==false;k++)
{
if(iCommentTagStore[aCommentOfInterest].GetElementFromLine(aLineInComment,j)== iCommentDefinitions[aDefinitionNumber].GetPermissibleParameter(k))
{
parameterPermitted = true;
}
}
if(parameterPermitted == false)
{
Message * message = pG->Messages.GetEntry(LT_014);
String fileName = iCommentTagStore[aCommentOfInterest].GetFileName();
int lineNumber = iCommentTagStore[aCommentOfInterest].GetFirstLine(aLineInComment);
if(message->GetActivated())
{
pGL->AddWarningToStore(fileName, lineNumber, message->GetMessageOutput());
}
return;
}
}
}
int GlobalLocalisationData::FindIndex(const String aFileName, int aLineNumber)
{
for(unsigned int j=0;j<iCommentTagStore.size(); j++)
{
if(iCommentTagStore[j].GetFileName() == aFileName)
{
if(iCommentTagStore[j].GetLastLineOfComment() == aLineNumber - 1)
{
return j;
}
}
}
return -1; //signifies that there is no localisation comment preceding this rls line
}
bool GlobalLocalisationData::CheckFirstIsCommand(LocalisationLine aCommandLine)
{
return aCommandLine.GetElement(0).FindSubString("@") == 0 ? true : false;
}
void GlobalLocalisationData::StoreFinalComment()
{
if(iTempCommentStore.GetFirstLine() >= 0)
AddCommentToStore();
}
void GlobalLocalisationData::StoreComment(String aString)
{
iTempCommentStore.AddElement(aString);
}
void GlobalLocalisationData::Process(unsigned int aStoreIndex, unsigned int aCurrentIndex)
{
LocalisationLine tagCommandLine(iCommentTagStore[aStoreIndex].GetLine(aCurrentIndex));
String firstWord = tagCommandLine.GetElement(0);
iCommentTagStore[aStoreIndex].SetAnalysed(aCurrentIndex, true); // will reset to false if turns out not to be a declaration
if(firstWord == "@declaretag")
ProcessDeclaration(aStoreIndex, aCurrentIndex);
else if(firstWord == "@tagvalue")
ProcessTagParameter(aStoreIndex, aCurrentIndex);
else if(firstWord == "@tagoptional")
{
ProcessOptional(aStoreIndex, aCurrentIndex);
}
else if(firstWord == "@tagrequired")
ProcessRequired(aStoreIndex, aCurrentIndex);
else if(firstWord[0]=='@') // must be a tag like 'localise' or 'description'
{
iCommentTagStore[aStoreIndex].SetAnalysed(aCurrentIndex, false);
}
else // first word on a line (not wrapping over from a previous line) does not start with an @ symbol, enit warning
{
Message * message = pG->Messages.GetEntry(LT_015);
String fileName = tagCommandLine.GetFileName();
int lineNumber = tagCommandLine.GetFirstLine();
if(message->GetActivated())
{
pGL->AddWarningToStore(fileName, lineNumber, message->GetMessageOutput());
}
}
}
void GlobalLocalisationData::ProcessDeclaration(unsigned int aStoreIndex, unsigned int aCurrentIndex)
{
LocalisationLine tagDeclarationLine(iCommentTagStore[aStoreIndex].GetLine(aCurrentIndex));
if(tagDeclarationLine.GetNumberOfTokens()!=3) // tag declaration lines must have three words in them
{
Message * message = pG->Messages.GetEntry(LT_016);
String fileName = tagDeclarationLine.GetFileName();
int lineNumber = tagDeclarationLine.GetFirstLine();
if(message->GetActivated())
{
pGL->AddWarningToStore(fileName, lineNumber, message->GetMessageOutput());
}
return;
}
String tagType = tagDeclarationLine.GetElement(1);
bool acceptableParameter = false; // check that tagType is one of void, single, multiple or text
for(int i=0; i<4 && acceptableParameter == false; i++)
{
if(tagType == iTypes[i])
{
acceptableParameter = true;
}
}
if(acceptableParameter == false)
{
Message * message = pG->Messages.GetEntry(LT_017);
String fileName = tagDeclarationLine.GetFileName();
int lineNumber = tagDeclarationLine.GetFirstLine();
if(message->GetActivated())
{
pGL->AddWarningToStore(fileName, lineNumber, message->GetMessageOutput());
}
return;
}
if(tagDeclarationLine.GetElement(2).FindSubString("@")==0)
{
Message * message = pG->Messages.GetEntry(LT_018);
String fileName = tagDeclarationLine.GetFileName();
int lineNumber = tagDeclarationLine.GetFirstLine();
if(message->GetActivated())
{
pGL->AddWarningToStore(fileName, lineNumber, message->GetMessageOutput());
}
return;
}
String tagName = tagDeclarationLine.GetElement(2);
CommentTagPair dataToAdd(tagName, tagType, true);
int entryNumber = GetTagDeclaredIndex(tagName); // check whether tag has already been declared
if(entryNumber == EStringNotFound) // if not then add to store
{
iCommentDefinitions.push_back( dataToAdd );
}
else if(iCommentDefinitions[entryNumber].TagDeclared()) // emit warning if declared
{
Message * message = pG->Messages.GetEntry(LT_019);
String fileName = tagDeclarationLine.GetFileName();
int lineNumber = tagDeclarationLine.GetFirstLine();
if(message->GetActivated())
{
pGL->AddWarningToStore(fileName, lineNumber, message->GetMessageOutput());
}
}
else
iCommentDefinitions[entryNumber].SetTagDeclared(); // set tag as declared
}
void GlobalLocalisationData::StoreTagParameter(String aCommandName, String aParameter)
{
int entryNumber = GetTagDeclaredIndex(aCommandName);
iCommentDefinitions[entryNumber].AddPermissibleParameter(aParameter);
}
int GlobalLocalisationData::GetTagDeclaredIndex(String aCommandName)
{ // return index number of tag in iCommentDefinitions store
for(unsigned int j = 0; j < iCommentDefinitions.size(); j++)
{
if(iCommentDefinitions[j].GetCommandName() == aCommandName)
{
return j;
}
}
return -1;
}
void GlobalLocalisationData::ProcessTagParameter(unsigned int aStoreIndex, unsigned int aCurrentIndex)
{
LocalisationLine tagParameterLine(iCommentTagStore[aStoreIndex].GetLine(aCurrentIndex));
if(tagParameterLine.GetNumberOfTokens()!=3)
{
Message * message = pG->Messages.GetEntry(LT_020);
String fileName = tagParameterLine.GetFileName();
int lineNumber = tagParameterLine.GetFirstLine();
if(message->GetActivated())
{
pGL->AddWarningToStore(fileName, lineNumber, message->GetMessageOutput());
}
return;
}
String tagName = tagParameterLine.GetElement(1);
if(tagName.FindSubString("@") == 0)
{
Message * message = pG->Messages.GetEntry(LT_021);
String fileName = tagParameterLine.GetFileName();
int lineNumber = tagParameterLine.GetFirstLine();
if(message->GetActivated())
{
pGL->AddWarningToStore(fileName, lineNumber, message->GetMessageOutput());
}
return;
}
int entryNumber = GetTagDeclaredIndex(tagName);
String parameter = tagParameterLine.GetElement(2);
if(entryNumber == -1) // if tag not declared then add to store, doesn't set tag as declared though as haven't seen a @declaretag line for this tag
{
CommentTagPair dataToAdd(tagName);
iCommentDefinitions.push_back(dataToAdd);
}
else
{
// check whether this parameter has alreasy been declared for this tag
bool alreadyDeclared = iCommentDefinitions[entryNumber].IsParameterAlreadyDeclared(parameter);
if(alreadyDeclared)
{
Message * message = pG->Messages.GetEntry(LT_022);
String fileName = tagParameterLine.GetFileName();
int lineNumber = tagParameterLine.GetFirstLine();
if(message->GetActivated())
{
pGL->AddWarningToStore(fileName, lineNumber, message->GetMessageOutput());
}
return;
}
}
StoreTagParameter(tagName, parameter); // store the parameter if all conditions met
}
void GlobalLocalisationData::ProcessRequired(unsigned int aStoreIndex, unsigned int aCurrentIndex)
{
LocalisationLine tagRequiredLine(iCommentTagStore[aStoreIndex].GetLine(aCurrentIndex));
// @tagrequired line must consist of three distinct tokens
if(tagRequiredLine.GetNumberOfTokens()!=3)
{
Message * message = pG->Messages.GetEntry(LT_023);
String fileName = tagRequiredLine.GetFileName();
int lineNumber = tagRequiredLine.GetFirstLine();
if(message->GetActivated())
{
pGL->AddWarningToStore(fileName, lineNumber, message->GetMessageOutput());
}
return;
}
// get the tag name and check it doesn't start with an @ symbol
String tagName = tagRequiredLine.GetElement(1);
if(tagName.FindSubString("@")==0)
{
Message * message = pG->Messages.GetEntry(LT_024);
String fileName = tagRequiredLine.GetFileName();
int lineNumber = tagRequiredLine.GetFirstLine();
if(message->GetActivated())
{
pGL->AddWarningToStore(fileName, lineNumber, message->GetMessageOutput());
}
return;
}
String rlsItem = tagRequiredLine.GetElement(2);
//check that the rls type passed is one of the legally allowed values
bool validRlsFlag = false;
for(int j=0; (j < ENumberOfRlsTypes) && (validRlsFlag == false); j++)
{
if(rlsItem == iRlsTypes[j])
{
validRlsFlag = true;
}
}
if(validRlsFlag == false)
{
Message * message = pG->Messages.GetEntry(LT_036);
String fileName = tagRequiredLine.GetFileName();
int lineNumber = tagRequiredLine.GetFirstLine();
if(message->GetActivated())
{
String comment = message->GetMessageOutput();
comment += rlsItem;
pGL->AddWarningToStore(fileName, lineNumber, comment);
}
return;
}
// store the data
int entryNumber = GetTagDeclaredIndex(tagName);
if(entryNumber == -1)
{
CommentTagPair dataToAdd(tagName);
iCommentDefinitions.push_back(dataToAdd);
}
else
{
int requirementStatus = iCommentDefinitions[entryNumber].GetRequirementStatus(rlsItem);
if(requirementStatus != EForbidden)
{
Message * message = pG->Messages.GetEntry(LT_025);
String fileName = tagRequiredLine.GetFileName();
int lineNumber = tagRequiredLine.GetFirstLine();
if(message->GetActivated())
{
pGL->AddWarningToStore(fileName, lineNumber, message->GetMessageOutput());
}
return;
}
}
StoreRlsItem(tagName, tagRequiredLine.GetElement(2), ERequired);
}
void GlobalLocalisationData::StoreRlsItem(String aCommandName, String aRlsItem, int aRequired, String aDefault)
{
int entryNumber = GetTagDeclaredIndex(aCommandName);
iCommentDefinitions[entryNumber].AddRlsItem(aRlsItem,aRequired,aDefault);
}
bool GlobalLocalisationData::IsAnRlsItem(String aString) const
{
//check whether aString is one of the legally allowed rls items
for(int j=0; j < ENumberOfRlsTypes ; j++)
{
if(aString == iRlsTypes[j])
{
return true;
}
}
return false;
}
void GlobalLocalisationData::ProcessOptional(unsigned int aStoreIndex, unsigned int aCurrentIndex)
{
LocalisationLine tagOptionalLine(iCommentTagStore[aStoreIndex].GetLine(aCurrentIndex));
int tagLineSize = tagOptionalLine.GetNumberOfTokens();
String fileName = tagOptionalLine.GetFileName();
int lineNumber = tagOptionalLine.GetFirstLine();
String comment;
String commandName;
String defaultValue;
String rlsItem;
bool validOptionalDeclaration = false; // will be set to true if the line conforms to the accepted syntax
unsigned int state = ELookingForCommand;
int firstOccurance;
String currentToken;
for(int j=1; j<tagLineSize; j++) // start at 1 as 0th element is @tagoptional
{
currentToken = tagOptionalLine.GetElement(j);
switch(state)
{
case(ELookingForCommand):
firstOccurance = currentToken.FindSubString("=");
if(firstOccurance == EStringNotFound)
{
if(IsAnRlsItem(currentToken))
{
Message * message = pG->Messages.GetEntry(LT_038);
if(message->GetActivated())
{
pGL->AddWarningToStore(fileName, lineNumber, message->GetMessageOutput());
}
return;
}
else
{
commandName = currentToken;
state = ELookingForEqualSignOrRlsItem;
}
}
else if(firstOccurance == 0) // = sign is at the start
{
Message * message = pG->Messages.GetEntry(LT_039);
if(message->GetActivated())
{
pGL->AddWarningToStore(fileName, lineNumber, message->GetMessageOutput());
}
return;
}
else if(currentToken.FindSubString("=",firstOccurance+1)!=EStringNotFound) // more than one = sign
{
Message * message = pG->Messages.GetEntry(LT_027);
if(message->GetActivated())
{
pGL->AddWarningToStore(fileName, lineNumber, message->GetMessageOutput());
}
return;
}
else if((unsigned int)firstOccurance == currentToken.Length() - 1) // = sign at end
{
commandName = currentToken.ExtractSubString( 0, currentToken.Length()-2 );
state = ELookingForDefault;
}
else // know that is of from <string1>=<string2>
{
commandName = currentToken.ExtractSubString( 0, firstOccurance - 1 );
defaultValue = currentToken.ExtractSubString( firstOccurance + 1, currentToken.Length()-1 );
if(IsAnRlsItem(commandName))
{
Message * message = pG->Messages.GetEntry(LT_040);
if(message->GetActivated())
{
pGL->AddWarningToStore(fileName, lineNumber, message->GetMessageOutput());
}
return;
}
else if(IsAnRlsItem(defaultValue))
{
Message * message = pG->Messages.GetEntry(LT_041);
if(message->GetActivated())
{
pGL->AddWarningToStore(fileName, lineNumber, message->GetMessageOutput());
}
return;
}
else // no problems so go and look next for an rls item
{
state = ELookingForRlsItem;
}
}
break;
case(ELookingForEqualSignOrRlsItem):
firstOccurance = currentToken.FindSubString("=");
if(firstOccurance == EStringNotFound) // element must be rls item or error
{
if(IsAnRlsItem(currentToken))
{
rlsItem = currentToken;
state = EShouldBeFinished;
validOptionalDeclaration = true;
}
else // not an rls item
{
Message * message = pG->Messages.GetEntry(LT_035);
if(message->GetActivated())
{
String comment = message->GetMessageOutput();
comment += currentToken;
pGL->AddWarningToStore(fileName, lineNumber, comment);
}
return;
}
}
else if(currentToken.FindSubString("=",firstOccurance+1)!=EStringNotFound) // more than one = sign
{
Message * message = pG->Messages.GetEntry(LT_027);
if(message->GetActivated())
{
pGL->AddWarningToStore(fileName, lineNumber, message->GetMessageOutput());
}
return;
}
else if(firstOccurance != 0) // = sign not at start
{
Message * message = pG->Messages.GetEntry(LT_042);
if(message->GetActivated())
{
pGL->AddWarningToStore(fileName, lineNumber, message->GetMessageOutput());
}
return;
}
else if(currentToken.Length() == 1) // = sign by itself
{
state = ELookingForDefault;
}
else
{
defaultValue = currentToken.ExtractSubString( 1, currentToken.Length()-1 );
if(IsAnRlsItem(defaultValue)) // if found rls item where default value should be
{
Message * message = pG->Messages.GetEntry(LT_041);
if(message->GetActivated())
{
pGL->AddWarningToStore(fileName, lineNumber, message->GetMessageOutput());
}
return;
}
else
{
state = ELookingForRlsItem;
}
}
break;
case(ELookingForDefault):
firstOccurance = currentToken.FindSubString("=");
if(firstOccurance != EStringNotFound) // should not find any more equal signs on the line
{
Message * message = pG->Messages.GetEntry(LT_027);
if(message->GetActivated())
{
pGL->AddWarningToStore(fileName, lineNumber, message->GetMessageOutput());
}
return;
}
else
{
defaultValue = currentToken;
if(IsAnRlsItem(defaultValue)) //check that default value is not an rls item
{
Message * message = pG->Messages.GetEntry(LT_041);
if(message->GetActivated())
{
pGL->AddWarningToStore(fileName, lineNumber, message->GetMessageOutput());
}
return;
}
else
{
state = ELookingForRlsItem;
}
}
break;
case(ELookingForRlsItem):
rlsItem = currentToken;
if(IsAnRlsItem(rlsItem) == false)
{
Message * message = pG->Messages.GetEntry(LT_035);
if(message->GetActivated())
{
String comment = message->GetMessageOutput();
comment += rlsItem;
pGL->AddWarningToStore(fileName, lineNumber, comment);
}
return;
}
else
{
state = EShouldBeFinished;
validOptionalDeclaration = true;
}
break;
case(EShouldBeFinished):
Message * message = pG->Messages.GetEntry(LT_043);
if(message->GetActivated())
{
String comment = message->GetMessageOutput();
comment += currentToken;
pGL->AddWarningToStore(fileName, lineNumber, comment);
}
return;
}
}
if(validOptionalDeclaration == false) // end of line reached prematurely
{
Message * message = pG->Messages.GetEntry(LT_044);
if(message->GetActivated())
{
pGL->AddWarningToStore(fileName, lineNumber, message->GetMessageOutput());
}
return;
}
int entryNumber = GetTagDeclaredIndex(commandName);
if(entryNumber == -1)
{
CommentTagPair dataToAdd(commandName);
iCommentDefinitions.push_back(dataToAdd);
}
else
{
int requirementStatus = iCommentDefinitions[entryNumber].GetRequirementStatus(rlsItem);
if(requirementStatus != EForbidden)
{
Message * message = pG->Messages.GetEntry(LT_025);
if(message->GetActivated())
{
pGL->AddWarningToStore(fileName, lineNumber, message->GetMessageOutput());
}
return;
}
}
if(defaultValue.Length())
StoreRlsItem(commandName, rlsItem, EOptionalWithDefault, defaultValue);
else
StoreRlsItem(commandName, rlsItem, EOptional);
}
void GlobalLocalisationData::AddWarningToStore(const String aFileName, int aLineNumber, String aComment)
{
WarningToOutput warning(aFileName, aLineNumber, aComment);
iWarningStore.push_back(warning);
}
void GlobalLocalisationData::PrintLocalisationWarnings()
{
std::vector<WarningToOutput> warningStore;
unsigned int j;
unsigned int numberOfWarnings = iWarningStore.size();
std::vector<int> flags;
for(j=0 ; j<numberOfWarnings; j++)
{
warningStore.push_back(iWarningStore[j]);
flags.push_back(1);
}
iWarningStore.clear();
StringLess stringCompare;
int currentBestIndex;
int totalLeft = numberOfWarnings;
while(totalLeft) // loop orders stored warnings alphabetically by file name and then by line number
{
String fileName;
int lineNumber = -1;
String comment;
String currentBestFileName;
int currentBestLineNumber = -1;
String currentBestComment;
bool beforeFirst = true;
for(j=0,totalLeft=0,currentBestIndex=-1; j< numberOfWarnings; j++)
{
if(flags[j])
{
if(beforeFirst)
{
currentBestFileName = warningStore[j].GetFileName();
currentBestLineNumber = warningStore[j].GetLineNumber();
currentBestComment = warningStore[j].GetComment();
currentBestIndex = j;
beforeFirst = false;
}
else
{
fileName = warningStore[j].GetFileName();
lineNumber = warningStore[j].GetLineNumber();
comment = warningStore[j].GetComment();
if(!stringCompare(fileName, currentBestFileName) && !stringCompare(currentBestFileName, fileName))
{
if(lineNumber < currentBestLineNumber)
{
currentBestLineNumber = lineNumber;
currentBestComment = comment;
currentBestIndex = j;
}
}
else if(stringCompare(fileName, currentBestFileName))
{
currentBestFileName = fileName;
currentBestLineNumber = lineNumber;
currentBestComment = comment;
currentBestIndex = j;
}
}
totalLeft++;
}
}
if(currentBestIndex>=0)
{
flags[currentBestIndex]=0;
WarningToOutput warning(warningStore[currentBestIndex]);
iWarningStore.push_back(warning);
totalLeft--;
}
}
for(j=0; j< numberOfWarnings; j++) // outputs warning in alphabetical file order, by line number within a file
{
String fileName = iWarningStore[j].GetFileName();
ErrorHandler::Register(& fileName, iWarningStore[j].GetLineNumber());
ErrorHandler::OutputErrorLine(iWarningStore[j].GetComment());
}
}
void GlobalLocalisationData::OutputLocalisedFile(String SourceFileName)
{ // reparse the source file and output a file with the optional tags with defaults added in
char fileChar;
char * fileCharAsArray = new char[2];
fileCharAsArray[0] = 'a';
fileCharAsArray[1]='\0';
const char * fileName = SourceFileName.GetAssertedNonEmptyBuffer();
ifstream iFile(fileName);
char * LocalisationOutputFileName;
LocalisationOutputFileName = tmpnam(NULL);
ofstream outputFile(LocalisationOutputFileName);
String fileLine("");
int fileLineLength = fileLine.Length();
int previousState;
int state = EStartOfLine;
int currentFileLine = 1;
String currentFileName = SourceFileName;
int newLineNumber = -1;
String newFileName("");
String newLineNumberAsString("");
bool validLine = false;
while(iFile.get(fileChar)) // read file character by character looking for file declaration lines
{
fileCharAsArray[0]=fileChar;
if(state == EStartOfLine) // add character to store of this line
fileLine = fileCharAsArray;
else
fileLine += fileCharAsArray;
previousState = state;
switch(state)
{
case(EStartOfLine):
switch(fileChar)
{
case('#'):
state = EFindLineNo;
break;
case('\n'):
break;
default:
state = EGeneral;
}
break;
case(EGeneral):
switch(fileChar)
{
case('\n'):
state = EStartOfLine;
break;
}
break;
case(EFindLineNo):
switch(fileChar)
{
case('\n'):
state = EStartOfLine;
break;
case('0'):
case('1'):
case('2'):
case('3'):
case('4'):
case('5'):
case('6'):
case('7'):
case('8'):
case('9'):
state = EInLineNo;
break;
case(' '):
case('\t'):
break;
default:
state = EGeneral;
}
break;
case(EInLineNo):
switch(fileChar)
{
case('\n'):
state = EStartOfLine;
break;
case('0'):
case('1'):
case('2'):
case('3'):
case('4'):
case('5'):
case('6'):
case('7'):
case('8'):
case('9'):
break;
case(' '):
case('\t'):
state = EFindFileName;
break;
default:
state = EGeneral;
}
break;
case(EFindFileName):
switch(fileChar)
{
case('\n'):
state = EStartOfLine;
break;
case(' '):
case('\t'):
break;
case('\"'):
state = EInFileName;
break;
default:
state = EGeneral;
}
break;
case(EInFileName):
switch(fileChar)
{
case('\n'):
state = EStartOfLine;
break;
case(' '):
case('\t'):
state = EGeneral;
break;
case('\"'):
state = EFindDigit;
break;
}
break;
case(EFindDigit):
switch(fileChar)
{
case('\n'):
state = EStartOfLine;
break;
case(' '):
case('\t'):
break;
case('1'):
case('2'):
state = EAfterDigit;
break;
default:
state = EGeneral;
}
break;
case(EAfterDigit):
switch(fileChar)
{
case('\n'):
state = EStartOfLine;
break;
case(' '):
case('\t'):
break;
default:
state = EGeneral;
}
break;
}
int lineOfInterest;
switch(state)
{
case(EStartOfLine):
if(validLine) //validline will be true if this line is a file line declaration
{
currentFileName = newFileName;
currentFileLine = newLineNumber - 1;
}
validLine = false;
newFileName.Reset();
newLineNumber = -1;
newLineNumberAsString.Reset();
fileLineLength = fileLine.Length();
lineOfInterest = NeedToAddDefaultData(currentFileName, currentFileLine); //checks if previous line was the end of a localisation tag and whether that tag has optional data to add
if(lineOfInterest > -1) // data to add
{
int end = fileLine.FindSubString("*/");
String tempString;
if(end)
{
tempString = fileLine.ExtractSubString(0,end-1);
outputFile.write(tempString.GetBuffer(),tempString.Length());
outputFile.write("\n",1);
}
unsigned int numberOfLinesToAdd = iCommentTagStore[lineOfInterest].GetNumberOfOptionalLinesToAdd();
for(unsigned int j=0; j<numberOfLinesToAdd; j++)
{
tempString = iCommentTagStore[lineOfInterest].GetOptionalLineToAdd(j);
const char * pTempString = tempString.GetBuffer();
outputFile.write(pTempString,tempString.Length()-1);
outputFile.write("\n",1);
}
tempString = fileLine.ExtractSubString(end, fileLine.Length()-1);
outputFile.write(tempString.GetBuffer(),tempString.Length());
}
else
outputFile.write(fileLine.GetBuffer(), fileLineLength);
fileLine.Reset();
currentFileLine++;
break;
case(EGeneral):
if(previousState!=EGeneral)
{
newLineNumber = -1;
newLineNumberAsString.Reset();
newFileName.Reset();
validLine = false;
}
break;
case(EInLineNo):
if(newLineNumberAsString.Length())
newLineNumberAsString+= fileCharAsArray;
else
newLineNumberAsString = fileCharAsArray;
break;
case(EFindFileName):
if(previousState == EInLineNo)
{
newLineNumber = newLineNumberAsString.Atoi();
}
break;
case(EInFileName):
if(previousState == EInFileName)
{
if(newFileName.Length())
newFileName += fileCharAsArray;
else
newFileName = fileCharAsArray;
}
break;
case(EFindDigit):
if(previousState == EInFileName)
validLine = true;
break;
}
}
iFile.close();
outputFile.close();
if(remove(fileName) != 0)
{
Message * message = pG->Messages.GetEntry(LT_037);
if(message->GetActivated())
{
cerr << message->GetMessageOutput() << endl;
}
}
else
{
rename(LocalisationOutputFileName, fileName);
}
delete []fileCharAsArray;
}
#ifdef __VC32__
#pragma warning( pop )
#endif