diff -ur --exclude=CVS sc.clean/inc/compiler.hxx sc/inc/compiler.hxx
--- sc.clean/inc/compiler.hxx	2006-10-18 08:16:39.000000000 -0400
+++ sc/inc/compiler.hxx	2007-06-10 11:49:45.000000000 -0400
@@ -214,13 +214,6 @@
 
 struct ScArrayStack;
 
-struct ScStringHashCode
-{
-    size_t operator()( const String& rStr ) const
-	{
-        return rtl_ustr_hashCode_WithLength( rStr.GetBuffer(), rStr.Len() );
-	}
-};
 typedef ::std::hash_map< String, OpCode, ScStringHashCode, ::std::equal_to< String > > ScOpCodeHashMap;
 
 using namespace ::com::sun::star::i18n;
diff -ur --exclude=CVS sc.clean/inc/global.hxx sc/inc/global.hxx
--- sc.clean/inc/global.hxx	2006-08-04 08:11:05.000000000 -0400
+++ sc/inc/global.hxx	2007-06-10 11:49:45.000000000 -0400
@@ -481,6 +481,14 @@
 	void			Clear		();
 };
 
+struct ScStringHashCode
+{
+    size_t operator()( const String& rStr ) const
+    {
+        return rtl_ustr_hashCode_WithLength( rStr.GetBuffer(), rStr.Len() );
+    }
+};
+
 // -----------------------------------------------------------------------
 
 class ScDocument;
Only in sc: sc.vpj
Only in sc/source/core/inc: cellkeytranslator.hxx
Only in sc/source/core/tool: cellkeytranslator.cxx
diff -ur --exclude=CVS sc.clean/source/core/tool/interpr1.cxx sc/source/core/tool/interpr1.cxx
--- sc.clean/source/core/tool/interpr1.cxx	2006-10-18 08:22:33.000000000 -0400
+++ sc/source/core/tool/interpr1.cxx	2007-06-10 14:37:22.000000000 -0400
@@ -69,7 +69,7 @@
 #include "globstr.hrc"
 #include "attrib.hxx"
 #include "jumpmatrix.hxx"
-
+#include "cellkeytranslator.hxx"
 
 #define	SC_DOUBLE_MAXVALUE	1.7e307
 
@@ -1649,6 +1649,7 @@
 			ScBaseCell*		pCell = GetCell( aCellPos );
 
 			aInfoType.ToUpperAscii();
+            ScCellKeywordTranslator::transKeyword(aInfoType, ScGlobal::pLocale, ocCell);
 
 // *** ADDRESS INFO ***
 			if( aInfoType.EqualsAscii( "COL" ) )
diff -ur --exclude=CVS sc.clean/source/core/tool/interpr5.cxx sc/source/core/tool/interpr5.cxx
--- sc.clean/source/core/tool/interpr5.cxx	2006-07-21 07:37:12.000000000 -0400
+++ sc/source/core/tool/interpr5.cxx	2007-06-10 14:37:12.000000000 -0400
@@ -56,6 +56,7 @@
 #include "dociter.hxx"
 #include "scmatrix.hxx"
 #include "globstr.hrc"
+#include "cellkeytranslator.hxx"
 
 const double fInvEpsilon = 1.0E-7;
 
