diff options
author | Andras Timar <atimar@suse.com> | 2012-11-13 11:44:29 +0100 |
---|---|---|
committer | Andras Timar <atimar@suse.com> | 2012-11-13 11:44:29 +0100 |
commit | 0a7189a3b2d8fc78e9b3ce1b5fff2622557258a5 (patch) | |
tree | 2c40ba7224f9255d4835d3d25bb8006ee23f9bc5 /l10ntools | |
parent | deaceba0c27040ad9982b16e2be8745f6bd1605a (diff) |
remove obsoleted gsicheck tool
Change-Id: Ib25a6feae34533fa3752fe57e857613ca113ee3a
Diffstat (limited to 'l10ntools')
-rw-r--r-- | l10ntools/Executable_gsicheck.mk | 45 | ||||
-rw-r--r-- | l10ntools/Module_l10ntools.mk | 1 | ||||
-rw-r--r-- | l10ntools/inc/tagtest.hxx | 346 | ||||
-rw-r--r-- | l10ntools/source/gsicheck.cxx | 1051 | ||||
-rw-r--r-- | l10ntools/source/tagtest.cxx | 1570 |
5 files changed, 0 insertions, 3013 deletions
diff --git a/l10ntools/Executable_gsicheck.mk b/l10ntools/Executable_gsicheck.mk deleted file mode 100644 index 829a0296939f..000000000000 --- a/l10ntools/Executable_gsicheck.mk +++ /dev/null @@ -1,45 +0,0 @@ -# -*- Mode: makefile-gmake; tab-width: 4; indent-tabs-mode: t -*- -# Version: MPL 1.1 / GPLv3+ / LGPLv3+ -# -# The contents of this file are subject to the Mozilla Public License Version -# 1.1 (the "License"); you may not use this file except in compliance with -# the License or as specified alternatively below. You may obtain a copy of -# the License at http://www.mozilla.org/MPL/ -# -# Software distributed under the License is distributed on an "AS IS" basis, -# WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License -# for the specific language governing rights and limitations under the -# License. -# -# Major Contributor(s): -# Copyright (C) 2012 David Ostrovsky <d.ostrovsky@gmx.de> (initial developer) -# -# All Rights Reserved. -# -# For minor contributions see the git repository. -# -# Alternatively, the contents of this file may be used under the terms of -# either the GNU General Public License Version 3 or later (the "GPLv3+"), or -# the GNU Lesser General Public License Version 3 or later (the "LGPLv3+"), -# in which case the provisions of the GPLv3+ or the LGPLv3+ are applicable -# instead of those above. - -$(eval $(call gb_Executable_Executable,gsicheck)) - -$(eval $(call gb_Executable_set_include,gsicheck,\ - -I$(SRCDIR)/l10ntools/inc \ - $$(INCLUDE) \ -)) - -$(eval $(call gb_Executable_use_libraries,gsicheck,\ - sal \ -)) - -$(eval $(call gb_Executable_use_unpacked,gsicheck,boost)) - -$(eval $(call gb_Executable_add_exception_objects,gsicheck,\ - l10ntools/source/gsicheck \ - l10ntools/source/tagtest \ -)) - -# vim:set shiftwidth=4 softtabstop=4 expandtab: diff --git a/l10ntools/Module_l10ntools.mk b/l10ntools/Module_l10ntools.mk index 6efcd7f45596..4b2b0f6d970d 100644 --- a/l10ntools/Module_l10ntools.mk +++ b/l10ntools/Module_l10ntools.mk @@ -31,7 +31,6 @@ $(eval $(call gb_Module_add_targets,l10ntools,\ Executable_idxdict \ Executable_ulfconv \ Executable_ulfex \ - Executable_gsicheck \ Executable_cfgex \ Executable_uiex \ Executable_xrmex \ diff --git a/l10ntools/inc/tagtest.hxx b/l10ntools/inc/tagtest.hxx deleted file mode 100644 index a6ccec4d73ea..000000000000 --- a/l10ntools/inc/tagtest.hxx +++ /dev/null @@ -1,346 +0,0 @@ -/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ -/* - * This file is part of the LibreOffice project. - * - * This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. - * - * This file incorporates work covered by the following license notice: - * - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed - * with this work for additional information regarding copyright - * ownership. The ASF licenses this file to you under the Apache - * License, Version 2.0 (the "License"); you may not use this file - * except in compliance with the License. You may obtain a copy of - * the License at http://www.apache.org/licenses/LICENSE-2.0 . - */ - -#ifndef _TAGTEST_HXX_ -#define _TAGTEST_HXX_ - -#include <boost/unordered_map.hpp> -#include <vector> - -class GSILine; - -typedef sal_Int32 TokenId; - -#define TOK_INVALIDPOS (-1) - -class ParserMessage; -typedef ::std::vector< ParserMessage* > Impl_ParserMessageList; - -class ParserMessageList; - -typedef boost::unordered_map<rtl::OString, rtl::OUString, rtl::OStringHash> StringHashMap; - -class TokenInfo -{ -private: - void SplitTag( ParserMessageList &rErrorList ); - - rtl::OUString aTagName; - StringHashMap aProperties; - sal_Bool bClosed; // tag is closed <sdnf/> - sal_Bool bCloseTag; // tag is close Tag </sdnf> - - - sal_Bool bIsBroken; - sal_Bool bHasBeenFixed; - sal_Bool bDone; - -public: - - rtl::OUString aTokenString; - TokenId nId; - sal_Int32 nPos; // Position in String - - TokenInfo():bClosed(sal_False),bCloseTag(sal_False),bIsBroken(sal_False),bHasBeenFixed(sal_False),bDone(sal_False),nId( 0 ){;} -explicit TokenInfo( TokenId pnId, sal_Int32 nP ):bClosed(sal_False),bCloseTag(sal_False),bIsBroken(sal_False),bHasBeenFixed(sal_False),bDone(sal_False),nId( pnId ),nPos(nP){;} - explicit TokenInfo( TokenId pnId, sal_Int32 nP, rtl::OUString const & paStr ):bClosed(sal_False),bCloseTag(sal_False),bIsBroken(sal_False),bHasBeenFixed(sal_False),bDone(sal_False),aTokenString( paStr ),nId( pnId ),nPos(nP) {;} - explicit TokenInfo( TokenId pnId, sal_Int32 nP, rtl::OUString const & paStr, ParserMessageList &rErrorList ); - - rtl::OUString GetTagName() const; - - rtl::OUString MakeTag() const; - - /** - Is the property to be ignored or does it have the default value anyways - **/ - sal_Bool IsPropertyRelevant( const rtl::OString &rName, const rtl::OUString &rValue ) const; - sal_Bool IsPropertyValueValid( const rtl::OString &rName, const rtl::OUString &rValue ) const; - /** - Does the property contain the same value for all languages - e.g.: the href in a link tag - **/ - sal_Bool IsPropertyInvariant( const rtl::OString &rName, const rtl::OUString &rValue ) const; - /** - a subset of IsPropertyInvariant but containing only those that are fixable - we dont wat to fix e.g.: ahelp :: visibility - **/ - sal_Bool IsPropertyFixable( const rtl::OString &rName ) const; - sal_Bool MatchesTranslation( TokenInfo& rInfo, sal_Bool bGenErrors, ParserMessageList &rErrorList, sal_Bool bFixTags = sal_False ) const; - - sal_Bool IsDone() const { return bDone; } - void SetDone( sal_Bool bNew = sal_True ) { bDone = bNew; } - - sal_Bool HasBeenFixed() const { return bHasBeenFixed; } - void SetHasBeenFixed( sal_Bool bNew = sal_True ) { bHasBeenFixed = bNew; } -}; - - -class ParserMessageList -{ -private: - Impl_ParserMessageList maList; - -public: - ~ParserMessageList() { clear(); } - void AddError( sal_Int32 nErrorNr, const rtl::OString& rErrorText, const TokenInfo &rTag ); - void AddWarning( sal_Int32 nErrorNr, const rtl::OString& rErrorText, const TokenInfo &rTag ); - - sal_Bool HasErrors(); - bool empty() const { return maList.empty(); } - size_t size() const { return maList.size(); } - ParserMessage* operator [] ( size_t i ) { return ( i < maList.size() ) ? maList[ i ] : NULL; } - void clear(); -}; - - -#define TAG_GROUPMASK 0xF000 -#define TAG_GROUPSHIFT 12 - -#define TAG_GROUP( nTag ) (( nTag & TAG_GROUPMASK ) >> TAG_GROUPSHIFT ) -#define TAG_NOGROUP( nTag ) ( nTag & ~TAG_GROUPMASK ) // ~ = Bitweises NOT - -#define TAG_NOMORETAGS 0x0 - -#define TAG_GROUP_FORMAT 0x1 -#define TAG_ON 0x100 -#define TAG_BOLDON ( TAG_GROUP_FORMAT << TAG_GROUPSHIFT | TAG_ON | 0x001 ) -#define TAG_BOLDOFF ( TAG_GROUP_FORMAT << TAG_GROUPSHIFT | 0x001 ) -#define TAG_ITALICON ( TAG_GROUP_FORMAT << TAG_GROUPSHIFT | TAG_ON | 0x002 ) -#define TAG_ITALICOFF ( TAG_GROUP_FORMAT << TAG_GROUPSHIFT | 0x002 ) -#define TAG_UNDERLINEON ( TAG_GROUP_FORMAT << TAG_GROUPSHIFT | TAG_ON | 0x004 ) -#define TAG_UNDERLINEOFF ( TAG_GROUP_FORMAT << TAG_GROUPSHIFT | 0x004 ) - -#define TAG_GROUP_NOTALLOWED 0x2 -#define TAG_HELPID ( TAG_GROUP_NOTALLOWED << TAG_GROUPSHIFT | 0x001 ) -#define TAG_MODIFY ( TAG_GROUP_NOTALLOWED << TAG_GROUPSHIFT | 0x002 ) -#define TAG_REFNR ( TAG_GROUP_NOTALLOWED << TAG_GROUPSHIFT | 0x004 ) - -#define TAG_GROUP_STRUCTURE 0x3 -#define TAG_NAME ( TAG_GROUP_STRUCTURE << TAG_GROUPSHIFT | 0x001 ) -#define TAG_HREF ( TAG_GROUP_STRUCTURE << TAG_GROUPSHIFT | 0x002 ) -#define TAG_AVIS ( TAG_GROUP_STRUCTURE << TAG_GROUPSHIFT | 0x004 ) -#define TAG_AHID ( TAG_GROUP_STRUCTURE << TAG_GROUPSHIFT | 0x008 ) - -#define TAG_TITEL ( TAG_GROUP_STRUCTURE << TAG_GROUPSHIFT | 0x020 ) -#define TAG_KEY ( TAG_GROUP_STRUCTURE << TAG_GROUPSHIFT | 0x040 ) -#define TAG_INDEX ( TAG_GROUP_STRUCTURE << TAG_GROUPSHIFT | 0x080 ) - -#define TAG_REFSTART ( TAG_GROUP_STRUCTURE << TAG_GROUPSHIFT | 0x100 ) - -#define TAG_GRAPHIC ( TAG_GROUP_STRUCTURE << TAG_GROUPSHIFT | 0x200 ) -#define TAG_NEXTVERSION ( TAG_GROUP_STRUCTURE << TAG_GROUPSHIFT | 0x400 ) - -#define TAG_GROUP_SYSSWITCH 0x4 -#define TAG_WIN ( TAG_GROUP_SYSSWITCH << TAG_GROUPSHIFT | 0x001 ) -#define TAG_UNIX ( TAG_GROUP_SYSSWITCH << TAG_GROUPSHIFT | 0x002 ) -#define TAG_MAC ( TAG_GROUP_SYSSWITCH << TAG_GROUPSHIFT | 0x004 ) -#define TAG_OS2 ( TAG_GROUP_SYSSWITCH << TAG_GROUPSHIFT | 0x008 ) - -#define TAG_GROUP_PROGSWITCH 0x5 -#define TAG_WRITER ( TAG_GROUP_PROGSWITCH << TAG_GROUPSHIFT | 0x001 ) -#define TAG_CALC ( TAG_GROUP_PROGSWITCH << TAG_GROUPSHIFT | 0x002 ) -#define TAG_DRAW ( TAG_GROUP_PROGSWITCH << TAG_GROUPSHIFT | 0x004 ) -#define TAG_IMPRESS ( TAG_GROUP_PROGSWITCH << TAG_GROUPSHIFT | 0x008 ) -#define TAG_SCHEDULE ( TAG_GROUP_PROGSWITCH << TAG_GROUPSHIFT | 0x010 ) -#define TAG_IMAGE ( TAG_GROUP_PROGSWITCH << TAG_GROUPSHIFT | 0x020 ) -#define TAG_MATH ( TAG_GROUP_PROGSWITCH << TAG_GROUPSHIFT | 0x040 ) -#define TAG_CHART ( TAG_GROUP_PROGSWITCH << TAG_GROUPSHIFT | 0x080 ) -#define TAG_OFFICE ( TAG_GROUP_PROGSWITCH << TAG_GROUPSHIFT | 0x100 ) - - -#define TAG_GROUP_META 0x6 -#define TAG_OFFICEFULLNAME ( TAG_GROUP_META << TAG_GROUPSHIFT | 0x001 ) -#define TAG_OFFICENAME ( TAG_GROUP_META << TAG_GROUPSHIFT | 0x002 ) -#define TAG_OFFICEPATH ( TAG_GROUP_META << TAG_GROUPSHIFT | 0x004 ) -#define TAG_OFFICEVERSION ( TAG_GROUP_META << TAG_GROUPSHIFT | 0x008 ) -#define TAG_PORTALNAME ( TAG_GROUP_META << TAG_GROUPSHIFT | 0x010 ) -#define TAG_PORTALFULLNAME ( TAG_GROUP_META << TAG_GROUPSHIFT | 0x020 ) -#define TAG_PORTALPATH ( TAG_GROUP_META << TAG_GROUPSHIFT | 0x040 ) -#define TAG_PORTALVERSION ( TAG_GROUP_META << TAG_GROUPSHIFT | 0x080 ) -#define TAG_PORTALSHORTNAME ( TAG_GROUP_META << TAG_GROUPSHIFT | 0x100 ) - - -#define TAG_GROUP_SINGLE 0x7 -#define TAG_REFINSERT ( TAG_GROUP_SINGLE << TAG_GROUPSHIFT | 0x001 ) - - -#define TAG_GROUP_MULTI 0x8 -#define TAG_END ( TAG_GROUP_MULTI << TAG_GROUPSHIFT | 0x010 ) -#define TAG_ELSE ( TAG_GROUP_MULTI << TAG_GROUPSHIFT | 0x020 ) -#define TAG_AEND ( TAG_GROUP_MULTI << TAG_GROUPSHIFT | 0x040 ) -#define TAG_VERSIONEND ( TAG_GROUP_MULTI << TAG_GROUPSHIFT | 0x080 ) -#define TAG_ENDGRAPHIC ( TAG_GROUP_MULTI << TAG_GROUPSHIFT | 0x100 ) - -#define TAG_GROUP_MISC 0x9 -#define TAG_COMMONSTART ( TAG_GROUP_MISC << TAG_GROUPSHIFT | 0x001 ) -#define TAG_COMMONEND ( TAG_GROUP_MISC << TAG_GROUPSHIFT | 0x002 ) - -#define TAG_UNKNOWN_TAG ( TAG_GROUP_MULTI << TAG_GROUPSHIFT | 0x800 ) - -typedef ::std::vector< TokenInfo* > TokenListImpl; - -class TokenList -{ -private: - TokenListImpl maList; - TokenList& operator =( const TokenList& rList ); - -public: - TokenList() {} - ~TokenList(){ clear(); } - - size_t size() const { return maList.size(); } - void clear() - { - for ( size_t i = 0 ; i < maList.size() ; i++ ) - delete maList[ i ]; - maList.clear(); - } - - void insert( TokenInfo p, size_t nIndex = size_t(-1) ) - { - if ( nIndex < maList.size() ) { - TokenListImpl::iterator it = maList.begin(); - ::std::advance( it, nIndex ); - maList.insert( it, new TokenInfo(p) ); - } else { - maList.push_back( new TokenInfo(p) ); - } - } - TokenInfo& operator [] ( size_t nIndex ) const - { - return *maList[ nIndex ]; - } - - TokenList( const TokenList& rList ); -}; - -class ParserMessage -{ - sal_Int32 nErrorNr; - rtl::OString aErrorText; - sal_Int32 nTagBegin,nTagLength; - -protected: - ParserMessage( sal_Int32 PnErrorNr, const rtl::OString &rPaErrorText, const TokenInfo &rTag ); -public: - - sal_Int32 GetErrorNr() { return nErrorNr; } - rtl::OString GetErrorText() { return aErrorText; } - - sal_Int32 GetTagBegin() { return nTagBegin; } - sal_Int32 GetTagLength() { return nTagLength; } - - virtual ~ParserMessage() {} - virtual sal_Bool IsError() =0; - virtual rtl::OString Prefix() =0; -}; - -class ParserError : public ParserMessage -{ -public: - ParserError( sal_Int32 PnErrorNr, const rtl::OString &rPaErrorText, const TokenInfo &rTag ); - - virtual sal_Bool IsError() {return sal_True;} - virtual rtl::OString Prefix() {return rtl::OString(RTL_CONSTASCII_STRINGPARAM("Error:")); } -}; - -class ParserWarning : public ParserMessage -{ -public: - ParserWarning( sal_Int32 PnErrorNr, const rtl::OString &rPaErrorText, const TokenInfo &rTag ); - - virtual sal_Bool IsError() {return sal_False;} - virtual rtl::OString Prefix() {return rtl::OString(RTL_CONSTASCII_STRINGPARAM("Warning:")); } -}; - -class SimpleParser -{ -private: - sal_Int32 nPos; - rtl::OUString aSource; - rtl::OUString aLastToken; - TokenList aTokenList; - - TokenInfo aNextTag; // to store closetag in case of combined tags like <br/> - - rtl::OUString GetNextTokenString( ParserMessageList &rErrorList, sal_Int32 &rTokeStartPos ); - -public: - SimpleParser(); - void Parse( rtl::OUString const & PaSource ); - TokenInfo GetNextToken( ParserMessageList &rErrorList ); - static rtl::OUString GetLexem( TokenInfo const &aToken ); - TokenList& GetTokenList(){ return aTokenList; } -}; - -class TokenParser -{ - sal_Bool match( const TokenInfo &aCurrentToken, const TokenId &aExpectedToken ); - sal_Bool match( const TokenInfo &aCurrentToken, const TokenInfo &aExpectedToken ); - void ParseError( sal_Int32 nErrNr, const rtl::OString &rErrMsg, const TokenInfo &rTag ); - void Paragraph(); - void PfCase(); - void PfCaseBegin(); - void AppCase(); - void AppCaseBegin(); - void CaseEnd(); - void SimpleTag(); - void TagPair(); - void TagRef(); - - SimpleParser aParser; - TokenInfo aTag; - - TokenId nPfCaseOptions; - TokenId nAppCaseOptions; - sal_Bool bPfCaseActive ,bAppCaseActive; - - TokenId nActiveRefTypes; - - ParserMessageList *pErrorList; - -public: - TokenParser(); - void Parse( const rtl::OUString &aCode, ParserMessageList* pList ); - TokenList& GetTokenList(){ return aParser.GetTokenList(); } -}; - -class LingTest -{ -private: - TokenParser aReferenceParser; - TokenParser aTesteeParser; - ParserMessageList aCompareWarningList; - void CheckTags( TokenList &aReference, TokenList &aTestee, sal_Bool bFixTags ); - sal_Bool IsTagMandatory( TokenInfo const &aToken, TokenId &aMetaTokens ); - rtl::OUString aFixedTestee; -public: - void CheckReference( GSILine *aReference ); - void CheckTestee( GSILine *aTestee, sal_Bool bHasSourceLine, sal_Bool bFixTags ); - - ParserMessageList& GetCompareWarnings(){ return aCompareWarningList; } - sal_Bool HasCompareWarnings(){ return ( !aCompareWarningList.empty() ); } - - rtl::OUString GetFixedTestee(){ return aFixedTestee; } -}; - -#endif - -/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/l10ntools/source/gsicheck.cxx b/l10ntools/source/gsicheck.cxx deleted file mode 100644 index 1abc00d17ac9..000000000000 --- a/l10ntools/source/gsicheck.cxx +++ /dev/null @@ -1,1051 +0,0 @@ -/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ -/************************************************************************* - * - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * Copyright 2000, 2010 Oracle and/or its affiliates. - * - * OpenOffice.org - a multi-platform office productivity suite - * - * This file is part of OpenOffice.org. - * - * OpenOffice.org is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License version 3 - * only, as published by the Free Software Foundation. - * - * OpenOffice.org is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License version 3 for more details - * (a copy is included in the LICENSE file that accompanied this code). - * - * You should have received a copy of the GNU Lesser General Public License - * version 3 along with OpenOffice.org. If not, see - * <http://www.openoffice.org/license.html> - * for a copy of the LGPLv3 License. - * - ************************************************************************/ - -#include "sal/config.h" - -#include <algorithm> -#include <cassert> -#include <cstddef> -#include <fstream> -#include <string> - -#include <stdio.h> - -#include <rtl/strbuf.hxx> -#include "sal/main.h" -#include "helper.hxx" -#include "tagtest.hxx" -#include "gsicheck.hxx" - -sal_Int32 const MAX_GID_LID_LEN = 250; - -namespace { - -rtl::OString copyUpTo( - rtl::OString const & text, sal_Int32 start, sal_Int32 maximumLength) -{ - assert(start >= 0 && start <= text.getLength()); - return text.copy(start, std::min(text.getLength() - start, maximumLength)); -} - -rtl::OString addSuffix( - rtl::OString const & pathname, rtl::OString const & suffix) -{ - sal_Int32 n = pathname.lastIndexOf('.'); - if (n == -1) { - fprintf( - stderr, - ("Error: pathname \"%s\" does not contain dot to add suffix in" - " front of\n"), - pathname.getStr()); - exit(EXIT_FAILURE); - } - return pathname.replaceAt(n, 0, suffix); -} - -} - -/*****************************************************************************/ -void PrintMessage( rtl::OString const & aType, rtl::OString const & aMsg, rtl::OString const & aPrefix, - rtl::OString const & aContext, sal_Bool bPrintContext, std::size_t nLine, rtl::OString aUniqueId = rtl::OString() ) -/*****************************************************************************/ -{ - fprintf( stdout, "%s %s, Line %u", aType.getStr(), aPrefix.getStr(), static_cast<unsigned>( nLine ) ); - if ( !aUniqueId.isEmpty() ) - fprintf( stdout, ", UniqueID %s", aUniqueId.getStr() ); - fprintf( stdout, ": %s", aMsg.getStr() ); - - if ( bPrintContext ) - fprintf( stdout, " \"%s\"", aContext.getStr() ); - fprintf( stdout, "\n" ); -} - -/*****************************************************************************/ -void PrintError( rtl::OString const & aMsg, rtl::OString const & aPrefix, - rtl::OString const & aContext, sal_Bool bPrintContext, std::size_t nLine, rtl::OString const & aUniqueId = rtl::OString() ) -/*****************************************************************************/ -{ - PrintMessage( "Error:", aMsg, aPrefix, aContext, bPrintContext, nLine, aUniqueId ); -} - -bool LanguageOK( rtl::OString const & aLang ) -{ - sal_Int32 n = 0; - rtl::OString t0(aLang.getToken(0, '-', n)); - if (n == -1) { - return !t0.isEmpty() - && (helper::isAllAsciiDigits(t0) - || helper::isAllAsciiLowerCase(t0)); - } - rtl::OString t1(aLang.getToken(0, '-', n)); - return n == -1 - && !t0.isEmpty() && helper::isAllAsciiLowerCase(t0) - && !t1.isEmpty() && helper::isAllAsciiUpperCase(t1) - && !t0.equalsIgnoreAsciiCase(t1); -} - -class LazyStream: public std::ofstream -{ - -private: - rtl::OString aFileName; - bool bOpened; - -public: - LazyStream() - : aFileName() - , bOpened(false) - {}; - - void SetFileName( const rtl::OString& rFileName ) - { - aFileName = rFileName; - }; - - void LazyOpen(); -}; - -void LazyStream::LazyOpen() -{ - if ( !bOpened ) - { - open(aFileName.getStr(), std::ios_base::out | std::ios_base::trunc); - if (!is_open()) - { - fprintf( stderr, "\nERROR: Could not open Output-File %s!\n\n", - aFileName.getStr() ); - exit ( 4 ); - } - bOpened = true; - } -} - - -// -// class GSILine -// - -/*****************************************************************************/ -GSILine::GSILine( const rtl::OString &rLine, std::size_t nLine ) -/*****************************************************************************/ - : nLineNumber( nLine ) - , bOK( sal_True ) - , bFixed ( sal_False ) - , data_( rLine ) -{ - if (rLine.isEmpty()) { - NotOK(); - return; - } - - aFormat = FORMAT_SDF; - sal_Int32 n = 0; - aUniqId = rLine.getToken(0, '\t', n); // token 0 - aUniqId += "/"; - aUniqId += rLine.getToken(0, '\t', n); // token 1 - aUniqId += "/"; - aUniqId += rLine.getToken(1, '\t', n); // token 3 - aUniqId += "/"; - rtl::OString gid(rLine.getToken(0, '\t', n)); // token 4 - aUniqId += gid; - aUniqId += "/"; - rtl::OString lid(rLine.getToken(0, '\t', n)); // token 5 - aUniqId += lid; - aUniqId += "/"; - aUniqId += rLine.getToken(0, '\t', n); // token 6 - aUniqId += "/"; - aUniqId += rLine.getToken(0, '\t', n); // token 7 - rtl::OString length(rLine.getToken(0, '\t', n)); // token 8 - aLineType = rtl::OString(); - aLangId = rLine.getToken(0, '\t', n); // token 9 - aText = rLine.getToken(0, '\t', n); // token 10 - aQuickHelpText = rLine.getToken(1, '\t', n); // token 12 - aTitle = rLine.getToken(0, '\t', n); // token 13 - if (n == -1) { - NotOK(); - return; - } - rLine.getToken(0, '\t', n); // token 14 - if (n != -1) { - NotOK(); - return; - } - - // do some more format checks here - if (!helper::isAllAsciiDigits(length)) { - PrintError( - "The length field does not contain a number!", "Line format", - length, true, GetLineNumber(), GetUniqId()); - NotOK(); - } - if (!LanguageOK(aLangId)) { - PrintError( - "The Language is invalid!", "Line format", aLangId, true, - GetLineNumber(), GetUniqId()); - NotOK(); - } - // Limit GID and LID to MAX_GID_LID_LEN chars each for database conformity, - // see #137575#: - if (gid.getLength() > MAX_GID_LID_LEN || lid.getLength() > MAX_GID_LID_LEN) - { - PrintError( - (rtl::OString( - RTL_CONSTASCII_STRINGPARAM("GID and LID may only be ")) - + rtl::OString::valueOf(MAX_GID_LID_LEN) - + rtl::OString(RTL_CONSTASCII_STRINGPARAM(" chars long each"))), - "Line format", aLangId, true, GetLineNumber(), GetUniqId()); - NotOK(); - } -} - -/*****************************************************************************/ -void GSILine::NotOK() -/*****************************************************************************/ -{ - bOK = sal_False; -} - -/*****************************************************************************/ -void GSILine::ReassembleLine() -/*****************************************************************************/ -{ - if (GetLineFormat() != FORMAT_SDF) { - PrintError( - "Cannot reassemble line of unknown type (internal Error).", - "Line format", rtl::OString(), false, GetLineNumber(), - GetUniqId()); - return; - } - rtl::OStringBuffer b; - sal_Int32 n = 0; - for (sal_Int32 i = 0; i != 10; ++i) { - b.append(data_.getToken(0, '\t', n)); // token 0--9 - b.append('\t'); - } - b.append(aText); - b.append('\t'); - b.append(data_.getToken(1, '\t', n)); - // token 11; should be empty but there are some places in sc not - // reflected to sources - b.append('\t'); - b.append(aQuickHelpText); - b.append('\t'); - b.append(aTitle); - b.append('\t'); - b.append(data_.getToken(2, '\t', n)); // token 14 - data_ = b.makeStringAndClear(); -} - -// -// class GSIBlock -// -/*****************************************************************************/ -GSIBlock::GSIBlock( sal_Bool PbPrintContext, sal_Bool bSource, sal_Bool bTrans, sal_Bool bRef, sal_Bool bAllowSusp ) -/*****************************************************************************/ - : pSourceLine( NULL ) - , pReferenceLine( NULL ) - , bPrintContext( PbPrintContext ) - , bCheckSourceLang( bSource ) - , bCheckTranslationLang( bTrans ) - , bReference( bRef ) - , bAllowSuspicious( bAllowSusp ) - , bHasBlockError( sal_False ) -{ -} - -/*****************************************************************************/ -GSIBlock::~GSIBlock() -/*****************************************************************************/ -{ - delete pSourceLine; - delete pReferenceLine; - - for ( size_t i = 0, n = maList.size(); i < n; ++i ) - delete maList[ i ]; - maList.clear(); -} - -void GSIBlock::InsertLine( GSILine* pLine, const rtl::OString &rSourceLang) -{ - if ( pLine->GetLanguageId() == rSourceLang ) - { - if ( pSourceLine ) - { - PrintError( "Source Language entry double. Treating as Translation.", "File format", "", pLine->GetLineNumber(), pLine->GetUniqId() ); - bHasBlockError = sal_True; - pSourceLine->NotOK(); - pLine->NotOK(); - } - else - { - pSourceLine = pLine; - return; - } - } - - if (!rSourceLang.isEmpty()) // only check blockstructure if source lang is given - { - for ( size_t nPos = 0, n = maList.size(); nPos < n; ++nPos ) - { - if ( maList[ nPos ]->GetLanguageId() == pLine->GetLanguageId() ) - { - PrintError( "Translation Language entry double. Checking both.", "File format", "", pLine->GetLineNumber(), pLine->GetUniqId() ); - bHasBlockError = sal_True; - maList[ nPos ]->NotOK(); - pLine->NotOK(); - } - nPos++; - } - } - maList.push_back( pLine ); -} - -/*****************************************************************************/ -void GSIBlock::SetReferenceLine( GSILine* pLine ) -/*****************************************************************************/ -{ - pReferenceLine = pLine; -} - -/*****************************************************************************/ -void GSIBlock::PrintMessage( rtl::OString const & aType, rtl::OString const & aMsg, rtl::OString const & aPrefix, - rtl::OString const & aContext, std::size_t nLine, rtl::OString const & aUniqueId ) -/*****************************************************************************/ -{ - ::PrintMessage( aType, aMsg, aPrefix, aContext, bPrintContext, nLine, aUniqueId ); -} - -/*****************************************************************************/ -void GSIBlock::PrintError( rtl::OString const & aMsg, rtl::OString const & aPrefix, - rtl::OString const & aContext, std::size_t nLine, rtl::OString const & aUniqueId ) -/*****************************************************************************/ -{ - PrintMessage( "Error:", aMsg, aPrefix, aContext, nLine, aUniqueId ); -} - -/*****************************************************************************/ -void GSIBlock::PrintList( ParserMessageList *pList, rtl::OString const & aPrefix, - GSILine *pLine ) -/*****************************************************************************/ -{ - for ( size_t i = 0 ; i < pList->size() ; i++ ) - { - ParserMessage *pMsg = (*pList)[ i ]; - rtl::OString aContext; - if ( bPrintContext ) - { - if ( pMsg->GetTagBegin() == -1 ) - aContext = pLine->GetText().copy( 0, 300 ); - else - aContext = helper::abbreviate( pLine->data_, pMsg->GetTagBegin()-150, 300 ); - aContext = aContext.trim(); - } - - PrintMessage( pMsg->Prefix(), pMsg->GetErrorText(), aPrefix, aContext, pLine->GetLineNumber(), pLine->GetUniqId() ); - } -} - -/*****************************************************************************/ -sal_Bool GSIBlock::IsUTF8( const rtl::OString &aTestee, sal_Bool bFixTags, sal_Int32 &nErrorPos, rtl::OString &aErrorMsg, sal_Bool &bHasBeenFixed, rtl::OString &aFixed ) const -/*****************************************************************************/ -{ - rtl::OUString aUTF8Tester( - rtl::OStringToOUString(aTestee, RTL_TEXTENCODING_UTF8)); - rtl::OString aTestee2( - rtl::OUStringToOString(aUTF8Tester, RTL_TEXTENCODING_UTF8)); - sal_Int32 i = 0; - while (i != std::min(aTestee.getLength(), aTestee2.getLength()) - && aTestee[i] == aTestee2[i]) - { - ++i; - } - if (i != aTestee.getLength() || i != aTestee2.getLength()) - { - aUTF8Tester = rtl::OUString(aTestee.getStr(), i, RTL_TEXTENCODING_UTF8); - nErrorPos = aUTF8Tester.getLength(); - aErrorMsg = "UTF8 Encoding seems to be broken"; - return sal_False; - } - - nErrorPos = helper::indexOfAnyAsciiL( - aUTF8Tester, - RTL_CONSTASCII_STRINGPARAM( - "\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0b\x0c\x0e\x0f\x10\x11\x12" - "\x13\x14\x15\x16\x17\x18\x19\x1a\x1b\x1c\x1d\x1e\x1f\x7f")); - if (nErrorPos != -1) - { - aErrorMsg = "String contains illegal character"; - return sal_False; - } - - if ( bFixTags ) - { - bHasBeenFixed = sal_False; - aFixed = rtl::OString(); - } - - return sal_True; -} - -/*****************************************************************************/ -sal_Bool GSIBlock::TestUTF8( GSILine* pTestee, sal_Bool bFixTags ) -/*****************************************************************************/ -{ - sal_Int32 nErrorPos = 0; - rtl::OString aErrorMsg; - sal_Bool bError = sal_False; - rtl::OString aFixed; - sal_Bool bHasBeenFixed = sal_False; - if ( !IsUTF8( pTestee->GetText(), bFixTags, nErrorPos, aErrorMsg, bHasBeenFixed, aFixed ) ) - { - rtl::OString aContext(copyUpTo(pTestee->GetText(), nErrorPos, 20)); - PrintError(rtl::OStringBuffer(aErrorMsg).append(RTL_CONSTASCII_STRINGPARAM(" in Text at Position ")) - .append(nErrorPos).getStr(), - "Text format", aContext, pTestee->GetLineNumber(), pTestee->GetUniqId()); - bError = sal_True; - if ( bHasBeenFixed ) - { - pTestee->SetText( aFixed ); - pTestee->SetFixed(); - } - } - if ( !IsUTF8( pTestee->GetQuickHelpText(), bFixTags, nErrorPos, aErrorMsg, bHasBeenFixed, aFixed ) ) - { - rtl::OString aContext( - copyUpTo(pTestee->GetQuickHelpText(), nErrorPos, 20)); - PrintError(rtl::OStringBuffer(aErrorMsg).append(RTL_CONSTASCII_STRINGPARAM(" in QuickHelpText at Position ")) - .append(nErrorPos).getStr(), - "Text format", aContext, pTestee->GetLineNumber(), pTestee->GetUniqId()); - bError = sal_True; - if ( bHasBeenFixed ) - { - pTestee->SetQuickHelpText( aFixed ); - pTestee->SetFixed(); - } - } - if ( !IsUTF8( pTestee->GetTitle(), bFixTags, nErrorPos, aErrorMsg, bHasBeenFixed, aFixed ) ) - { - rtl::OString aContext( pTestee->GetTitle().copy( nErrorPos, 20 ) ); - PrintError(rtl::OStringBuffer(aErrorMsg).append(RTL_CONSTASCII_STRINGPARAM(" in Title at Position ")) - .append(nErrorPos).getStr(), - "Text format", aContext, pTestee->GetLineNumber(), pTestee->GetUniqId()); - bError = sal_True; - if ( bHasBeenFixed ) - { - pTestee->SetTitle( aFixed ); - pTestee->SetFixed(); - } - } - if ( bError ) - pTestee->NotOK(); - return !bError; -} - - -/*****************************************************************************/ -sal_Bool GSIBlock::HasSuspiciousChars( GSILine* pTestee, GSILine* pSource ) -/*****************************************************************************/ -{ - sal_Int32 nPos = 0; - if ( !bAllowSuspicious && ( nPos = pTestee->GetText().indexOf("??")) != -1 ) - if ( pSource->GetText().indexOf("??") == -1 ) - { - rtl::OUString aUTF8Tester( - rtl::OStringToOUString( - pTestee->GetText().copy(0, nPos), RTL_TEXTENCODING_UTF8)); - sal_Int32 nErrorPos = aUTF8Tester.getLength(); - rtl::OString aContext( helper::abbreviate( pTestee->GetText(), nPos, 20 ) ); - PrintError(rtl::OStringBuffer(RTL_CONSTASCII_STRINGPARAM("Found double questionmark in translation only. Looks like an encoding problem at Position ")) - .append(nErrorPos).getStr(), - "Text format", aContext, pTestee->GetLineNumber(), pTestee->GetUniqId()); - pTestee->NotOK(); - return sal_True; - } - - return sal_False; -} - - -/*****************************************************************************/ -sal_Bool GSIBlock::CheckSyntax( std::size_t nLine, sal_Bool bRequireSourceLine, sal_Bool bFixTags ) -/*****************************************************************************/ -{ - static LingTest aTester; - sal_Bool bHasError = sal_False; - - if ( !pSourceLine ) - { - if ( bRequireSourceLine ) - { - PrintError( "No source language entry defined!", "File format", "", nLine ); - bHasBlockError = sal_True; - } - } - else - { - aTester.CheckReference( pSourceLine ); - if ( pSourceLine->HasMessages() ) - { - PrintList( pSourceLine->GetMessageList(), "ReferenceString", pSourceLine ); - pSourceLine->NotOK(); - bHasError = sal_True; - } - } - if ( bReference ) - { - if ( !pReferenceLine ) - { - GSILine *pSource; - if ( pSourceLine ) - pSource = pSourceLine; - else - pSource = maList.empty() ? NULL : maList[ 0 ]; // get some other line - if ( pSource ) - PrintError( "No reference line found. Entry is new in source file", "File format", "", pSource->GetLineNumber(), pSource->GetUniqId() ); - else - PrintError( "No reference line found. Entry is new in source file", "File format", "", nLine ); - bHasBlockError = sal_True; - } - else - { - if ( pSourceLine && pSourceLine->data_ != pReferenceLine->data_ ) - { - sal_Int32 nPos = pSourceLine->data_.indexOf( pReferenceLine->data_ ); - rtl::OStringBuffer aContext( pReferenceLine->data_.copy( nPos - 5, 15) ); - aContext.append( "\" --> \"" ).append( pSourceLine->data_.copy( nPos - 5, 15) ); - PrintError( "Source Language Entry has changed.", "File format", aContext.makeStringAndClear(), pSourceLine->GetLineNumber(), pSourceLine->GetUniqId() ); - pSourceLine->NotOK(); - bHasError = sal_True; - } - } - } - - if ( pSourceLine ) - bHasError |= !TestUTF8( pSourceLine, bFixTags ); - - for ( size_t i = 0, n = maList.size(); i < n; ++i ) - { - GSILine* pItem = maList[ i ]; - aTester.CheckTestee( pItem, pSourceLine != NULL, bFixTags ); - if ( pItem->HasMessages() || aTester.HasCompareWarnings() ) - { - if ( pItem->HasMessages() || aTester.GetCompareWarnings().HasErrors() ) - pItem->NotOK(); - bHasError = sal_True; - PrintList( pItem->GetMessageList(), "Translation", pItem ); - PrintList( &(aTester.GetCompareWarnings()), "Translation Tag Mismatch", pItem ); - } - bHasError |= !TestUTF8( pItem, bFixTags ); - if ( pSourceLine ) - bHasError |= HasSuspiciousChars( pItem, pSourceLine ); - } - - return bHasError || bHasBlockError; -} - -void GSIBlock::WriteError( LazyStream &aErrOut, sal_Bool bRequireSourceLine ) -{ - if ( pSourceLine && pSourceLine->IsOK() && bCheckSourceLang && !bHasBlockError ) - return; - - sal_Bool bHasError = sal_False; - sal_Bool bCopyAll = ( !pSourceLine && bRequireSourceLine ) || ( pSourceLine && !pSourceLine->IsOK() && !bCheckTranslationLang ) || bHasBlockError; - for ( size_t i = 0, n = maList.size(); i < n; ++i ) - { - GSILine* pItem = maList[ i ]; - if ( !pItem->IsOK() || bCopyAll ) - { - bHasError = sal_True; - aErrOut.LazyOpen(); - aErrOut << pItem->data_.getStr() << '\n'; - } - } - - if ( pSourceLine && ( bHasError || !pSourceLine->IsOK() ) && !( !bHasError && bCheckTranslationLang ) ) - { - aErrOut.LazyOpen(); - aErrOut << pSourceLine->data_.getStr() << '\n'; - } -} - -void GSIBlock::WriteCorrect( LazyStream &aOkOut, sal_Bool bRequireSourceLine ) -{ - if ( ( !pSourceLine && bRequireSourceLine ) || ( pSourceLine && !pSourceLine->IsOK() && !bCheckTranslationLang ) ) - return; - - sal_Bool bHasOK = sal_False; - for ( size_t i = 0, n = maList.size(); i < n; ++i ) - { - GSILine* pItem = maList[ i ]; - if ( ( pItem->IsOK() || bCheckSourceLang ) && !bHasBlockError ) - { - bHasOK = sal_True; - aOkOut.LazyOpen(); - aOkOut << pItem->data_.getStr() << '\n'; - } - } - - if ( ( pSourceLine && pSourceLine->IsOK() && ( !maList.empty() || !bCheckTranslationLang ) ) || ( bHasOK && bCheckTranslationLang ) ) - { - aOkOut.LazyOpen(); - aOkOut << pSourceLine->data_.getStr() << '\n'; - } -} - -void GSIBlock::WriteFixed( LazyStream &aFixOut ) -{ - if ( pSourceLine && !pSourceLine->IsFixed() && bCheckSourceLang ) - return; - - sal_Bool bHasFixes = sal_False; - for ( size_t i = 0, n = maList.size(); i < n; ++i ) - { - GSILine* pItem = maList[ i ]; - if ( pItem->IsFixed() ) - { - bHasFixes = sal_True; - aFixOut.LazyOpen(); - aFixOut << pItem->data_.getStr() << '\n'; - } - } - - if ( pSourceLine && ( bHasFixes || pSourceLine->IsFixed() ) ) - { - aFixOut.LazyOpen(); - aFixOut << pSourceLine->data_.getStr() << '\n'; - } -} - - -/*****************************************************************************/ -/*****************************************************************************/ -/*****************************************************************************/ -/*****************************************************************************/ -/*****************************************************************************/ -/*****************************************************************************/ -/*****************************************************************************/ - -/*****************************************************************************/ -void Help() -/*****************************************************************************/ -{ - fprintf( stdout, "\n" ); - fprintf( stdout, "gsicheck checks the syntax of tags in SDF-Files\n" ); - fprintf( stdout, " checks for inconsistencies and malicious UTF8 encoding\n" ); - fprintf( stdout, " checks tags in Online Help\n" ); - fprintf( stdout, " relax GID/LID length to %s\n", - rtl::OString::valueOf(static_cast<sal_Int32>(MAX_GID_LID_LEN)).getStr() ); - fprintf( stdout, "\n" ); - fprintf( stdout, "Syntax: gsicheck [ -c ] [-f] [ -we ] [ -wef ErrorFilename ] [ -wc ]\n" ); - fprintf( stdout, " [ -wcf CorrectFilename ] [ -s | -t ] [ -l LanguageID ]\n" ); - fprintf( stdout, " [ -r ReferenceFile ] filename\n" ); - fprintf( stdout, "\n" ); - fprintf( stdout, "-c Add context to error message (Print the line containing the error)\n" ); - fprintf( stdout, "-f try to fix errors. See also -wf -wff \n" ); - fprintf( stdout, "-wf Write File containing all fixed parts\n" ); - fprintf( stdout, "-wff Same as above but give own filename\n" ); - fprintf( stdout, "-we Write File containing all errors\n" ); - fprintf( stdout, "-wef Same as above but give own filename\n" ); - fprintf( stdout, "-wc Write File containing all correct parts\n" ); - fprintf( stdout, "-wcf Same as above but give own filename\n" ); - fprintf( stdout, "-s Check only source language. Should be used before handing out to vendor.\n" ); - fprintf( stdout, "-t Check only Translation language(s). Should be used before merging.\n" ); - fprintf( stdout, "-e disable encoding checks. E.g.: double questionmark \'??\' which may be the\n" ); - fprintf( stdout, " result of false conversions\n" ); - fprintf( stdout, "-l ISO language code of the source language.\n" ); - fprintf( stdout, " Default is en-US. Use \"\" (empty string) or 'none'\n" ); - fprintf( stdout, " to disable source language dependent checks\n" ); - fprintf( stdout, "-r Reference filename to check that source language entries\n" ); - fprintf( stdout, " have not been changed\n" ); - fprintf( stdout, "\n" ); -} - -SAL_IMPLEMENT_MAIN_WITH_ARGS(argc, argv) { - sal_Bool bError = sal_False; - sal_Bool bPrintContext = sal_False; - sal_Bool bCheckSourceLang = sal_False; - sal_Bool bCheckTranslationLang = sal_False; - sal_Bool bWriteError = sal_False; - sal_Bool bWriteCorrect = sal_False; - sal_Bool bWriteFixed = sal_False; - sal_Bool bFixTags = sal_False; - sal_Bool bAllowSuspicious = sal_False; - rtl::OString aErrorFilename; - rtl::OString aCorrectFilename; - rtl::OString aFixedFilename; - sal_Bool bFileHasError = sal_False; - rtl::OString aSourceLang( "en-US" ); // English is default - rtl::OString aFilename; - rtl::OString aReferenceFilename; - sal_Bool bReferenceFile = sal_False; - for ( int i = 1 ; i < argc ; i++ ) - { - if ( *argv[ i ] == '-' ) - { - switch (*(argv[ i ]+1)) - { - case 'c':bPrintContext = sal_True; - break; - case 'w': - { - if ( (*(argv[ i ]+2)) == 'e' ) - { - if ( (*(argv[ i ]+3)) == 'f' ) - if ( (i+1) < argc ) - { - aErrorFilename = argv[i + 1]; - bWriteError = sal_True; - i++; - } - else - { - fprintf( stderr, "\nERROR: Switch %s requires parameter!\n\n", argv[ i ] ); - bError = sal_True; - } - else - bWriteError = sal_True; - } - else if ( (*(argv[ i ]+2)) == 'c' ) - if ( (*(argv[ i ]+3)) == 'f' ) - if ( (i+1) < argc ) - { - aCorrectFilename = argv[i + 1]; - bWriteCorrect = sal_True; - i++; - } - else - { - fprintf( stderr, "\nERROR: Switch %s requires parameter!\n\n", argv[ i ] ); - bError = sal_True; - } - else - bWriteCorrect = sal_True; - else if ( (*(argv[ i ]+2)) == 'f' ) - if ( (*(argv[ i ]+3)) == 'f' ) - if ( (i+1) < argc ) - { - aFixedFilename = argv[i + 1]; - bWriteFixed = sal_True; - bFixTags = sal_True; - i++; - } - else - { - fprintf( stderr, "\nERROR: Switch %s requires parameter!\n\n", argv[ i ] ); - bError = sal_True; - } - else - { - bWriteFixed = sal_True; - bFixTags = sal_True; - } - else - { - fprintf( stderr, "\nERROR: Unknown Switch %s!\n\n", argv[ i ] ); - bError = sal_True; - } - } - break; - case 's':bCheckSourceLang = sal_True; - break; - case 't':bCheckTranslationLang = sal_True; - break; - case 'l': - { - if ( (i+1) < argc ) - { - aSourceLang = argv[ i+1 ]; - if ( aSourceLang.equalsIgnoreAsciiCaseL(RTL_CONSTASCII_STRINGPARAM("none")) ) - aSourceLang = rtl::OString(); - i++; - } - else - { - fprintf( stderr, "\nERROR: Switch %s requires parameter!\n\n", argv[ i ] ); - bError = sal_True; - } - } - break; - case 'r': - { - if ( (i+1) < argc ) - { - aReferenceFilename = argv[ i+1 ]; - bReferenceFile = sal_True; - i++; - } - else - { - fprintf( stderr, "\nERROR: Switch %s requires parameter!\n\n", argv[ i ] ); - bError = sal_True; - } - } - break; - case 'f': - { - bFixTags = sal_True; - } - break; - case 'e': - { - bAllowSuspicious = sal_True; - } - break; - default: - fprintf( stderr, "\nERROR: Unknown Switch %s!\n\n", argv[ i ] ); - bError = sal_True; - } - } - else - { - if (aFilename.isEmpty()) - aFilename = argv[i]; - else - { - fprintf( stderr, "\nERROR: Only one filename may be specified!\n\n"); - bError = sal_True; - } - } - } - - - if (aFilename.isEmpty() || bError) - { - Help(); - exit ( 0 ); - } - - if ( !aSourceLang.isEmpty() && !LanguageOK( aSourceLang ) ) - { - fprintf( stderr, "\nERROR: The Language '%s' is invalid!\n\n", aSourceLang.getStr() ); - Help(); - exit ( 1 ); - } - - if ( bCheckSourceLang && bCheckTranslationLang ) - { - fprintf( stderr, "\nERROR: The Options -s and -t are mutually exclusive.\nUse only one of them.\n\n" ); - Help(); - exit ( 1 ); - } - - - - std::ifstream aGSI(aFilename.getStr()); - if (!aGSI.is_open()) { - fprintf( stderr, "\nERROR: Could not open GSI-File %s!\n\n", aFilename.getStr() ); - exit ( 3 ); - } - - std::ifstream aReferenceGSI; - if ( bReferenceFile ) - { - aReferenceGSI.open(aReferenceFilename.getStr()); - if (!aReferenceGSI.is_open()) { - fprintf( stderr, "\nERROR: Could not open Input-File %s!\n\n", aFilename.getStr() ); - exit ( 3 ); - } - } - - LazyStream aOkOut; - if ( bWriteCorrect ) - { - if (aCorrectFilename.isEmpty()) - { - aCorrectFilename = addSuffix( - aFilename, rtl::OString(RTL_CONSTASCII_STRINGPARAM("_ok"))); - } - aOkOut.SetFileName(aCorrectFilename); - } - - LazyStream aErrOut; - if ( bWriteError ) - { - if (aErrorFilename.isEmpty()) - { - aErrorFilename = addSuffix( - aFilename, rtl::OString(RTL_CONSTASCII_STRINGPARAM("_err"))); - } - aErrOut.SetFileName(aErrorFilename); - } - - LazyStream aFixOut; - if ( bWriteFixed ) - { - if (aFixedFilename.isEmpty()) - { - aFixedFilename = addSuffix( - aFilename, rtl::OString(RTL_CONSTASCII_STRINGPARAM("_fix"))); - } - aFixOut.SetFileName(aFixedFilename); - } - - - GSILine* pReferenceLine = NULL; - std::size_t nReferenceLine = 0; - - GSILine* pGSILine = NULL; - rtl::OString aOldId("No Valid ID"); // just set to something which can never be an ID - GSIBlock *pBlock = NULL; - std::size_t nLine = 0; - - while (!aGSI.eof()) - { - std::string s; - std::getline(aGSI, s); - nLine++; - pGSILine = new GSILine(rtl::OString(s.data(), s.length()), nLine ); - sal_Bool bDelete = sal_True; - - - if ( !pGSILine->data_.isEmpty() ) - { - if ( FORMAT_UNKNOWN == pGSILine->GetLineFormat() ) - { - PrintError( "Format of line is unknown. Ignoring!", "Line format", pGSILine->data_.copy( 0,40 ), bPrintContext, pGSILine->GetLineNumber() ); - pGSILine->NotOK(); - if ( bWriteError ) - { - bFileHasError = sal_True; - aErrOut.LazyOpen(); - aErrOut << pGSILine->data_.getStr(); - } - } - else if ( pGSILine->GetLineType().equalsIgnoreAsciiCaseL(RTL_CONSTASCII_STRINGPARAM("res-comment")) ) - { // ignore comment lines, but write them to Correct Items File - if ( bWriteCorrect ) - { - aOkOut.LazyOpen(); - aOkOut << pGSILine->data_.getStr() << '\n'; - } - } - else - { - rtl::OString aId = pGSILine->GetUniqId(); - if ( aId != aOldId ) - { - if ( pBlock ) - { - bFileHasError |= pBlock->CheckSyntax( nLine, !aSourceLang.isEmpty(), bFixTags ); - - if ( bWriteError ) - pBlock->WriteError( aErrOut, !aSourceLang.isEmpty() ); - if ( bWriteCorrect ) - pBlock->WriteCorrect( aOkOut, !aSourceLang.isEmpty() ); - if ( bWriteFixed ) - pBlock->WriteFixed( aFixOut ); - - delete pBlock; - } - pBlock = new GSIBlock( bPrintContext, bCheckSourceLang, bCheckTranslationLang, bReferenceFile, bAllowSuspicious ); - - aOldId = aId; - - - // find corresponding line in reference file - if ( bReferenceFile ) - { - sal_Bool bContinueSearching = sal_True; - while ( ( !aReferenceGSI.eof() || pReferenceLine ) && bContinueSearching ) - { - if ( !pReferenceLine ) - { - std::string s2; - std::getline(aReferenceGSI, s2); - nReferenceLine++; - pReferenceLine = new GSILine( - rtl::OString(s2.data(), s2.length()), - nReferenceLine); - } - if ( pReferenceLine->GetLineFormat() != FORMAT_UNKNOWN ) - { - if ( pReferenceLine->GetUniqId() == aId && pReferenceLine->GetLanguageId() == aSourceLang ) - { - pBlock->SetReferenceLine( pReferenceLine ); - pReferenceLine = NULL; - } - else if ( pReferenceLine->GetUniqId() > aId ) - { - bContinueSearching = sal_False; - } - else - { - if ( pReferenceLine->GetUniqId() < aId && pReferenceLine->GetLanguageId() == aSourceLang ) - PrintError( "No Entry in source file found. Entry has been removed from source file", "File format", "", bPrintContext, pGSILine->GetLineNumber(), pReferenceLine->GetUniqId() ); - delete pReferenceLine; - pReferenceLine = NULL; - } - } - else - { - delete pReferenceLine; - pReferenceLine = NULL; - } - - } - } - - } - - pBlock->InsertLine( pGSILine, aSourceLang ); - bDelete = sal_False; - } - } - if ( bDelete ) - delete pGSILine; - - } - if ( pBlock ) - { - bFileHasError |= pBlock->CheckSyntax( nLine, !aSourceLang.isEmpty(), bFixTags ); - - if ( bWriteError ) - pBlock->WriteError( aErrOut, !aSourceLang.isEmpty() ); - if ( bWriteCorrect ) - pBlock->WriteCorrect( aOkOut, !aSourceLang.isEmpty() ); - if ( bWriteFixed ) - pBlock->WriteFixed( aFixOut ); - - delete pBlock; - } - aGSI.close(); - - if ( bWriteError ) - aErrOut.close(); - if ( bWriteCorrect ) - aOkOut.close(); - if ( bWriteFixed ) - aFixOut.close(); - - if ( bFileHasError ) - return 55; - else - return 0; -} - -/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/l10ntools/source/tagtest.cxx b/l10ntools/source/tagtest.cxx deleted file mode 100644 index ada1a36582f1..000000000000 --- a/l10ntools/source/tagtest.cxx +++ /dev/null @@ -1,1570 +0,0 @@ -/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ -/* - * This file is part of the LibreOffice project. - * - * This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. - * - * This file incorporates work covered by the following license notice: - * - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed - * with this work for additional information regarding copyright - * ownership. The ASF licenses this file to you under the Apache - * License, Version 2.0 (the "License"); you may not use this file - * except in compliance with the License. You may obtain a copy of - * the License at http://www.apache.org/licenses/LICENSE-2.0 . - */ - -#include "sal/config.h" - -#include "rtl/strbuf.hxx" -#include "rtl/string.hxx" -#include "rtl/ustrbuf.hxx" -#include "rtl/ustring.hxx" - -#include "tagtest.hxx" - -#if OSL_DEBUG_LEVEL > 1 -#include <stdio.h> -#endif - -#include "gsicheck.hxx" -#include "helper.hxx" - -#define HAS_FLAG( nFlags, nFlag ) ( ( nFlags & nFlag ) != 0 ) -#define SET_FLAG( nFlags, nFlag ) ( nFlags |= nFlag ) -#define RESET_FLAG( nFlags, nFlag ) ( nFlags &= ~nFlag ) // ~ = Bitweises NOT - - - -TokenInfo::TokenInfo( TokenId pnId, sal_Int32 nP, rtl::OUString const & paStr, ParserMessageList &rErrorList ) -: bClosed(sal_False) -, bCloseTag(sal_False) -, bIsBroken(sal_False) -, bHasBeenFixed(sal_False) -, bDone(sal_False) -, aTokenString( paStr ) -, nId( pnId ) -, nPos(nP) -{ - if ( nId == TAG_COMMONSTART || nId == TAG_COMMONEND ) - SplitTag( rErrorList ); -} - -enum tagcheck { TC_START, TC_HAS_TAG_NAME, TC_HAS_PROP_NAME_EQ, TC_HAS_PROP_NAME_EQ_SP, TC_HAS_PROP_NAME_SP, TC_INSIDE_STRING, TC_PROP_FINISHED, TC_CLOSED, TC_CLOSED_SPACE, TC_CLOSETAG, TC_CLOSETAG_HAS_TAG_NAME, TC_FINISHED, TC_ERROR }; - -/* - \< link href = \"text\" name = \"C\" \> -START ' ' -> HAS_TAG_NAME -START '/' -> CLOSED -START '/' -> CLOSETAG - no Portion (starting with /) -START '>' -> FINISHED -HAS_TAG_NAME '=' -> HAS_PROP_NAME_EQ -HAS_TAG_NAME ' ' -> HAS_PROP_NAME_SP -HAS_TAG_NAME '/' -> CLOSED -HAS_TAG_NAME '>' -> FINISHED -HAS_PROP_NAME_SP '=' -> HAS_PROP_NAME_EQ -HAS_PROP_NAME_EQ ' ' -> HAS_PROP_NAME_EQ_SP -HAS_PROP_NAME_EQ '"' -> INSIDE_STRING -HAS_PROP_NAME_EQ_SP '"' -> INSIDE_STRING -INSIDE_STRING ' ' -> INSIDE_STRING -INSIDE_STRING '=' -> INSIDE_STRING -INSIDE_STRING '>' -> INSIDE_STRING -INSIDE_STRING '"' -> PROP_FINISHED -PROP_FINISHED ' ' -> HAS_TAG_NAME -PROP_FINISHED '/' -> CLOSED -PROP_FINISHED '>' -> FINISHED -CLOSED ' ' -> CLOSED_SPACE -CLOSED '>' -> FINISHED -CLOSED_SPACE '>' -> FINISHED - -CLOSETAG ' ' -> CLOSETAG_HAS_TAG_NAME -CLOSETAG '>' -> FINISHED -CLOSETAG_HAS_TAG_NAME '>' -> FINISHED - -*/ -void TokenInfo::SplitTag( ParserMessageList &rErrorList ) -{ - sal_Int32 nLastPos = 2; // skip initial \< - sal_Int32 nCheckPos = nLastPos; - static char const aDelims[] = " \\=>/"; - rtl::OUString aPortion; - rtl::OUString aValue; // store the value of a property - rtl::OString aName; // store the name of a property/tag - sal_Bool bCheckName = sal_False; - sal_Bool bCheckEmpty = sal_False; - sal_Unicode cDelim; - tagcheck aState = TC_START; - - // skip blanks - while ( nLastPos < aTokenString.getLength() && aTokenString[nLastPos] == ' ') - nLastPos++; - - nCheckPos = helper::indexOfAnyAsciiL( - aTokenString, RTL_CONSTASCII_STRINGPARAM(aDelims), nLastPos); - while ( nCheckPos != -1 && !( aState == TC_FINISHED || aState == TC_ERROR ) ) - { - aPortion = aTokenString.copy( nLastPos, nCheckPos-nLastPos ); - - if ( aTokenString[nCheckPos] == '\\' ) - nCheckPos++; - - cDelim = aTokenString[nCheckPos]; - nCheckPos++; - - switch ( aState ) - { -// START ' ' -> HAS_TAG_NAME -// START '/' -> CLOSED -// START '>' -> FINISHED - case TC_START: - aTagName = aPortion; - switch ( cDelim ) - { - case ' ': aState = TC_HAS_TAG_NAME; - bCheckName = sal_True; - break; - case '/': - { - if (aPortion.isEmpty()) - { - aState = TC_CLOSETAG; - } - else - { - aState = TC_CLOSED; - bCheckName = sal_True; - } - } - break; - case '>': aState = TC_FINISHED; - bCheckName = sal_True; - break; - default: aState = TC_ERROR; - } - break; - -// HAS_TAG_NAME '=' -> HAS_PROP_NAME_EQ -// HAS_TAG_NAME ' ' -> HAS_PROP_NAME_SP -// HAS_TAG_NAME '/' -> CLOSED -// HAS_TAG_NAME '>' -> FINISHED - case TC_HAS_TAG_NAME: - switch ( cDelim ) - { - case '=': aState = TC_HAS_PROP_NAME_EQ; - bCheckName = sal_True; - break; - case ' ': aState = TC_HAS_PROP_NAME_SP; - bCheckName = sal_True; - break; - case '/': aState = TC_CLOSED; - bCheckEmpty = sal_True; - break; - case '>': aState = TC_FINISHED; - bCheckEmpty = sal_True; - break; - default: aState = TC_ERROR; - } - break; - -// HAS_PROP_NAME_SP '=' -> HAS_PROP_NAME_EQ - case TC_HAS_PROP_NAME_SP: - switch ( cDelim ) - { - case '=': aState = TC_HAS_PROP_NAME_EQ; - bCheckEmpty = sal_True; - break; - default: aState = TC_ERROR; - } - break; - -// HAS_PROP_NAME_EQ ' ' -> HAS_PROP_NAME_EQ_SP -// HAS_PROP_NAME_EQ '"' -> INSIDE_STRING - case TC_HAS_PROP_NAME_EQ: - switch ( cDelim ) - { - case ' ': aState = TC_HAS_PROP_NAME_EQ_SP; - bCheckEmpty = sal_True; - break; - case '\"': aState = TC_INSIDE_STRING; - bCheckEmpty = sal_True; - aValue = rtl::OUString(); - break; - default: aState = TC_ERROR; - } - break; - -// HAS_PROP_NAME_EQ_SP '"' -> INSIDE_STRING - case TC_HAS_PROP_NAME_EQ_SP: - switch ( cDelim ) - { - case '\"': aState = TC_INSIDE_STRING; - bCheckEmpty = sal_True; - aValue = rtl::OUString(); - break; - default: aState = TC_ERROR; - } - break; - -// INSIDE_STRING * -> INSIDE_STRING -// INSIDE_STRING '"' -> PROP_FINISHED - case TC_INSIDE_STRING: - switch ( cDelim ) - { - case '\"': - { - aState = TC_PROP_FINISHED; - aValue += aPortion; - if ( aProperties.find( aName ) == aProperties.end() ) - { - if ( !IsPropertyValueValid( aName, aValue ) ) - { - rErrorList.AddError( 25, rtl::OStringBuffer(RTL_CONSTASCII_STRINGPARAM("Property '")).append(aName).append(RTL_CONSTASCII_STRINGPARAM("' has invalid value '")).append(rtl::OUStringToOString(aValue, RTL_TEXTENCODING_UTF8)).append("' ").makeStringAndClear(), *this ); - bIsBroken = sal_True; - } - aProperties[ aName ] = aValue; - } - else - { - rErrorList.AddError( 25, rtl::OStringBuffer(RTL_CONSTASCII_STRINGPARAM("Property '")).append(aName).append(RTL_CONSTASCII_STRINGPARAM("' defined twice ")).makeStringAndClear(), *this ); - bIsBroken = sal_True; - } - } - break; - default: - { - aState = TC_INSIDE_STRING; - aValue += aPortion; - aValue += rtl::OUString(cDelim); - } - } - break; - -// PROP_FINISHED ' ' -> HAS_TAG_NAME -// PROP_FINISHED '/' -> CLOSED -// PROP_FINISHED '>' -> FINISHED - case TC_PROP_FINISHED: - switch ( cDelim ) - { - case ' ': aState = TC_HAS_TAG_NAME; - bCheckEmpty = sal_True; - break; - case '/': aState = TC_CLOSED; - bCheckEmpty = sal_True; - break; - case '>': aState = TC_FINISHED; - bCheckEmpty = sal_True; - break; - default: aState = TC_ERROR; - } - break; - -// CLOSED ' ' -> CLOSED_SPACE -// CLOSED '>' -> FINISHED - case TC_CLOSED: - switch ( cDelim ) - { - case ' ': aState = TC_CLOSED_SPACE; - bCheckEmpty = sal_True; - bClosed = sal_True; - break; - case '>': aState = TC_FINISHED; - bCheckEmpty = sal_True; - break; - default: aState = TC_ERROR; - } - break; - -// CLOSED_SPACE '>' -> FINISHED - case TC_CLOSED_SPACE: - switch ( cDelim ) - { - case '>': aState = TC_FINISHED; - bCheckEmpty = sal_True; - break; - default: aState = TC_ERROR; - } - break; - -// CLOSETAG ' ' -> CLOSETAG_HAS_TAG_NAME -// CLOSETAG '>' -> FINISHED - case TC_CLOSETAG: - bCloseTag = sal_True; - switch ( cDelim ) - { - case ' ': aState = TC_CLOSETAG_HAS_TAG_NAME; - aTagName = aPortion; - bCheckName = sal_True; - break; - case '>': aState = TC_FINISHED; - aTagName = aPortion; - bCheckName = sal_True; - break; - default: aState = TC_ERROR; - } - break; - -// CLOSETAG_HAS_TAG_NAME '>' -> FINISHED - case TC_CLOSETAG_HAS_TAG_NAME: - switch ( cDelim ) - { - case '>': aState = TC_FINISHED; - bCheckEmpty = sal_True; - break; - default: aState = TC_ERROR; - } - break; - - - default: rErrorList.AddError( 99, "Internal error Parsing Tag ", *this ); - bIsBroken = sal_True; - - } - - if ( bCheckName ) - { - if (aPortion.isEmpty()) - { - rErrorList.AddError( 25, "Tag/Property name missing ", *this ); - bIsBroken = sal_True; - } - else - { - aName = rtl::OUStringToOString(aPortion, RTL_TEXTENCODING_UTF8); - // "a-zA-Z_-.0-9" - sal_Bool bBroken = sal_False; - const sal_Char* aBuf = aName.getStr(); - for (sal_Int32 nCount = 0 ; !bBroken && nCount < aName.getLength() ; ++nCount) - { - bBroken = ! ( ( aBuf[nCount] >= 'a' && aBuf[nCount] <= 'z' ) - ||( aBuf[nCount] >= 'A' && aBuf[nCount] <= 'Z' ) - ||( aBuf[nCount] >= '0' && aBuf[nCount] <= '9' ) - ||( aBuf[nCount] == '_' ) - ||( aBuf[nCount] == '-' ) - ||( aBuf[nCount] == '.' ) - ); - } - - if ( bBroken ) - { - rErrorList.AddError( 25, "Found illegal character in Tag/Property name ", *this ); - bIsBroken = sal_True; - } - } - - bCheckName = sal_False; - } - - if ( bCheckEmpty ) - { - if (!aPortion.isEmpty()) - { - rErrorList.AddError( 25, rtl::OStringBuffer(RTL_CONSTASCII_STRINGPARAM("Found displaced characters '")).append(rtl::OUStringToOString(aPortion, RTL_TEXTENCODING_UTF8)).append(RTL_CONSTASCII_STRINGPARAM("' in Tag ")).makeStringAndClear(), *this ); - bIsBroken = sal_True; - } - bCheckEmpty = sal_False; - } - - - nLastPos = nCheckPos; - - // skip further blanks - if ( cDelim == ' ' && aState != TC_INSIDE_STRING ) - while ( nLastPos < aTokenString.getLength() && aTokenString[nLastPos] == ' ') - nLastPos++; - - nCheckPos = helper::indexOfAnyAsciiL( - aTokenString, RTL_CONSTASCII_STRINGPARAM(aDelims), nLastPos); - } - if ( aState != TC_FINISHED ) - { - rErrorList.AddError( 25, "Parsing error in Tag ", *this ); - bIsBroken = sal_True; - } -} - -sal_Bool TokenInfo::IsPropertyRelevant( const rtl::OString &rName, const rtl::OUString &rValue ) const -{ - if ( aTagName == "alt" && rName.equalsL(RTL_CONSTASCII_STRINGPARAM("xml-lang")) ) - return sal_False; - if ( aTagName == "ahelp" && rName.equalsL(RTL_CONSTASCII_STRINGPARAM("visibility")) && rValue == "visible" ) - return sal_False; - if ( aTagName == "image" && (rName.equalsL(RTL_CONSTASCII_STRINGPARAM("width")) || rName.equalsL(RTL_CONSTASCII_STRINGPARAM("height"))) ) - return sal_False; - - return sal_True; -} - -sal_Bool TokenInfo::IsPropertyValueValid( const rtl::OString &rName, const rtl::OUString &rValue ) const -{ -/* removed due to i56740 - if ( aTagName.EqualsAscii( "switchinline" ) && rName.equalsL(RTL_CONSTASCII_STRINGPARAM("select")) ) - { - return rValue.EqualsAscii("sys") || - rValue.EqualsAscii("appl") || - rValue.EqualsAscii("distrib"); - } */ - if ( aTagName == "caseinline" && rName.equalsL(RTL_CONSTASCII_STRINGPARAM("select")) ) - { - return !rValue.isEmpty(); - } - - // we don't know any better so we assume it to be OK - return sal_True; -} - -sal_Bool TokenInfo::IsPropertyInvariant( const rtl::OString &rName, const rtl::OUString &rValue ) const -{ - if ( aTagName == "link" && rName.equalsL(RTL_CONSTASCII_STRINGPARAM("name")) ) - return sal_False; - if ( aTagName == "link" && rName.equalsL(RTL_CONSTASCII_STRINGPARAM("href")) ) - { // check for external reference - return - !(rValue.matchIgnoreAsciiCaseAsciiL( - RTL_CONSTASCII_STRINGPARAM("http:")) - || rValue.matchIgnoreAsciiCaseAsciiL( - RTL_CONSTASCII_STRINGPARAM("https:")) - || rValue.matchIgnoreAsciiCaseAsciiL( - RTL_CONSTASCII_STRINGPARAM("ftp:"))); - } - return sal_True; -} - -sal_Bool TokenInfo::IsPropertyFixable( const rtl::OString &rName ) const -{ - // name everything that is allowed to be fixed automatically here - if ( (aTagName == "ahelp" && rName.equalsL(RTL_CONSTASCII_STRINGPARAM("hid"))) - || (aTagName == "link" && rName.equalsL(RTL_CONSTASCII_STRINGPARAM("href"))) - || (aTagName == "alt" && rName.equalsL(RTL_CONSTASCII_STRINGPARAM("id"))) - || (aTagName == "variable" && rName.equalsL(RTL_CONSTASCII_STRINGPARAM("id"))) - || (aTagName == "image" && rName.equalsL(RTL_CONSTASCII_STRINGPARAM("src"))) - || (aTagName == "image" && rName.equalsL(RTL_CONSTASCII_STRINGPARAM("id")) )) - return sal_True; - return sal_False; -} - -sal_Bool TokenInfo::MatchesTranslation( TokenInfo& rInfo, sal_Bool bGenErrors, ParserMessageList &rErrorList, sal_Bool bFixTags ) const -{ - // check if tags are equal - // check if all existing properties are in the translation as well and - // whether they have a matching content (the same in most cases) - - if ( nId != rInfo.nId ) - return sal_False; - - if ( aTagName != rInfo.aTagName ) - return sal_False; - - // If one of the tags has formating errors already it does make no sense to check here, so return right away - if ( bGenErrors && ( bIsBroken || rInfo.bIsBroken ) ) - return sal_True; - - StringHashMap::const_iterator iProp; - for( iProp = aProperties.begin() ; iProp != aProperties.end(); ++iProp ) - { - if ( rInfo.aProperties.find( iProp->first ) != rInfo.aProperties.end() ) - { - if ( IsPropertyRelevant( iProp->first, iProp->second ) || IsPropertyRelevant( iProp->first, rInfo.aProperties.find( iProp->first )->second ) ) - { - if ( IsPropertyInvariant( iProp->first, iProp->second ) ) - { - if ( rInfo.aProperties.find( iProp->first )->second != iProp->second ) - { - if ( bGenErrors ) - { - if ( bFixTags && IsPropertyFixable( iProp->first ) ) - { - rInfo.aProperties.find( iProp->first )->second = iProp->second; - rInfo.SetHasBeenFixed(); - rErrorList.AddWarning( 25, rtl::OStringBuffer(RTL_CONSTASCII_STRINGPARAM("Property '")).append(iProp->first).append(RTL_CONSTASCII_STRINGPARAM("': FIXED different value in Translation ")).makeStringAndClear(), *this ); - } - else - rErrorList.AddError( 25, rtl::OStringBuffer(RTL_CONSTASCII_STRINGPARAM("Property '")).append(iProp->first).append(RTL_CONSTASCII_STRINGPARAM("': value different in Translation ")).makeStringAndClear(), *this ); - } - else return sal_False; - } - } - } - } - else - { - if ( IsPropertyRelevant( iProp->first, iProp->second ) ) - { - if ( bGenErrors ) - rErrorList.AddError( 25, rtl::OStringBuffer(RTL_CONSTASCII_STRINGPARAM("Property '")).append(iProp->first).append(RTL_CONSTASCII_STRINGPARAM("' missing in Translation ")).makeStringAndClear(), *this ); - else return sal_False; - } - } - } - for( iProp = rInfo.aProperties.begin() ; iProp != rInfo.aProperties.end(); ++iProp ) - { - if ( aProperties.find( iProp->first ) == aProperties.end() ) - { - if ( IsPropertyRelevant( iProp->first, iProp->second ) ) - { - if ( bGenErrors ) - rErrorList.AddError( 25, rtl::OStringBuffer(RTL_CONSTASCII_STRINGPARAM("Extra Property '")).append(iProp->first).append(RTL_CONSTASCII_STRINGPARAM("' in Translation ")).makeStringAndClear(), rInfo ); - else return sal_False; - } - } - } - - // if we reach here eather - // the tags match completely or - // the tags match but not the properties and we generated errors for that - return sal_True; -} - -rtl::OUString TokenInfo::GetTagName() const -{ - return aTagName; -} - -rtl::OUString TokenInfo::MakeTag() const -{ - rtl::OUStringBuffer aRet; - aRet.appendAscii("\\<"); - if ( bCloseTag ) - aRet.appendAscii("/"); - aRet.append( GetTagName() ); - StringHashMap::const_iterator iProp; - - for( iProp = aProperties.begin() ; iProp != aProperties.end(); ++iProp ) - { - aRet.appendAscii(" "); - aRet.append( rtl::OStringToOUString( iProp->first, RTL_TEXTENCODING_UTF8 ) ); - aRet.appendAscii("=\\\""); - aRet.append( iProp->second ); - aRet.appendAscii("\\\""); - } - if ( bClosed ) - aRet.appendAscii("/"); - aRet.appendAscii("\\>"); - return aRet.makeStringAndClear(); -} - - -void ParserMessageList::AddError( sal_Int32 nErrorNr, const rtl::OString& rErrorText, const TokenInfo &rTag ) -{ - maList.push_back( new ParserError( nErrorNr, rErrorText, rTag ) ); -} - -void ParserMessageList::AddWarning( sal_Int32 nErrorNr, const rtl::OString& rErrorText, const TokenInfo &rTag ) -{ - maList.push_back( new ParserWarning( nErrorNr, rErrorText, rTag ) ); -} - -sal_Bool ParserMessageList::HasErrors() -{ - for ( size_t i = 0, n = maList.size(); i < n; ++i ) - if ( maList[ i ]->IsError() ) - return sal_True; - return sal_False; -} - -void ParserMessageList::clear() -{ - for ( size_t i = 0, n = maList.size(); i < n; ++i ) - delete maList[ i ]; - maList.clear(); -} - -struct Tag -{ - rtl::OUString GetName() const { return rtl::OUString::createFromAscii( pName ); }; - const char* pName; - TokenId nTag; -}; - - -static const Tag aKnownTags[] = -{ -/* commenting oldstyle tags -// { "<#GROUP_FORMAT>", TAG_GROUP_FORMAT }, - { "<#BOLD>", TAG_BOLDON }, - { "<#/BOLD>", TAG_BOLDOFF }, - { "<#ITALIC>", TAG_ITALICON }, - { "<#/ITALIC>", TAG_ITALICOFF }, - { "<#UNDER>", TAG_UNDERLINEON }, - { "<#/UNDER>", TAG_UNDERLINEOFF }, - -// { "<#GROUP_NOTALLOWED>", TAG_GROUP_NOTALLOWED }, - { "<#HELPID>", TAG_HELPID }, - { "<#MODIFY>", TAG_MODIFY }, - { "<#REFNR>", TAG_REFNR }, - -// { "<#GROUP_STRUCTURE>", TAG_GROUP_STRUCTURE }, - { "<#NAME>", TAG_NAME }, - { "<#HREF>", TAG_HREF }, - { "<#AVIS>", TAG_AVIS }, - { "<#AHID>", TAG_AHID }, - { "<#AEND>", TAG_AEND }, - - { "<#TITEL>", TAG_TITEL }, - { "<#KEY>", TAG_KEY }, - { "<#INDEX>", TAG_INDEX }, - - { "<#REFSTART>", TAG_REFSTART }, - - { "<#GRAPHIC>", TAG_GRAPHIC }, - { "<#NEXTVERSION>", TAG_NEXTVERSION }, - - // { "<#GROUP_SYSSWITCH>", TAG_GROUP_SYSSWITCH }, - { "<#WIN>", TAG_WIN }, - { "<#UNIX>", TAG_UNIX }, - { "<#MAC>", TAG_MAC }, - { "<#OS2>", TAG_OS2 }, - -// { "<#GROUP_PROGSWITCH>", TAG_GROUP_PROGSWITCH }, - { "<#WRITER>", TAG_WRITER }, - { "<#CALC>", TAG_CALC }, - { "<#DRAW>", TAG_DRAW }, - { "<#IMPRESS>", TAG_IMPRESS }, - { "<#SCHEDULE>", TAG_SCHEDULE }, - { "<#IMAGE>", TAG_IMAGE }, - { "<#MATH>", TAG_MATH }, - { "<#CHART>", TAG_CHART }, - { "<#OFFICE>", TAG_OFFICE }, - */ -// { "<#TAG_GROUP_META>", TAG_GROUP_META }, - { "$[officefullname]", TAG_OFFICEFULLNAME }, - { "$[officename]", TAG_OFFICENAME }, - { "$[officepath]", TAG_OFFICEPATH }, - { "$[officeversion]", TAG_OFFICEVERSION }, - { "$[portalname]", TAG_PORTALNAME }, - { "$[portalfullname]", TAG_PORTALFULLNAME }, - { "$[portalpath]", TAG_PORTALPATH }, - { "$[portalversion]", TAG_PORTALVERSION }, - { "$[portalshortname]", TAG_PORTALSHORTNAME }, -/* commenting oldstyle tags -// { "<#TAG_GROUP_SINGLE>", TAG_GROUP_SINGLE }, - { "<#REFINSERT>", TAG_REFINSERT }, - -// { "<#GROUP_MULTI>", TAG_GROUP_MULTI }, - { "<#END>", TAG_END }, - { "<#ELSE>", TAG_ELSE }, - { "<#VERSIONEND>", TAG_VERSIONEND }, - { "<#ENDGRAPHIC>", TAG_ENDGRAPHIC },*/ - { "<Common Tag>", TAG_COMMONSTART }, - { "</Common Tag>", TAG_COMMONEND }, - - { "<no more tags>", TAG_NOMORETAGS }, - { "", TAG_UNKNOWN_TAG }, -}; - - -SimpleParser::SimpleParser() -: nPos( 0 ) -, aNextTag( TAG_NOMORETAGS, TOK_INVALIDPOS ) -{ -} - -void SimpleParser::Parse( rtl::OUString const & PaSource ) -{ - aSource = PaSource; - nPos = 0; - aLastToken = rtl::OUString(); - aNextTag = TokenInfo( TAG_NOMORETAGS, TOK_INVALIDPOS ); - aTokenList.clear(); -}; - -TokenInfo SimpleParser::GetNextToken( ParserMessageList &rErrorList ) -{ - TokenInfo aResult; - sal_Int32 nTokenStartPos = 0; - if ( aNextTag.nId != TAG_NOMORETAGS ) - { - aResult = aNextTag; - aNextTag = TokenInfo( TAG_NOMORETAGS, TOK_INVALIDPOS ); - } - else - { - aLastToken = GetNextTokenString( rErrorList, nTokenStartPos ); - if ( aLastToken.isEmpty() ) - return TokenInfo( TAG_NOMORETAGS, TOK_INVALIDPOS ); - - // do we have a \< ... \> style tag? - if (aLastToken.matchAsciiL(RTL_CONSTASCII_STRINGPARAM("\\<"))) - { - // check for paired \" \" - bool bEven = true; - sal_Int32 nQuotePos = 0; - sal_Int32 nQuotedQuotesPos = - aLastToken.indexOfAsciiL(RTL_CONSTASCII_STRINGPARAM("\\\"")); - sal_Int32 nQuotedBackPos = aLastToken.indexOfAsciiL( - RTL_CONSTASCII_STRINGPARAM("\\\\")); - // this is only to kick out quoted backslashes - while (nQuotedQuotesPos != -1) - { - if ( nQuotedBackPos != -1 && nQuotedBackPos <= nQuotedQuotesPos ) - nQuotePos = nQuotedBackPos+2; - else - { - nQuotePos = nQuotedQuotesPos+2; - bEven = !bEven; - } - nQuotedQuotesPos = aLastToken.indexOfAsciiL( - RTL_CONSTASCII_STRINGPARAM("\\\""), nQuotePos); - nQuotedBackPos = aLastToken.indexOfAsciiL( - RTL_CONSTASCII_STRINGPARAM("\\\\"), nQuotePos); - // this is only to kick out quoted backslashes - } - if ( !bEven ) - { - rErrorList.AddError( 24, "Missing quotes ( \\\" ) in Tag", TokenInfo( TAG_UNKNOWN_TAG, nTokenStartPos, aLastToken ) ); - } - - // check if we have an end-tag or a start-tag - sal_Int32 nNonBlankStartPos = 2; - while (aLastToken[nNonBlankStartPos] == ' ') - nNonBlankStartPos++; - if (aLastToken[nNonBlankStartPos] == '/') - aResult = TokenInfo( TAG_COMMONEND, nTokenStartPos, aLastToken, rErrorList ); - else - { - aResult = TokenInfo( TAG_COMMONSTART, nTokenStartPos, aLastToken, rErrorList ); - sal_Int32 nNonBlankEndPos = aLastToken.getLength() - 3; - while (aLastToken[nNonBlankEndPos] == ' ') - nNonBlankEndPos--; - if (aLastToken[nNonBlankEndPos] == '/') - aNextTag = TokenInfo( TAG_COMMONEND, nTokenStartPos, rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("\\</")) + aResult.GetTagName() + rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("\\>")), rErrorList ); - } - } - else - { - sal_Int32 i = 0; - while ( aKnownTags[i].nTag != TAG_UNKNOWN_TAG && - aLastToken != aKnownTags[i].GetName() ) - i++; - aResult = TokenInfo( aKnownTags[i].nTag, nTokenStartPos ); - } - } - - if ( aResult.nId == TAG_UNKNOWN_TAG ) - aResult = TokenInfo( TAG_UNKNOWN_TAG, nTokenStartPos, aLastToken ); - aTokenList.insert( aResult ); - return aResult; -} - -rtl::OUString SimpleParser::GetNextTokenString( ParserMessageList &rErrorList, sal_Int32 &rTagStartPos ) -{ - sal_Int32 nStyle2StartPos = aSource.indexOfAsciiL( - RTL_CONSTASCII_STRINGPARAM("$["), nPos ); - sal_Int32 nStyle3StartPos = aSource.indexOfAsciiL( - RTL_CONSTASCII_STRINGPARAM("\\<"), nPos); - sal_Int32 nStyle4StartPos = aSource.indexOfAsciiL( - RTL_CONSTASCII_STRINGPARAM("\\\\"), nPos); - // this is only to kick out quoted backslashes - - rTagStartPos = 0; - - if (nStyle2StartPos == -1 && nStyle3StartPos == -1) - return rtl::OUString(); // no more tokens - - if ( nStyle4StartPos != -1 - && (nStyle2StartPos == -1 || nStyle4StartPos < nStyle2StartPos) - && (nStyle3StartPos == -1 || nStyle4StartPos < nStyle3StartPos ) ) - // to make sure \\ is always handled first - { // Skip quoted Backslash - nPos = nStyle4StartPos +2; - return GetNextTokenString( rErrorList, rTagStartPos ); - } - - if ( nStyle2StartPos != -1 && ( nStyle3StartPos == -1 || nStyle2StartPos < nStyle3StartPos ) ) - { // test for $[ ... ] style tokens - sal_Int32 nEndPos = aSource.indexOf(']', nStyle2StartPos); - if (nEndPos == -1) - { // Token is incomplete. Skip start and search for better ones - nPos = nStyle2StartPos +2; - return GetNextTokenString( rErrorList, rTagStartPos ); - } - nPos = nEndPos; - rTagStartPos = nStyle2StartPos; - return aSource.copy(nStyle2StartPos, nEndPos - nStyle2StartPos + 1); - } - else - { // test for \< ... \> style tokens - sal_Int32 nEndPos = aSource.indexOfAsciiL( - RTL_CONSTASCII_STRINGPARAM("\\>"), nStyle3StartPos); - sal_Int32 nQuotedBackPos = aSource.indexOfAsciiL( - RTL_CONSTASCII_STRINGPARAM("\\\\"), nStyle3StartPos); - // this is only to kick out quoted backslashes - while (nQuotedBackPos <= nEndPos && nQuotedBackPos != -1) - { - nEndPos = aSource.indexOfAsciiL( - RTL_CONSTASCII_STRINGPARAM("\\>"), nQuotedBackPos + 2); - nQuotedBackPos = aSource.indexOfAsciiL( - RTL_CONSTASCII_STRINGPARAM("\\\\"), nQuotedBackPos + 2); - // this is only to kick out quoted backslashes - } - if (nEndPos == -1) - { // Token is incomplete. Skip start and search for better ones - nPos = nStyle3StartPos +2; - rErrorList.AddError( 24, "Tag Start '\\<' without Tag End '\\>'", TokenInfo( TAG_UNKNOWN_TAG, nStyle3StartPos, helper::abbreviate(aSource, nStyle3StartPos - 10, 20) ) ); - return GetNextTokenString( rErrorList, rTagStartPos ); - } - // check for paired quoted " --> \"sometext\" - - nPos = nEndPos; - rTagStartPos = nStyle3StartPos; - return aSource.copy(nStyle3StartPos, nEndPos-nStyle3StartPos + 2); - } -} - -rtl::OUString SimpleParser::GetLexem( TokenInfo const &aToken ) -{ - if ( !aToken.aTokenString.isEmpty() ) - return aToken.aTokenString; - else - { - sal_Int32 i = 0; - while ( aKnownTags[i].nTag != TAG_UNKNOWN_TAG && - aKnownTags[i].nTag != aToken.nId ) - i++; - - return aKnownTags[i].GetName(); - } -} - -TokenParser::TokenParser() -: pErrorList( NULL ) -{} - -void TokenParser::Parse( const rtl::OUString &aCode, ParserMessageList* pList ) -{ - pErrorList = pList; - - //Scanner initialisieren - aParser.Parse( aCode ); - - //erstes Symbol holen - aTag = aParser.GetNextToken( *pErrorList ); - - nPfCaseOptions = 0; - nAppCaseOptions = 0; - bPfCaseActive = sal_False; - bAppCaseActive = sal_False; - - nActiveRefTypes = 0; - - //Ausfuehren der Start-Produktion - Paragraph(); - - //Es wurde nicht die ganze Kette abgearbeitet, bisher ist aber - //kein Fehler aufgetreten - //=> es wurde ein einleitendes Tag vergessen - if ( aTag.nId != TAG_NOMORETAGS ) - { - switch ( aTag.nId ) - { - case TAG_END: - { - ParseError( 3, "Extra Tag <#END>. Switch or <#HREF> expected.", aTag ); - } - break; - case TAG_BOLDOFF: - { - ParseError( 4, "<#BOLD> expected before <#/BOLD>.", aTag ); - } - break; - case TAG_ITALICOFF: - { - ParseError( 5, "<#ITALIC> expected before <#/ITALIC>.", aTag ); - } - break; - case TAG_UNDERLINEOFF: - { - ParseError( 17, "<#UNDER> expected before <#/UNDER>.", aTag ); - } - break; - case TAG_AEND: - { - ParseError( 5, "Extra Tag <#AEND>. <#AVIS> or <#AHID> expected.", aTag ); - } - break; - case TAG_ELSE: - { - ParseError( 16, "Application-tag or platform-tag expected before <#ELSE>.", aTag ); - } - break; - case TAG_UNKNOWN_TAG: - { - ParseError( 6, "unknown Tag", aTag ); - } - break; - default: - { - ParseError( 6, "unexpected Tag", aTag ); - } - } - } - pErrorList = NULL; -} - -void TokenParser::Paragraph() -{ - switch ( aTag.nId ) - { - case TAG_GRAPHIC: - case TAG_NEXTVERSION: - { - TagRef(); - Paragraph(); - } - break; - case TAG_AVIS: - case TAG_AHID: - { - TagRef(); - Paragraph(); - } - break; - case TAG_HELPID: - { - SimpleTag(); - Paragraph(); - } - break; - case TAG_OFFICEFULLNAME: - case TAG_OFFICENAME: - case TAG_OFFICEPATH: - case TAG_OFFICEVERSION: - case TAG_PORTALNAME: - case TAG_PORTALFULLNAME: - case TAG_PORTALPATH: - case TAG_PORTALVERSION: - case TAG_PORTALSHORTNAME: - { - SimpleTag(); - Paragraph(); - } - break; - case TAG_REFINSERT: - { - SimpleTag(); - Paragraph(); - } - break; - case TAG_BOLDON: - case TAG_ITALICON: - case TAG_UNDERLINEON: - case TAG_COMMONSTART: - { - TagPair(); - Paragraph(); - } - break; - case TAG_HREF: - case TAG_NAME: - case TAG_KEY: - case TAG_INDEX: - case TAG_TITEL: - case TAG_REFSTART: - { - TagRef(); - Paragraph(); - } - break; - case TAG_WIN: - case TAG_UNIX: - case TAG_MAC: //... - { - if ( ! bPfCaseActive ) - { - //PfCases duerfen nicht verschachtelt sein: - bPfCaseActive = sal_True; - PfCase(); - - //So jetzt kann wieder ein PfCase kommen: - bPfCaseActive = sal_False; - Paragraph(); - } - } - break; - case TAG_WRITER: - case TAG_CALC: - case TAG_DRAW: - case TAG_IMPRESS: - case TAG_SCHEDULE: - case TAG_IMAGE: - case TAG_MATH: - case TAG_CHART: - case TAG_OFFICE: - { - if ( !bAppCaseActive ) - { - //AppCases duerfen nicht verschachtelt sein: - bAppCaseActive = sal_True; - AppCase(); - - //jetzt koennen wieder AppCases kommen: - bAppCaseActive = sal_False; - Paragraph(); - } - } - break; - - //Case TAG_BOLDOFF, TAG_ITALICOFF, TAG_BUNDERLINE, TAG_END - //nichts tun wg. epsilon-Prod. - } -} - -void TokenParser::PfCase() -{ - - //Produktion: - //PfCase -> PfCaseBegin Paragraph (PfCase | PfCaseEnd) - - PfCaseBegin(); - - //Jetzt ist eine PfCase-Produktion aktiv: - Paragraph(); - switch ( aTag.nId ) - { - case TAG_ELSE: - case TAG_END: - { - CaseEnd(); - } - break; - case TAG_WIN: - case TAG_UNIX: - case TAG_MAC: //First (PfBegin) - { - PfCase(); - } - break; - default: - ParseError( 8, "<#ELSE> or <#END> or platform-tag expected.", aTag ); - } - //Die gemerkten Tags wieder loeschen fuer naechstes PfCase: - nPfCaseOptions = 0; -} - -void TokenParser::PfCaseBegin() -{ - switch ( aTag.nId ) - { - case TAG_WIN: - case TAG_UNIX: - case TAG_MAC: - { - //Token darf noch nicht vorgekommen sein im - //aktuellen Plattform-Case: - if ( !HAS_FLAG( nPfCaseOptions, TAG_NOGROUP( aTag.nId ) ) ) - { - SET_FLAG( nPfCaseOptions, TAG_NOGROUP( aTag.nId ) ); - match( aTag, aTag ); - } - else { - ParseError( 9, "Tag defined twice in the same platform-case", aTag ); - } - } - } -} - -void TokenParser::AppCase() -{ - - //Produktion: - //AppCase -> AppCaseBegin Paragraph (AppCase | AppCaseEnd) - - - AppCaseBegin(); - - Paragraph(); - - switch ( aTag.nId ) - { - case TAG_ELSE: - case TAG_END: - { - CaseEnd(); - } - break; - case TAG_WRITER: - case TAG_DRAW: - case TAG_CALC: - case TAG_IMAGE: - case TAG_MATH: - case TAG_CHART: - case TAG_OFFICE: - case TAG_IMPRESS: - case TAG_SCHEDULE: //First (AppBegin) - { - AppCase(); - } - break; - default: - ParseError( 1, "<#ELSE> or <#END> or application-case-tag expected.", aTag ); - } - - //Die gemerkten Tags wieder loeschen fuer naechstes AppCase: - nAppCaseOptions = 0; -} - -void TokenParser::AppCaseBegin() -{ - switch ( aTag.nId ) - { - case TAG_WRITER: - case TAG_DRAW: - case TAG_CALC: - case TAG_IMAGE: - case TAG_MATH: - case TAG_CHART: - case TAG_OFFICE: - case TAG_IMPRESS: - case TAG_SCHEDULE: - { - //Token darf noch nicht vorgekommen sein im - //aktuellen Plattform-Case: - if ( !HAS_FLAG( nAppCaseOptions, TAG_NOGROUP( aTag.nId ) ) ) - { - SET_FLAG( nAppCaseOptions, TAG_NOGROUP( aTag.nId ) ); - match( aTag, aTag ); - } - else { - ParseError( 13, "Tag defined twice in the same application-case.", aTag ); - } - } - } -} - -void TokenParser::CaseEnd() -{ - //Produktion: - //CaseEnd -> <#ELSE> Paragraph <#END> | <#END> - - switch ( aTag.nId ) - { - case TAG_ELSE: - { - match( aTag, TAG_ELSE ); - Paragraph(); - match( aTag, TAG_END ); - } - break; - case TAG_END: - { - match( aTag, TAG_END ); - } - break; - default: - ParseError( 2, "<#ELSE> or <#END> expected.", aTag ); - } -} - -void TokenParser::SimpleTag() -{ - - switch ( aTag.nId ) - { - case TAG_HELPID: - { - match( aTag, TAG_HELPID ); - } - break; - case TAG_OFFICEFULLNAME: - case TAG_OFFICENAME: - case TAG_OFFICEPATH: - case TAG_OFFICEVERSION: - case TAG_PORTALNAME: - case TAG_PORTALFULLNAME: - case TAG_PORTALPATH: - case TAG_PORTALVERSION: - case TAG_PORTALSHORTNAME: - - case TAG_REFINSERT: - { - match( aTag, aTag ); - } - break; - default: - ParseError( 15, "[<#SimpleTag>] expected.", aTag ); - } -} - -void TokenParser::TagPair() -{ - switch ( aTag.nId ) - { - case TAG_BOLDON: - { - match( aTag, TAG_BOLDON ); - Paragraph(); - match( aTag, TAG_BOLDOFF ); - } - break; - case TAG_ITALICON: - { - match( aTag, TAG_ITALICON ); - Paragraph(); - match( aTag, TAG_ITALICOFF ); - } - break; - case TAG_UNDERLINEON: - { - match( aTag, TAG_UNDERLINEON ); - Paragraph(); - match( aTag, TAG_UNDERLINEOFF ); - } - break; - case TAG_COMMONSTART: - { - //remember tag so we can give the original tag in case of an error - TokenInfo aEndTag( aTag ); - aEndTag.nId = TAG_COMMONEND; - match( aTag, TAG_COMMONSTART ); - Paragraph(); - match( aTag, aEndTag ); - } - break; - default: - ParseError( 10, "<#BOLD>, <#ITALIC>, <#UNDER> expected.", aTag ); - } -} - - -void TokenParser::TagRef() -{ - switch ( aTag.nId ) - { - case TAG_GRAPHIC: - case TAG_NEXTVERSION: - { - if ( !HAS_FLAG( nActiveRefTypes, TAG_NOGROUP( aTag.nId ) ) ) - { - TokenId aThisToken = aTag.nId; - SET_FLAG( nActiveRefTypes, TAG_NOGROUP( aThisToken ) ); - match( aTag, aTag ); - Paragraph(); - if ( aThisToken == TAG_GRAPHIC ) - match( aTag, TAG_ENDGRAPHIC ); - else - match( aTag, TAG_VERSIONEND ); - // don't reset since alowed only once per paragraph - // RESET_FLAG( nActiveRefTypes, TAG_NOGROUP( aThisToken ) ); - } - else - { - ParseError( 11, "Tags <#GRAPHIC>,<#NEXTVERSION> allowed only once per paragraph at", aTag ); - } - } - break; - case TAG_AVIS: - case TAG_AHID: - { - if ( !HAS_FLAG( nActiveRefTypes, TAG_NOGROUP( aTag.nId ) ) ) - { - TokenId aThisToken = aTag.nId; - SET_FLAG( nActiveRefTypes, TAG_NOGROUP( aThisToken ) ); - match( aTag, aTag ); - Paragraph(); - match( aTag, TAG_AEND ); - RESET_FLAG( nActiveRefTypes, TAG_NOGROUP( aThisToken ) ); - } - else - { - ParseError( 11, "Nested <#AHID>,<#AVIS> not allowed.", aTag ); - } - } - break; - case TAG_HREF: - case TAG_NAME: - { - - } - // NOBREAK - case TAG_KEY: - case TAG_INDEX: - case TAG_TITEL: - case TAG_REFSTART: - { - if ( !HAS_FLAG( nActiveRefTypes, TAG_NOGROUP( aTag.nId ) ) ) - { - TokenId aThisToken = aTag.nId; - match( aTag, aTag ); - if ( aThisToken != TAG_NAME ) - { // TAG_NAME has no TAG_END - SET_FLAG( nActiveRefTypes, TAG_NOGROUP( aThisToken ) ); - Paragraph(); - match( aTag, TAG_END ); - RESET_FLAG( nActiveRefTypes, TAG_NOGROUP( aThisToken ) ); - } - } - else - { - ParseError( 11, "Nested <#HREF>,<#NAME> or <#KEY> not allowed.", aTag ); - } - } - break; - default: - ParseError( 12, "<#HREF>,<#NAME> or <#KEY> expected.", aTag ); - } -} - -sal_Bool TokenParser::match( const TokenInfo &aCurrentToken, const TokenId &aExpectedToken ) -{ - return match( aCurrentToken, TokenInfo( aExpectedToken, TOK_INVALIDPOS ) ); -} - -sal_Bool TokenParser::match( const TokenInfo &aCurrentToken, const TokenInfo &rExpectedToken ) -{ - TokenInfo aExpectedToken( rExpectedToken ); - if ( aCurrentToken.nId == aExpectedToken.nId ) - { - if ( ( aCurrentToken.nId == TAG_COMMONEND - && aCurrentToken.GetTagName() == aExpectedToken.GetTagName() ) - || aCurrentToken.nId != TAG_COMMONEND ) - { - aTag = aParser.GetNextToken( *pErrorList ); - return sal_True; - } - } - - if ( aExpectedToken.nId == TAG_COMMONEND ) - { - aExpectedToken.aTokenString = - rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("Close tag for ")) - + aExpectedToken.aTokenString; - } - - rtl::OString sTmp(RTL_CONSTASCII_STRINGPARAM("Expected Symbol")); - if ( aCurrentToken.nId == TAG_NOMORETAGS ) - { - ParseError( 7, sTmp, aExpectedToken ); - } - else - { - rtl::OStringBuffer aBuf(sTmp); - aBuf.append(": "). - append(rtl::OUStringToOString(aParser.GetLexem( aExpectedToken ), RTL_TEXTENCODING_UTF8)). - append(RTL_CONSTASCII_STRINGPARAM(" near ")); - ParseError( 7, aBuf.makeStringAndClear(), aCurrentToken ); - } - return sal_False; -} - -void TokenParser::ParseError( sal_Int32 nErrNr, const rtl::OString &rErrMsg, const TokenInfo &rTag ) -{ - pErrorList->AddError( nErrNr, rErrMsg, rTag); - - // Das Fehlerhafte Tag ueberspringen - aTag = aParser.GetNextToken( *pErrorList ); -} - - -ParserMessage::ParserMessage( sal_Int32 PnErrorNr, const rtl::OString &rPaErrorText, const TokenInfo &rTag ) - : nErrorNr( PnErrorNr ) - , nTagBegin( 0 ) - , nTagLength( 0 ) -{ - rtl::OUString aLexem( SimpleParser::GetLexem( rTag ) ); - rtl::OStringBuffer aErrorBuffer(rPaErrorText); - aErrorBuffer.append(RTL_CONSTASCII_STRINGPARAM(": ")); - aErrorBuffer.append(rtl::OUStringToOString(aLexem, RTL_TEXTENCODING_UTF8)); - if ( rTag.nId == TAG_NOMORETAGS ) - aErrorBuffer.append(RTL_CONSTASCII_STRINGPARAM(" at end of line ")); - else if ( rTag.nPos != TOK_INVALIDPOS ) - { - aErrorBuffer.append(RTL_CONSTASCII_STRINGPARAM(" at Position ")); - aErrorBuffer.append(static_cast<sal_Int32>(rTag.nPos)); - } - aErrorText = aErrorBuffer.makeStringAndClear(); - nTagBegin = rTag.nPos; - nTagLength = aLexem.getLength(); -} - -ParserError::ParserError( sal_Int32 ErrorNr, const rtl::OString &rErrorText, const TokenInfo &rTag ) -: ParserMessage( ErrorNr, rErrorText, rTag ) -{} - -ParserWarning::ParserWarning( sal_Int32 ErrorNr, const rtl::OString &rErrorText, const TokenInfo &rTag ) -: ParserMessage( ErrorNr, rErrorText, rTag ) -{} - -sal_Bool LingTest::IsTagMandatory( TokenInfo const &aToken, TokenId &aMetaTokens ) -{ - TokenId aTokenId = aToken.nId; - TokenId aTokenGroup = TAG_GROUP( aTokenId ); - if ( TAG_GROUP_PROGSWITCH == aTokenGroup - || TAG_REFINSERT == aTokenId - || TAG_REFSTART == aTokenId - || TAG_NAME == aTokenId - || TAG_HREF == aTokenId - || TAG_AVIS == aTokenId - || TAG_AHID == aTokenId - || TAG_GRAPHIC == aTokenId - || TAG_NEXTVERSION == aTokenId - || ( TAG_GROUP_META == aTokenGroup && (aMetaTokens & aTokenId) == aTokenId ) ) - { - if ( TAG_GROUP_META == aTokenGroup ) - aMetaTokens |= aTokenId; - return sal_True; - } - else if ( TAG_COMMONSTART == aTokenId - || TAG_COMMONEND == aTokenId ) - { - rtl::OUString aTagName = aToken.GetTagName(); - return !(aTagName.equalsIgnoreAsciiCaseAsciiL(RTL_CONSTASCII_STRINGPARAM("comment")) - || aTagName.equalsIgnoreAsciiCaseAsciiL(RTL_CONSTASCII_STRINGPARAM("bookmark_value")) - || aTagName.equalsIgnoreAsciiCaseAsciiL(RTL_CONSTASCII_STRINGPARAM("emph")) - || aTagName.equalsIgnoreAsciiCaseAsciiL(RTL_CONSTASCII_STRINGPARAM("item")) - || aTagName.equalsIgnoreAsciiCaseAsciiL(RTL_CONSTASCII_STRINGPARAM("br")) ); - } - return sal_False; -} - -void LingTest::CheckTags( TokenList &aReference, TokenList &aTestee, sal_Bool bFixTags ) -{ - size_t i=0,j=0; - // Clean old Warnings - aCompareWarningList.clear(); - - /* in xml tags, do not require the following tags - comment - bookmark_value - emph - item - br - */ - - // filter uninteresting Tags - TokenId aMetaTokens = 0; - for ( i=0 ; i < aReference.size() ; i++ ) - { - if ( !IsTagMandatory( aReference[ i ], aMetaTokens ) ) - aReference[ i ].SetDone(); - } - - aMetaTokens = 0; - for ( i=0 ; i < aTestee.size() ; i++ ) - { - if ( !IsTagMandatory( aTestee[ i ], aMetaTokens ) ) - aTestee[ i ].SetDone(); - } - - // remove all matching tags - for ( i=0 ; i < aReference.size() ; i++ ) - { - if ( aReference[ i ].IsDone() ) - continue; - - sal_Bool bTagFound = sal_False; - for ( j=0 ; j < aTestee.size() && !bTagFound ; j++ ) - { - if ( aTestee[ j ].IsDone() ) - continue; - - if ( aReference[ i ].MatchesTranslation( aTestee[ j ], sal_False, aCompareWarningList ) ) - { - aReference[ i ].SetDone(); - aTestee[ j ].SetDone(); - bTagFound = sal_True; - } - } - } - - sal_Bool bCanFix = sal_True; - - if ( bFixTags ) - { - // we fix only if its a really simple case - sal_Int32 nTagCount = 0; - for ( i=0 ; i < aReference.size() ; i++ ) - if ( !aReference[ i ].IsDone() ) - nTagCount++; - if ( nTagCount > 1 ) - bCanFix = sal_False; - - nTagCount = 0; - for ( i=0 ; i < aTestee.size() ; i++ ) - if ( !aTestee[ i ].IsDone() ) - nTagCount++; - if ( nTagCount > 1 ) - bCanFix = sal_False; - } - - // generate errors for tags that have differing attributes - for ( i=0 ; i < aReference.size() ; i++ ) - { - if ( aReference[ i ].IsDone() ) - continue; - - sal_Bool bTagFound = sal_False; - for ( j=0 ; j < aTestee.size() && !bTagFound ; j++ ) - { - if ( aTestee[ j ].IsDone() ) - continue; - - if ( aReference[ i ].MatchesTranslation( aTestee[ j ], sal_True, aCompareWarningList, bCanFix && bFixTags ) ) - { - aReference[ i ].SetDone(); - aTestee[ j ].SetDone(); - bTagFound = sal_True; - } - } - } - - // list remaining tags as errors - for ( i=0 ; i < aReference.size() ; i++ ) - { - if ( aReference[ i ].IsDone() ) - continue; - - aCompareWarningList.AddError( 20, "Missing Tag in Translation", aReference[ i ] ); - } - for ( i=0 ; i < aTestee.size() ; i++ ) - { - if ( aTestee[ i ].IsDone() ) - continue; - - aCompareWarningList.AddError( 21, "Extra Tag in Translation", aTestee[ i ] ); - } - - for ( i=0 ; i < aReference.size() ; i++ ) - aReference[ i ].SetDone( sal_False ); - - for ( i=0 ; i < aTestee.size() ; i++ ) - aTestee[ i ].SetDone( sal_False ); -} - -void LingTest::CheckReference( GSILine *aReference ) -{ - aReferenceParser.Parse( aReference->GetUText(), aReference->GetMessageList() ); -} - -void LingTest::CheckTestee( GSILine *aTestee, sal_Bool bHasSourceLine, sal_Bool bFixTags ) -{ - aFixedTestee = aTestee->GetUText(); - aTesteeParser.Parse( aFixedTestee, aTestee->GetMessageList() ); - - if ( bHasSourceLine ) - CheckTags( aReferenceParser.GetTokenList(), aTesteeParser.GetTokenList(), bFixTags ); - - if ( bFixTags ) - { - TokenList& aTesteeTokens = aTesteeParser.GetTokenList(); - sal_Bool bFixesDone = sal_False; - // count backwards to allow replacing from right to left - int i; - for ( i = aTesteeTokens.size() ; i > 0 ; ) - { - if ( aTesteeTokens[ --i ].HasBeenFixed() ) - { - bFixesDone = sal_True; - aFixedTestee = aFixedTestee.replaceAt( aTesteeTokens[ i ].nPos, aTesteeTokens[ i ].aTokenString.getLength(), aTesteeTokens[ i ].MakeTag() ); - } - } - if ( bFixesDone ) - { - aTestee->SetUText( aFixedTestee ); - aTestee->SetFixed(); - } - } -} - -/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ |