LCOV - code coverage report
Current view: top level - lingucomponent/source/lingutil - lingutil.cxx (source / functions) Hit Total Coverage
Test: commit c8344322a7af75b84dd3ca8f78b05543a976dfd5 Lines: 79 92 85.9 %
Date: 2015-06-13 12:38:46 Functions: 3 3 100.0 %
Legend: Lines: hit not hit

          Line data    Source code
       1             : /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
       2             : /*
       3             :  * This file is part of the LibreOffice project.
       4             :  *
       5             :  * This Source Code Form is subject to the terms of the Mozilla Public
       6             :  * License, v. 2.0. If a copy of the MPL was not distributed with this
       7             :  * file, You can obtain one at http://mozilla.org/MPL/2.0/.
       8             :  *
       9             :  * This file incorporates work covered by the following license notice:
      10             :  *
      11             :  *   Licensed to the Apache Software Foundation (ASF) under one or more
      12             :  *   contributor license agreements. See the NOTICE file distributed
      13             :  *   with this work for additional information regarding copyright
      14             :  *   ownership. The ASF licenses this file to you under the Apache
      15             :  *   License, Version 2.0 (the "License"); you may not use this file
      16             :  *   except in compliance with the License. You may obtain a copy of
      17             :  *   the License at http://www.apache.org/licenses/LICENSE-2.0 .
      18             :  */
      19             : 
      20             : #if defined(WNT)
      21             : #include <windows.h>
      22             : #endif
      23             : 
      24             : #include <osl/thread.h>
      25             : #include <osl/file.hxx>
      26             : #include <tools/debug.hxx>
      27             : #include <tools/urlobj.hxx>
      28             : #include <i18nlangtag/languagetag.hxx>
      29             : #include <i18nlangtag/mslangid.hxx>
      30             : #include <unotools/lingucfg.hxx>
      31             : #include <unotools/pathoptions.hxx>
      32             : #include <rtl/ustring.hxx>
      33             : #include <rtl/string.hxx>
      34             : #include <rtl/tencinfo.h>
      35             : #include <linguistic/misc.hxx>
      36             : 
      37             : #include <set>
      38             : #include <vector>
      39             : #include <string.h>
      40             : 
      41             : #include <lingutil.hxx>
      42             : 
      43             : #include <sal/macros.h>
      44             : 
      45             : using ::com::sun::star::lang::Locale;
      46             : using namespace ::com::sun::star;
      47             : 
      48             : #if defined(WNT)
      49             : OString Win_AddLongPathPrefix( const OString &rPathName )
      50             : {
      51             : #define WIN32_LONG_PATH_PREFIX "\\\\?\\"
      52             :   if (!rPathName.match(WIN32_LONG_PATH_PREFIX)) return WIN32_LONG_PATH_PREFIX + rPathName;
      53             :   return rPathName;
      54             : }
      55             : #endif //defined(WNT)
      56             : 
      57             : // build list of old style diuctionaries (not as extensions) to use.
      58             : // User installed dictionaries (the ones residing in the user paths)
      59             : // will get precedence over system installed ones for the same language.
      60         172 : std::vector< SvtLinguConfigDictionaryEntry > GetOldStyleDics( const char *pDicType )
      61             : {
      62         172 :     std::vector< SvtLinguConfigDictionaryEntry > aRes;
      63             : 
      64         172 :     if (!pDicType)
      65           0 :         return aRes;
      66             : 
      67         344 :     OUString aFormatName;
      68         344 :     OUString aDicExtension;
      69             : #ifdef SYSTEM_DICTS
      70         344 :     OUString aSystemDir;
      71         344 :     OUString aSystemPrefix;
      72         344 :     OUString aSystemSuffix;
      73             : #endif
      74         172 :     if (strcmp( pDicType, "DICT" ) == 0)
      75             :     {
      76          43 :         aFormatName     = "DICT_SPELL";
      77          43 :         aDicExtension   = ".dic";
      78             : #ifdef SYSTEM_DICTS
      79          43 :         aSystemDir      = DICT_SYSTEM_DIR;
      80          43 :         aSystemSuffix   = aDicExtension;
      81             : #endif
      82             :     }
      83         129 :     else if (strcmp( pDicType, "HYPH" ) == 0)
      84             :     {
      85          43 :         aFormatName     = "DICT_HYPH";
      86          43 :         aDicExtension   = ".dic";
      87             : #ifdef SYSTEM_DICTS
      88          43 :         aSystemDir      = HYPH_SYSTEM_DIR;
      89          43 :         aSystemPrefix   = "hyph_";
      90          43 :         aSystemSuffix   = aDicExtension;
      91             : #endif
      92             :     }
      93          86 :     else if (strcmp( pDicType, "THES" ) == 0)
      94             :     {
      95          86 :         aFormatName     = "DICT_THES";
      96          86 :         aDicExtension   = ".dat";
      97             : #ifdef SYSTEM_DICTS
      98          86 :         aSystemDir      = THES_SYSTEM_DIR;
      99          86 :         aSystemPrefix   = "th_";
     100          86 :         aSystemSuffix   = "_v2.dat";
     101             : #endif
     102             :     }
     103             : 
     104         172 :     if (aFormatName.isEmpty() || aDicExtension.isEmpty())
     105           0 :         return aRes;
     106             : 
     107             : #ifdef SYSTEM_DICTS
     108         344 :     osl::Directory aSystemDicts(aSystemDir);
     109         172 :     if (aSystemDicts.open() == osl::FileBase::E_None)
     110             :     {
     111             :         // set of languages to remember the language where it is already
     112             :         // decided to make use of the dictionary.
     113          86 :         std::set< OUString > aDicLangInUse;
     114             : 
     115         172 :         osl::DirectoryItem aItem;
     116         172 :         osl::FileStatus aFileStatus(osl_FileStatus_Mask_FileURL);
     117         989 :         while (aSystemDicts.getNextItem(aItem) == osl::FileBase::E_None)
     118             :         {
     119         817 :             aItem.getFileStatus(aFileStatus);
     120         817 :             OUString sPath = aFileStatus.getFileURL();
     121         817 :             if (sPath.endsWith(aSystemSuffix))
     122             :             {
     123         387 :                 sal_Int32 nStartIndex = sPath.lastIndexOf('/') + 1;
     124         387 :                 if (!sPath.match(aSystemPrefix, nStartIndex))
     125          43 :                     continue;
     126         387 :                 OUString sChunk = sPath.copy(nStartIndex + aSystemPrefix.getLength(),
     127         387 :                     sPath.getLength() - aSystemSuffix.getLength() -
     128         774 :                     nStartIndex - aSystemPrefix.getLength());
     129         387 :                 if (sChunk.isEmpty())
     130           0 :                     continue;
     131             : 
     132             :                 // We prefer (now) to use language tags.
     133             :                 // Avoid feeding in the older LANG_REGION scheme to the BCP47
     134             :                 // ctor as that triggers use of liblangtag and initializes its
     135             :                 // database which we do not want during startup. Convert
     136             :                 // instead.
     137         387 :                 sChunk = sChunk.replace( '_', '-');
     138             : 
     139             :                 // There's a known exception to the rule, the dreaded
     140             :                 // hu_HU_u8.dic of the myspell-hu package, see
     141             :                 // http://packages.debian.org/search?arch=any&searchon=contents&keywords=hu_HU_u8.dic
     142             :                 // This was ignored because unknown in the old implementation,
     143             :                 // truncate to the known locale and either insert because hu_HU
     144             :                 // wasn't encountered yet, or skip because it was. It doesn't
     145             :                 // really matter because the proper new-style hu_HU dictionary
     146             :                 // will take precedence anyway if installed with a Hungarian
     147             :                 // languagepack. Again, this is only to not pull in all
     148             :                 // liblangtag and stuff during startup, the result would be
     149             :                 // !isValidBcp47() and the dictionary ignored.
     150         387 :                 if (sChunk == "hu-HU-u8")
     151           0 :                     sChunk = "hu-HU";
     152             : 
     153         731 :                 LanguageTag aLangTag(sChunk, true);
     154         387 :                 if (!aLangTag.isValidBcp47())
     155          43 :                     continue;
     156             : 
     157             :                 // Thus we first get the language of the dictionary
     158         688 :                 OUString aLocaleName(aLangTag.getBcp47());
     159             : 
     160         344 :                 if (aDicLangInUse.insert(aLocaleName).second)
     161             :                 {
     162             :                     // add the dictionary to the resulting vector
     163         344 :                     SvtLinguConfigDictionaryEntry aDicEntry;
     164         344 :                     aDicEntry.aLocations.realloc(1);
     165         344 :                     aDicEntry.aLocaleNames.realloc(1);
     166         344 :                     aDicEntry.aLocations[0] = sPath;
     167         344 :                     aDicEntry.aFormatName = aFormatName;
     168         344 :                     aDicEntry.aLocaleNames[0] = aLocaleName;
     169         344 :                     aRes.push_back( aDicEntry );
     170         344 :                 }
     171             :             }
     172         860 :         }
     173             :     }
     174             : #endif
     175             : 
     176         172 :     return aRes;
     177             : }
     178             : 
     179         172 : void MergeNewStyleDicsAndOldStyleDics(
     180             :     std::list< SvtLinguConfigDictionaryEntry > &rNewStyleDics,
     181             :     const std::vector< SvtLinguConfigDictionaryEntry > &rOldStyleDics )
     182             : {
     183             :     // get list of languages supported by new style dictionaries
     184         172 :     std::set< OUString > aNewStyleLanguages;
     185         172 :     std::list< SvtLinguConfigDictionaryEntry >::const_iterator aIt;
     186         172 :     for (aIt = rNewStyleDics.begin() ;  aIt != rNewStyleDics.end();  ++aIt)
     187             :     {
     188           0 :         const uno::Sequence< OUString > aLocaleNames( aIt->aLocaleNames );
     189           0 :         sal_Int32 nLocaleNames = aLocaleNames.getLength();
     190           0 :         for (sal_Int32 k = 0;  k < nLocaleNames; ++k)
     191             :         {
     192           0 :             aNewStyleLanguages.insert( aLocaleNames[k] );
     193             :         }
     194           0 :     }
     195             : 
     196             :     // now check all old style dictionaries if they will add a not yet
     197             :     // added language. If so add them to the resulting vector
     198         172 :     std::vector< SvtLinguConfigDictionaryEntry >::const_iterator aIt2;
     199         516 :     for (aIt2 = rOldStyleDics.begin();  aIt2 != rOldStyleDics.end();  ++aIt2)
     200             :     {
     201         344 :         sal_Int32 nOldStyleDics = aIt2->aLocaleNames.getLength();
     202             : 
     203             :         // old style dics should only have one language listed...
     204             :         DBG_ASSERT( nOldStyleDics, "old style dictionary with more than one language found!");
     205         344 :         if (nOldStyleDics > 0)
     206             :         {
     207         344 :             if (linguistic::LinguIsUnspecified( aIt2->aLocaleNames[0]))
     208             :             {
     209             :                 OSL_FAIL( "old style dictionary with invalid language found!" );
     210           0 :                 continue;
     211             :             }
     212             : 
     213             :             // language not yet added?
     214         344 :             if (aNewStyleLanguages.find( aIt2->aLocaleNames[0] ) == aNewStyleLanguages.end())
     215         344 :                 rNewStyleDics.push_back( *aIt2 );
     216             :         }
     217             :         else
     218             :         {
     219             :             OSL_FAIL( "old style dictionary with no language found!" );
     220             :         }
     221         172 :     }
     222         172 : }
     223             : 
     224          32 : rtl_TextEncoding getTextEncodingFromCharset(const sal_Char* pCharset)
     225             : {
     226             :     // default result: used to indicate that we failed to get the proper encoding
     227          32 :     rtl_TextEncoding eRet = RTL_TEXTENCODING_DONTKNOW;
     228             : 
     229          32 :     if (pCharset)
     230             :     {
     231          32 :         eRet = rtl_getTextEncodingFromMimeCharset(pCharset);
     232          32 :         if (eRet == RTL_TEXTENCODING_DONTKNOW)
     233           0 :             eRet = rtl_getTextEncodingFromUnixCharset(pCharset);
     234          32 :         if (eRet == RTL_TEXTENCODING_DONTKNOW)
     235             :         {
     236           0 :             if (strcmp("ISCII-DEVANAGARI", pCharset) == 0)
     237           0 :                 eRet = RTL_TEXTENCODING_ISCII_DEVANAGARI;
     238             :         }
     239             :     }
     240          32 :     return eRet;
     241             : }
     242             : 
     243             : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */

Generated by: LCOV version 1.11