@@ -3968,6 +3969,7 @@
 	if( MustHaveParamCount( GetByte(), 1 ) )
 	{
         String aStr = String( GetString() ).ToUpperAscii();
+        ScCellKeywordTranslator::transKeyword(aStr, ScGlobal::pLocale, ocInfo);
         if( aStr.EqualsAscii( "SYSTEM" ) )
             PushString( String( RTL_CONSTASCII_USTRINGPARAM( SC_INFO_OSVERSION ) ) );
         else if( aStr.EqualsAscii( "OSVERSION" ) )
diff -ur --exclude=CVS sc.clean/source/core/tool/makefile.mk sc/source/core/tool/makefile.mk
--- sc.clean/source/core/tool/makefile.mk	2006-08-04 08:12:09.000000000 -0400
+++ sc/source/core/tool/makefile.mk	2007-06-10 11:49:45.000000000 -0400
@@ -67,6 +67,7 @@
 		$(SLO)$/autoform.obj \
 		$(SLO)$/callform.obj \
 		$(SLO)$/cellform.obj \
+		$(SLO)$/cellkeytranslator.obj \
 		$(SLO)$/chartarr.obj \
 		$(SLO)$/chartlis.obj \
 		$(SLO)$/chgtrack.obj \
Only in sc: unxlngi6.pro
--- /dev/null	2007-03-30 11:25:40.000000000 -0400
+++ sc/source/core/inc/cellkeytranslator.hxx	2007-06-10 14:36:57.000000000 -0400
@@ -0,0 +1,97 @@
+/*************************************************************************
+ *
+ *  OpenOffice.org - a multi-platform office productivity suite
+ *
+ *  $RCSfile: interpre.hxx,v $
+ *
+ *  $Revision: 1.27 $
+ *
+ *  last change: $Author: ihi $ $Date: 2006/12/19 13:16:55 $
+ *
+ *  The Contents of this file are made available subject to
+ *  the terms of GNU Lesser General Public License Version 2.1.
+ *
+ *
+ *    GNU Lesser General Public License Version 2.1
+ *    =============================================
+ *    Copyright 2005 by Sun Microsystems, Inc.
+ *    901 San Antonio Road, Palo Alto, CA 94303, USA
+ *
+ *    This library is free software; you can redistribute it and/or
+ *    modify it under the terms of the GNU Lesser General Public
+ *    License version 2.1, as published by the Free Software Foundation.
+ *
+ *    This library 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 for more details.
+ *
+ *    You should have received a copy of the GNU Lesser General Public
+ *    License along with this library; if not, write to the Free Software
+ *    Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ *    MA  02111-1307  USA
+ *
+ ************************************************************************/
+
+#ifndef SC_CELLKEY_TRANSLATOR_HXX
+#define SC_CELLKEY_TRANSLATOR_HXX
+
+#include "global.hxx"
+#include "opcode.hxx"
+#include <hash_map>
+#include <list>
+#include <memory>
+
+#include <com/sun/star/lang/Locale.hpp>
+
+struct TransItem;
+
+struct ScCellKeyword
+{
+    const sal_Char* mpName;
+    OpCodeEnum meOpCode;
+    const ::com::sun::star::lang::Locale& mrLocale;
+
+    ScCellKeyword(const sal_Char* pName, OpCodeEnum eOpCode, const ::com::sun::star::lang::Locale& rLocale);
+};
+
+typedef ::std::hash_map< String, ::std::list<ScCellKeyword>, ScStringHashCode, ::std::equal_to<String> > ScCellKeywordHashMap;
+
+/** Translate cell function keywords.
+    
+    This class provides a convenient way to translate a string keyword used as
+    a cell function argument.  Since Calc's built-in cell functions don't
+    localize string keywords, this class is used mainly to deal with an Excel
+    document where string names may be localized.
+    
+    To use, simply call one of
+    
+       ScCellKeywordTranslator::transKeyword(...)
+    
+    functions.
+    
+    Note that when the locale and/or the opcode is specified, the function
+    tries to find a string with matching locale and/or opcode. But when it
+    fails to find one that satisfies the specified locale and/or opcode, it
+    returns a translated string with non-matching locale and/or opcode if
+    available. */
+class ScCellKeywordTranslator
+{
+public:
+    static void transKeyword(String& rName, ::com::sun::star::lang::Locale* pLocale = NULL, OpCodeEnum eOpCode = ocNone);
+    ~ScCellKeywordTranslator() throw();
+
+private:
+    ScCellKeywordTranslator();
+
+    void init();
+    void addToMap(const String& rKey, const sal_Char* pName, 
+                  const ::com::sun::star::lang::Locale& rLocale, 
+                  OpCodeEnum eOpCode = ocNone);
+    void addToMap(const TransItem* pItems, const ::com::sun::star::lang::Locale& rLocale);
+
+    static ::std::auto_ptr<ScCellKeywordTranslator> spInstance;
+    ScCellKeywordHashMap maStringNameMap;
+};
+
+#endif
--- /dev/null	2007-03-30 11:25:40.000000000 -0400
+++ sc/source/core/tool/cellkeytranslator.cxx	2007-06-10 14:37:03.000000000 -0400
@@ -0,0 +1,239 @@
+/*************************************************************************
+ *
+ *  OpenOffice.org - a multi-platform office productivity suite
+ *
+ *  $RCSfile: interpre.hxx,v $
+ *
+ *  $Revision: 1.27 $
+ *
+ *  last change: $Author: ihi $ $Date: 2006/12/19 13:16:55 $
+ *
+ *  The Contents of this file are made available subject to
+ *  the terms of GNU Lesser General Public License Version 2.1.
+ *
+ *
+ *    GNU Lesser General Public License Version 2.1
+ *    =============================================
+ *    Copyright 2005 by Sun Microsystems, Inc.
+ *    901 San Antonio Road, Palo Alto, CA 94303, USA
+ *
+ *    This library is free software; you can redistribute it and/or
+ *    modify it under the terms of the GNU Lesser General Public
+ *    License version 2.1, as published by the Free Software Foundation.
+ *
+ *    This library 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 for more details.
+ *
+ *    You should have received a copy of the GNU Lesser General Public
+ *    License along with this library; if not, write to the Free Software
+ *    Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ *    MA  02111-1307  USA
+ *
+ ************************************************************************/
+
+#include "cellkeytranslator.hxx"
+#include "rtl/ustring.hxx"
+
+using ::com::sun::star::lang::Locale;
+using ::std::list;
+using ::std::hash_map;
+using ::rtl::OUString;
+
+enum LocaleMatch
+{
+    LOCALE_MATCH_NONE = 0,
+    LOCALE_MATCH_LANG,
+    LOCALE_MATCH_LANG_COUNTRY,
+    LOCALE_MATCH_ALL
+};
+
+static LocaleMatch lclLocaleCompare(const Locale& rLocale1, const Locale& rLocale2)
+{
+    LocaleMatch eMatchLevel = LOCALE_MATCH_NONE;
+    if ( !rLocale1.Language.compareTo(rLocale1.Language) )
+        eMatchLevel = LOCALE_MATCH_LANG;
+    else
+        return eMatchLevel;
+
+    if ( !rLocale1.Country.compareTo(rLocale2.Country) )
+        eMatchLevel = LOCALE_MATCH_LANG_COUNTRY;
+    else
+        return eMatchLevel;
+
+    if ( !rLocale1.Variant.compareTo(rLocale2.Variant) )
+        eMatchLevel = LOCALE_MATCH_ALL;
+
+    return eMatchLevel;
+}
+
+ScCellKeyword::ScCellKeyword(const sal_Char* pName, OpCodeEnum eOpCode, const Locale& rLocale) :
+    mpName(pName),
+    meOpCode(eOpCode),
+    mrLocale(rLocale)
+{
+}
+
+::std::auto_ptr<ScCellKeywordTranslator> ScCellKeywordTranslator::spInstance(NULL);
+
+static void lclMatchKeyword(String& rName, const ScCellKeywordHashMap& aMap, OpCodeEnum eOpCode = ocNone, const Locale* pLocale = NULL)
+{
+    ScCellKeywordHashMap::const_iterator itrEnd = aMap.end();
+    ScCellKeywordHashMap::const_iterator itr = aMap.find(rName);
+
+    if ( itr == itrEnd || itr->second.empty() )
+        // No candidate strings exist.  Bail out.
+        return;
+
+    if ( eOpCode == ocNone && !pLocale )
+    {
+        // Since no locale nor opcode matching is needed, simply return
+        // the first item on the list.
+        rName = String::CreateFromAscii( itr->second.front().mpName );
+        return;
+    }
+
+    const sal_Char* aBestMatchName = itr->second.front().mpName;
+    LocaleMatch eLocaleMatchLevel = LOCALE_MATCH_NONE;
+    bool bOpCodeMatched = false;
+
+    list<ScCellKeyword>::const_iterator itrListEnd = itr->second.end();
+    list<ScCellKeyword>::const_iterator itrList = itr->second.begin();
+    for ( ; itrList != itrListEnd; ++itrList )
+    {
+        if ( eOpCode != ocNone && pLocale )
+        {
+            if ( itrList->meOpCode == eOpCode )
+            {
+                LocaleMatch eLevel = lclLocaleCompare(itrList->mrLocale, *pLocale);
+                if ( eLevel == LOCALE_MATCH_ALL )
+                {
+                    // Name with matching opcode and locale found.
+                    rName = String::CreateFromAscii( itrList->mpName );
+                    return;
+                }
+                else if ( eLevel > eLocaleMatchLevel )
+                {
+                    // Name with a better matching locale.
+                    eLocaleMatchLevel = eLevel;
+                    aBestMatchName = itrList->mpName;
+                }
+                else if ( !bOpCodeMatched )
+                    // At least the opcode matches.
+                    aBestMatchName = itrList->mpName;
+
+                bOpCodeMatched = true;
+            }
+        }
+        else if ( eOpCode != ocNone && !pLocale )
+        {
+            if ( itrList->meOpCode == eOpCode )
+            {
+                // Name with a matching opcode preferred.
+                rName = String::CreateFromAscii( itrList->mpName );
+                return;
+            }
+        }
+        else if ( !eOpCode && pLocale )
+        {
+            LocaleMatch eLevel = lclLocaleCompare(itrList->mrLocale, *pLocale);
+            if ( eLevel == LOCALE_MATCH_ALL )
+            {
+                // Name with matching locale preferred.
+                rName = String::CreateFromAscii( itrList->mpName );
+                return;
+            }
+            else if ( eLevel > eLocaleMatchLevel )
+            {
+                // Name with a better matching locale.
+                eLocaleMatchLevel = eLevel;
+                aBestMatchName = itrList->mpName;
+            }
+        }
+    }
+
+    // No preferred strings found.  Return the best matching name.
+    rName = String::CreateFromAscii(aBestMatchName);
+}
+
+void ScCellKeywordTranslator::transKeyword(String& rName, Locale* pLocale, OpCodeEnum eOpCode)
+{
+    if ( !spInstance.get() )
+        spInstance.reset( new ScCellKeywordTranslator );
+
+    lclMatchKeyword(rName, spInstance->maStringNameMap, eOpCode, pLocale);
+}
+
+ScCellKeywordTranslator::ScCellKeywordTranslator()
+{
+    init();
+}
+
+ScCellKeywordTranslator::~ScCellKeywordTranslator() throw()
+{
+}
+
+struct TransItem
+{
+    const sal_Char* from;
+    const sal_Char* to;
+    OpCodeEnum      func;
+};
+
+void ScCellKeywordTranslator::init()
+{
+    // 1. Keywords must be all uppercase.
+    // 2. Mapping must be <localized string name> to <English string name>.
+
+    // French language locale.
+
+    static const Locale aFr(OUString::createFromAscii("fr"), OUString(), OUString());
+    static const TransItem pFr[] = 
+    {
+        // CELL
+        {"ADRESSE",    "ADDRESS",   ocCell},
+        {"COLONNE",    "COL",       ocCell},
+        {"CONTENU",    "CONTENTS",  ocCell},
+        {"COULEUR",    "COLOR",     ocCell},
+        {"LARGEUR",    "WIDTH",     ocCell},
+        {"LIGNE",      "ROW",       ocCell},
+        {"NOMFICHIER", "FILENAME",  ocCell},
+        {"PREFIXE",    "PREFIX",    ocCell},
+        {"PROTEGE",    "PROTECT",   ocCell},
+
+        // INFO
+        {"NBFICH",     "NUMFILE",   ocInfo},
+        {"RECALCUL",   "RECALC",    ocInfo},
+        {"SYSTEXPL",   "SYSTEM",    ocInfo},
+        {"VERSION",    "RELEASE",   ocInfo},
+        {"VERSIONSE",  "OSVERSION", ocInfo},
+
+        {NULL, NULL, ocNone}
+    };
+    addToMap(pFr, aFr);
+}
+
+void ScCellKeywordTranslator::addToMap(const String& rKey, const sal_Char* pName, const Locale& rLocale, OpCodeEnum eOpCode)
+{
+    ScCellKeyword aKeyItem( pName, eOpCode, rLocale );
+
+    ScCellKeywordHashMap::iterator itrEnd = maStringNameMap.end();
+    ScCellKeywordHashMap::iterator itr = maStringNameMap.find(rKey);
+
+    if ( itr == itrEnd )
+    {
+        // New keyword.
+        list<ScCellKeyword> aList;
+        aList.push_back(aKeyItem);
+        maStringNameMap.insert( ScCellKeywordHashMap::value_type(rKey, aList) );
+    }
+    else
+        itr->second.push_back(aKeyItem);
+}
+
+void ScCellKeywordTranslator::addToMap(const TransItem* pItems, const Locale& rLocale)
+{
+    for (sal_uInt16 i = 0; pItems[i].from != NULL; ++i)
+        addToMap(String::CreateFromAscii(pItems[i].from), pItems[i].to, rLocale, pItems[i].func);
+}
