2006-10-28 19:45:02 +00:00
/*
* lang . cpp
*
* This file is a part of NSIS .
*
2021-01-01 20:27:52 +00:00
* Copyright ( C ) 1999 - 2021 Nullsoft and Contributors
2006-10-28 19:45:02 +00:00
*
* Licensed under the zlib / libpng license ( the " License " ) ;
* you may not use this file except in compliance with the License .
*
* Licence details can be found in the file COPYING .
*
* This software is provided ' as - is ' , without any express or implied
* warranty .
2010-03-24 17:22:56 +00:00
*
* Unicode support and Doxygen comments by Jim Park - - 07 / 25 / 2007
2006-10-28 19:45:02 +00:00
*/
2004-01-30 22:04:10 +00:00
# include "Platform.h"
2002-08-03 23:06:10 +00:00
# include <stdio.h>
# include <stdlib.h>
2010-03-29 15:32:24 +00:00
# include "tchar.h"
2002-08-03 23:06:10 +00:00
# include "build.h"
2004-08-20 15:40:38 +00:00
# include "util.h"
2003-04-21 13:32:34 +00:00
# include "DialogTemplate.h"
2004-03-29 20:21:00 +00:00
# include "exehead/resource.h"
2009-02-04 14:05:48 +00:00
# include <nsis-version.h>
2010-03-24 17:22:56 +00:00
# include "tstring.h"
2011-12-05 23:44:26 +00:00
# include "utf.h"
2002-08-03 23:06:10 +00:00
2005-08-27 19:56:00 +00:00
using namespace std ;
2003-09-04 18:25:57 +00:00
// Default English strings. Should match NSIS_DEFAULT_LANG
// Do not change the first string in every item, it's the LangString
// name for usage in scripts.
typedef enum {
NONE_STATIC = 0 ,
INSTALL_STATIC = 1 ,
UNINSTALL_STATIC = 2 ,
BOTH_STATIC = 3
} STATICID ;
2007-03-11 16:49:02 +00:00
struct NLFString {
2010-03-24 17:22:56 +00:00
const TCHAR * szLangStringName ;
const TCHAR * szDefault ;
2003-09-04 18:25:57 +00:00
STATICID eStaticID ;
2007-03-11 16:49:02 +00:00
} ;
NLFString NLFStrings [ NLF_STRINGS ] = {
2010-03-24 17:22:56 +00:00
{ _T ( " ^Branding " ) , _T ( " Nullsoft Install System %s " ) , BOTH_STATIC } ,
{ _T ( " ^SetupCaption " ) , _T ( " $(^Name) Setup " ) , INSTALL_STATIC } ,
{ _T ( " ^UninstallCaption " ) , _T ( " $(^Name) Uninstall " ) , UNINSTALL_STATIC } ,
{ _T ( " ^LicenseSubCaption " ) , _T ( " : License Agreement " ) , NONE_STATIC } ,
{ _T ( " ^ComponentsSubCaption " ) , _T ( " : Installation Options " ) , NONE_STATIC } ,
{ _T ( " ^DirSubCaption " ) , _T ( " : Installation Folder " ) , NONE_STATIC } ,
{ _T ( " ^InstallingSubCaption " ) , _T ( " : Installing " ) , NONE_STATIC } ,
{ _T ( " ^CompletedSubCaption " ) , _T ( " : Completed " ) , NONE_STATIC } ,
{ _T ( " ^UnComponentsSubCaption " ) , _T ( " : Uninstallation Options " ) , NONE_STATIC } ,
{ _T ( " ^UnDirSubCaption " ) , _T ( " : Uninstallation Folder " ) , NONE_STATIC } ,
{ _T ( " ^ConfirmSubCaption " ) , _T ( " : Confirmation " ) , NONE_STATIC } ,
{ _T ( " ^UninstallingSubCaption " ) , _T ( " : Uninstalling " ) , NONE_STATIC } ,
{ _T ( " ^UnCompletedSubCaption " ) , _T ( " : Completed " ) , NONE_STATIC } ,
{ _T ( " ^BackBtn " ) , _T ( " < &Back " ) , NONE_STATIC } ,
{ _T ( " ^NextBtn " ) , _T ( " &Next > " ) , NONE_STATIC } ,
{ _T ( " ^AgreeBtn " ) , _T ( " I &Agree " ) , NONE_STATIC } ,
{ _T ( " ^AcceptBtn " ) , _T ( " I &accept the terms of the License Agreement " ) , NONE_STATIC } ,
{ _T ( " ^DontAcceptBtn " ) , _T ( " I &do not accept the terms of the License Agreement " ) , NONE_STATIC } ,
{ _T ( " ^InstallBtn " ) , _T ( " &Install " ) , NONE_STATIC } ,
{ _T ( " ^UninstallBtn " ) , _T ( " &Uninstall " ) , NONE_STATIC } ,
{ _T ( " ^CancelBtn " ) , _T ( " Cancel " ) , NONE_STATIC } ,
{ _T ( " ^CloseBtn " ) , _T ( " &Close " ) , NONE_STATIC } ,
{ _T ( " ^BrowseBtn " ) , _T ( " B&rowse... " ) , NONE_STATIC } ,
{ _T ( " ^ShowDetailsBtn " ) , _T ( " Show &details " ) , NONE_STATIC } ,
{ _T ( " ^ClickNext " ) , _T ( " Click Next to continue. " ) , NONE_STATIC } ,
{ _T ( " ^ClickInstall " ) , _T ( " Click Install to start the installation. " ) , NONE_STATIC } ,
{ _T ( " ^ClickUninstall " ) , _T ( " Click Uninstall to start the uninstallation. " ) , NONE_STATIC } ,
{ _T ( " ^Name " ) , _T ( " Name " ) , BOTH_STATIC } ,
{ _T ( " ^NameDA " ) , 0 , NONE_STATIC } , // virtual
{ _T ( " ^Completed " ) , _T ( " Completed " ) , NONE_STATIC } ,
{ _T ( " ^LicenseText " ) , _T ( " Please review the license agreement before installing $(^NameDA). If you accept all terms of the agreement, click I Agree. " ) , NONE_STATIC } ,
{ _T ( " ^LicenseTextCB " ) , _T ( " Please review the license agreement before installing $(^NameDA). If you accept all terms of the agreement, click the check box below. $_CLICK " ) , NONE_STATIC } ,
{ _T ( " ^LicenseTextRB " ) , _T ( " Please review the license agreement before installing $(^NameDA). If you accept all terms of the agreement, select the first option below. $_CLICK " ) , NONE_STATIC } ,
{ _T ( " ^UnLicenseText " ) , _T ( " Please review the license agreement before uninstalling $(^NameDA). If you accept all terms of the agreement, click I Agree. " ) , NONE_STATIC } ,
{ _T ( " ^UnLicenseTextCB " ) , _T ( " Please review the license agreement before uninstalling $(^NameDA). If you accept all terms of the agreement, click the check box below. $_CLICK " ) , NONE_STATIC } ,
{ _T ( " ^UnLicenseTextRB " ) , _T ( " Please review the license agreement before uninstalling $(^NameDA). If you accept all terms of the agreement, select the first option below. $_CLICK " ) , NONE_STATIC } ,
{ _T ( " ^LicenseData " ) , 0 , NONE_STATIC } , // virtual - not processed
{ _T ( " ^Custom " ) , _T ( " Custom " ) , NONE_STATIC } ,
{ _T ( " ^ComponentsText " ) , _T ( " Check the components you want to install and uncheck the components you don't want to install. $_CLICK " ) , NONE_STATIC } ,
{ _T ( " ^ComponentsSubText1 " ) , _T ( " Select the type of install: " ) , NONE_STATIC } ,
{ _T ( " ^ComponentsSubText2_NoInstTypes " ) , _T ( " Select components to install: " ) , NONE_STATIC } ,
{ _T ( " ^ComponentsSubText2 " ) , _T ( " Or, select the optional components you wish to install: " ) , NONE_STATIC } ,
{ _T ( " ^UnComponentsText " ) , _T ( " Check the components you want to uninstall and uncheck the components you don't want to uninstall. $_CLICK " ) , NONE_STATIC } ,
{ _T ( " ^UnComponentsSubText1 " ) , _T ( " Select the type of uninstall: " ) , NONE_STATIC } ,
{ _T ( " ^UnComponentsSubText2_NoInstTypes " ) , _T ( " Select components to uninstall: " ) , NONE_STATIC } ,
{ _T ( " ^UnComponentsSubText2 " ) , _T ( " Or, select the optional components you wish to uninstall: " ) , NONE_STATIC } ,
{ _T ( " ^DirText " ) , _T ( " Setup will install $(^NameDA) in the following folder. To install in a different folder, click Browse and select another folder. $_CLICK " ) , NONE_STATIC } ,
{ _T ( " ^DirSubText " ) , _T ( " Destination Folder " ) , NONE_STATIC } ,
{ _T ( " ^DirBrowseText " ) , _T ( " Select the folder to install $(^NameDA) in: " ) , NONE_STATIC } ,
{ _T ( " ^UnDirText " ) , _T ( " Setup will uninstall $(^NameDA) from the following folder. To uninstall from a different folder, click Browse and select another folder. $_CLICK " ) , NONE_STATIC } ,
{ _T ( " ^UnDirSubText " ) , _T ( " " ) , NONE_STATIC } ,
{ _T ( " ^UnDirBrowseText " ) , _T ( " Select the folder to uninstall $(^NameDA) from: " ) , NONE_STATIC } ,
{ _T ( " ^SpaceAvailable " ) , _T ( " Space available: " ) , BOTH_STATIC } ,
{ _T ( " ^SpaceRequired " ) , _T ( " Space required: " ) , BOTH_STATIC } ,
{ _T ( " ^UninstallingText " ) , _T ( " This wizard will uninstall $(^NameDA) from your computer. $_CLICK " ) , NONE_STATIC } ,
{ _T ( " ^UninstallingSubText " ) , _T ( " Uninstalling from: " ) , NONE_STATIC } ,
{ _T ( " ^FileError " ) , _T ( " Error opening file for writing: \r \n \r \n $0 \r \n \r \n Click Abort to stop the installation, \r \n Retry to try again, or \r \n Ignore to skip this file. " ) , NONE_STATIC } ,
{ _T ( " ^FileError_NoIgnore " ) , _T ( " Error opening file for writing: \r \n \r \n $0 \r \n \r \n Click Retry to try again, or \r \n Cancel to stop the installation. " ) , NONE_STATIC } ,
{ _T ( " ^CantWrite " ) , _T ( " Can't write: " ) , BOTH_STATIC } ,
{ _T ( " ^CopyFailed " ) , _T ( " Copy failed " ) , BOTH_STATIC } ,
{ _T ( " ^CopyTo " ) , _T ( " Copy to " ) , BOTH_STATIC } ,
{ _T ( " ^Registering " ) , _T ( " Registering: " ) , NONE_STATIC } ,
{ _T ( " ^Unregistering " ) , _T ( " Unregistering: " ) , NONE_STATIC } ,
{ _T ( " ^SymbolNotFound " ) , _T ( " Could not find symbol: " ) , BOTH_STATIC } ,
{ _T ( " ^CouldNotLoad " ) , _T ( " Could not load: " ) , BOTH_STATIC } ,
{ _T ( " ^CreateFolder " ) , _T ( " Create folder: " ) , BOTH_STATIC } ,
{ _T ( " ^CreateShortcut " ) , _T ( " Create shortcut: " ) , BOTH_STATIC } ,
{ _T ( " ^CreatedUninstaller " ) , _T ( " Created uninstaller: " ) , BOTH_STATIC } ,
{ _T ( " ^Delete " ) , _T ( " Delete file: " ) , BOTH_STATIC } ,
{ _T ( " ^DeleteOnReboot " ) , _T ( " Delete on reboot: " ) , BOTH_STATIC } ,
{ _T ( " ^ErrorCreatingShortcut " ) , _T ( " Error creating shortcut: " ) , BOTH_STATIC } ,
{ _T ( " ^ErrorCreating " ) , _T ( " Error creating: " ) , BOTH_STATIC } ,
{ _T ( " ^ErrorDecompressing " ) , _T ( " Error decompressing data! Corrupted installer? " ) , BOTH_STATIC } ,
{ _T ( " ^ErrorRegistering " ) , _T ( " Error registering DLL " ) , BOTH_STATIC } ,
{ _T ( " ^ExecShell " ) , _T ( " ExecShell: " ) , BOTH_STATIC } ,
{ _T ( " ^Exec " ) , _T ( " Execute: " ) , BOTH_STATIC } ,
{ _T ( " ^Extract " ) , _T ( " Extract: " ) , BOTH_STATIC } ,
{ _T ( " ^ErrorWriting " ) , _T ( " Extract: error writing to file " ) , BOTH_STATIC } ,
{ _T ( " ^InvalidOpcode " ) , _T ( " Installer corrupted: invalid opcode " ) , BOTH_STATIC } ,
{ _T ( " ^NoOLE " ) , _T ( " No OLE for: " ) , BOTH_STATIC } ,
{ _T ( " ^OutputFolder " ) , _T ( " Output folder: " ) , BOTH_STATIC } ,
{ _T ( " ^RemoveFolder " ) , _T ( " Remove folder: " ) , BOTH_STATIC } ,
{ _T ( " ^RenameOnReboot " ) , _T ( " Rename on reboot: " ) , BOTH_STATIC } ,
{ _T ( " ^Rename " ) , _T ( " Rename: " ) , BOTH_STATIC } ,
{ _T ( " ^Skipped " ) , _T ( " Skipped: " ) , BOTH_STATIC } ,
{ _T ( " ^CopyDetails " ) , _T ( " Copy Details To Clipboard " ) , BOTH_STATIC } ,
{ _T ( " ^LogInstall " ) , _T ( " Log install process " ) , BOTH_STATIC } ,
{ _T ( " ^Byte " ) , _T ( " B " ) , BOTH_STATIC } ,
2017-06-05 20:20:11 +00:00
{ _T ( " ^Kilo " ) , _T ( " K " ) , BOTH_STATIC } ,
{ _T ( " ^Mega " ) , _T ( " M " ) , BOTH_STATIC } ,
{ _T ( " ^Giga " ) , _T ( " G " ) , BOTH_STATIC } ,
2010-03-24 17:22:56 +00:00
{ _T ( " ^Font " ) , _T ( " MS Shell Dlg " ) , NONE_STATIC } ,
{ _T ( " ^FontSize " ) , _T ( " 8 " ) , NONE_STATIC } ,
{ _T ( " ^RTL " ) , _T ( " 0 " ) , NONE_STATIC } ,
{ _T ( " ^Language " ) , _T ( " English " ) , NONE_STATIC }
2002-08-03 23:06:10 +00:00
} ;
2004-10-12 21:22:55 +00:00
// ==============
// LangStringList
// ==============
2010-03-24 17:22:56 +00:00
int LangStringList : : add ( const TCHAR * name , int * sn /*=0*/ )
2004-10-12 21:22:55 +00:00
{
int pos = SortedStringListND < struct langstring > : : add ( name ) ;
if ( pos = = - 1 ) return - 1 ;
2010-04-14 10:15:40 +00:00
langstring * lstrPtr = ( langstring * ) ( m_gr . get ( ) ) + pos ;
lstrPtr - > sn = m_count ;
2010-04-13 15:19:12 +00:00
if ( sn ) * sn = m_count ;
m_count + + ;
2010-04-14 10:15:40 +00:00
lstrPtr - > index = - 1 ;
lstrPtr - > uindex = - 1 ;
lstrPtr - > process = 1 ;
2004-10-12 21:22:55 +00:00
return pos ;
}
2010-03-24 17:22:56 +00:00
int LangStringList : : get ( const TCHAR * name , int * sn /*=0*/ , int * index /*=0*/ , int * uindex /*=0*/ , int * process /*=0*/ )
2004-10-12 21:22:55 +00:00
{
2010-03-24 17:22:56 +00:00
if ( index ) * index = - 1 ;
2004-10-12 21:22:55 +00:00
if ( uindex ) * uindex = - 1 ;
if ( sn ) * sn = - 1 ;
int v = find ( name ) ;
if ( v = = - 1 ) return - 1 ;
2010-04-14 10:15:40 +00:00
langstring * lstrPtr = ( langstring * ) ( m_gr . get ( ) ) + v ;
if ( index ) * index = lstrPtr - > index ;
if ( uindex ) * uindex = lstrPtr - > uindex ;
if ( sn ) * sn = lstrPtr - > sn ;
if ( process ) * process = lstrPtr - > process ;
2004-10-12 21:22:55 +00:00
return v ;
}
void LangStringList : : set ( int pos , int index /*=-1*/ , int uindex /*=-1*/ , int process /*=-1*/ )
{
2010-04-13 15:19:12 +00:00
if ( ( unsigned int ) pos > ( m_gr . getlen ( ) / sizeof ( struct langstring ) ) )
2004-10-12 21:22:55 +00:00
return ;
2010-04-14 10:15:40 +00:00
struct langstring * data = ( ( struct langstring * ) m_gr . get ( ) ) + pos ;
2004-10-12 21:22:55 +00:00
2010-04-14 10:15:40 +00:00
if ( index > = 0 ) data - > index = index ;
if ( uindex > = 0 ) data - > uindex = uindex ;
if ( process > = 0 ) data - > process = process ;
2004-10-12 21:22:55 +00:00
}
2010-03-24 17:22:56 +00:00
void LangStringList : : set ( const TCHAR * name , int index , int uindex /*=-1*/ , int process /*=-1*/ )
2004-10-12 21:22:55 +00:00
{
2010-04-15 12:11:06 +00:00
set ( find ( name ) , index , uindex , process ) ;
2004-10-12 21:22:55 +00:00
}
2010-03-24 17:22:56 +00:00
const TCHAR * LangStringList : : pos2name ( int pos )
2004-10-12 21:22:55 +00:00
{
2010-04-13 15:19:12 +00:00
struct langstring * data = ( struct langstring * ) m_gr . get ( ) ;
2004-10-12 21:22:55 +00:00
2010-04-15 12:11:06 +00:00
if ( pos < 0 | | ( unsigned int ) pos > ( m_gr . getlen ( ) / sizeof ( struct langstring ) ) )
2004-10-12 21:22:55 +00:00
return 0 ;
2010-04-13 15:19:12 +00:00
return ( ( const TCHAR * ) m_strings . get ( ) + data [ pos ] . name ) ;
2004-10-12 21:22:55 +00:00
}
2010-03-24 17:22:56 +00:00
const TCHAR * LangStringList : : offset2name ( int name )
2004-10-12 21:22:55 +00:00
{
2010-04-15 12:11:06 +00:00
if ( name < 0 | | ( unsigned int ) name > m_strings . getlen ( ) / sizeof ( TCHAR ) )
2004-10-12 21:22:55 +00:00
return 0 ;
2010-04-13 15:19:12 +00:00
return ( const TCHAR * ) m_strings . get ( ) + name ;
2004-10-12 21:22:55 +00:00
}
int LangStringList : : getnum ( )
{
2010-04-13 15:19:12 +00:00
return m_gr . getlen ( ) / sizeof ( struct langstring ) ;
2004-10-12 21:22:55 +00:00
}
int LangStringList : : compare_index ( const void * item1 , const void * item2 )
{
struct langstring * ls1 = ( struct langstring * ) item1 ;
struct langstring * ls2 = ( struct langstring * ) item2 ;
return ls1 - > index - ls2 - > index ;
}
langstring * LangStringList : : sort_index ( int * num )
{
if ( ! num ) return 0 ;
2010-04-13 15:19:12 +00:00
m_sortbuf . resize ( 0 ) ;
m_sortbuf . add ( m_gr . get ( ) , m_gr . getlen ( ) ) ;
* num = m_sortbuf . getlen ( ) / sizeof ( struct langstring ) ;
qsort ( m_sortbuf . get ( ) , * num , sizeof ( struct langstring ) , compare_index ) ;
return ( struct langstring * ) m_sortbuf . get ( ) ;
2004-10-12 21:22:55 +00:00
}
int LangStringList : : compare_uindex ( const void * item1 , const void * item2 )
{
struct langstring * ls1 = ( struct langstring * ) item1 ;
struct langstring * ls2 = ( struct langstring * ) item2 ;
return ls1 - > uindex - ls2 - > uindex ;
}
langstring * LangStringList : : sort_uindex ( int * num )
{
if ( ! num ) return 0 ;
2010-04-13 15:19:12 +00:00
m_sortbuf . resize ( 0 ) ;
m_sortbuf . add ( m_gr . get ( ) , m_gr . getlen ( ) ) ;
* num = m_sortbuf . getlen ( ) / sizeof ( struct langstring ) ;
qsort ( m_sortbuf . get ( ) , * num , sizeof ( struct langstring ) , compare_uindex ) ;
return ( struct langstring * ) m_sortbuf . get ( ) ;
2004-10-12 21:22:55 +00:00
}
// ============
// StringsArray
// ============
StringsArray : : StringsArray ( )
{
2010-04-13 15:19:12 +00:00
// We make zero an invalid index. Using 0 will get back an empty string.
m_offsets . set_zeroing ( 1 ) ;
2004-10-12 21:22:55 +00:00
2010-04-13 15:19:12 +00:00
m_strings . add ( _T ( " " ) , sizeof ( _T ( " " ) ) ) ;
2004-10-12 21:22:55 +00:00
}
void StringsArray : : resize ( int num )
{
2010-04-13 15:19:12 +00:00
m_offsets . resize ( num * sizeof ( int ) ) ;
2004-10-12 21:22:55 +00:00
}
2010-03-24 17:22:56 +00:00
int StringsArray : : set ( int idx , const TCHAR * str )
2004-10-12 21:22:55 +00:00
{
if ( idx < 0 )
return 0 ;
2010-04-13 15:19:12 +00:00
if ( idx > = ( int ) ( m_offsets . getlen ( ) / sizeof ( int ) ) )
2004-10-12 21:22:55 +00:00
resize ( idx + 1 ) ;
2010-04-13 15:19:12 +00:00
int old = ( ( int * ) m_offsets . get ( ) ) [ idx ] ;
2004-10-12 21:22:55 +00:00
2010-04-13 15:19:12 +00:00
// Need to store the TCHAR index so we divide the return value of add by sizeof(TCHAR).
2014-02-08 00:13:52 +00:00
( ( int * ) m_offsets . get ( ) ) [ idx ] = m_strings . add ( str , ( DWORD ) ( _tcslen ( str ) + 1 ) * sizeof ( TCHAR ) ) / sizeof ( TCHAR ) ;
2004-10-12 21:22:55 +00:00
return old ;
}
2010-03-24 17:22:56 +00:00
const TCHAR * StringsArray : : get ( int idx )
2004-10-12 21:22:55 +00:00
{
2010-04-15 12:11:06 +00:00
if ( idx < 0 | | ( unsigned int ) idx > = ( m_offsets . getlen ( ) / sizeof ( int ) ) )
2004-10-12 21:22:55 +00:00
return 0 ;
2010-04-13 15:19:12 +00:00
return ( const TCHAR * ) m_strings . get ( ) + ( ( int * ) m_offsets . get ( ) ) [ idx ] ;
2004-10-12 21:22:55 +00:00
}
// =========
// CEXEBuild
// =========
2003-09-04 18:25:57 +00:00
void CEXEBuild : : InitLangTables ( ) {
keep_ref = false ;
for ( int i = 0 ; i < NLF_STRINGS ; i + + ) {
NLFRefs [ i ] . iRef = 0 ;
NLFRefs [ i ] . iUnRef = 0 ;
# ifdef NSIS_CONFIG_LOG
if ( i = = NLF_NAME ) {
NLFRefs [ i ] . iRef + + ;
NLFRefs [ i ] . iUnRef + + ;
}
# endif
if ( NLFStrings [ i ] . eStaticID & INSTALL_STATIC ) {
set_uninstall_mode ( 0 ) ;
DefineLangString ( NLFStrings [ i ] . szLangStringName ) ;
}
# ifdef NSIS_CONFIG_UNINSTALL_SUPPORT
if ( NLFStrings [ i ] . eStaticID & UNINSTALL_STATIC ) {
set_uninstall_mode ( 1 ) ;
DefineLangString ( NLFStrings [ i ] . szLangStringName ) ;
}
# endif
}
set_uninstall_mode ( 0 ) ;
keep_ref = true ;
}
2010-03-24 17:22:56 +00:00
//////////////////////////////////////////////////////////////////////////////
// class CEXEBuild
//
// Note: The functions below refer to the methods related to Languages.
//////////////////////////////////////////////////////////////////////////////
2007-01-23 21:21:30 +00:00
LanguageTable * CEXEBuild : : GetLangTable ( LANGID & lang , bool create /*=true*/ ) {
2003-09-04 18:25:57 +00:00
int nlt = lang_tables . getlen ( ) / sizeof ( LanguageTable ) ;
LanguageTable * nla = ( LanguageTable * ) lang_tables . get ( ) ;
lang = lang ? lang : last_used_lang ;
2007-01-23 21:21:30 +00:00
LanguageTable * table = NULL ;
2003-09-04 18:25:57 +00:00
for ( int i = 0 ; i < nlt ; i + + ) {
if ( lang = = nla [ i ] . lang_id ) {
table = & nla [ i ] ;
2002-08-03 23:06:10 +00:00
break ;
}
}
2007-01-23 21:21:30 +00:00
if ( ! table & & create ) {
2003-09-04 18:25:57 +00:00
LanguageTable newtable ;
2002-12-20 15:12:23 +00:00
2003-09-04 18:25:57 +00:00
newtable . lang_id = lang ;
newtable . dlg_offset = 0 ;
memset ( & newtable . nlf , 0 , sizeof ( NLF ) ) ;
2003-04-21 13:32:34 +00:00
2003-09-04 18:25:57 +00:00
newtable . lang_strings = new StringsArray ;
2002-12-20 15:12:23 +00:00
2003-09-04 18:25:57 +00:00
lang_tables . add ( & newtable , sizeof ( LanguageTable ) ) ;
table = ( LanguageTable * ) lang_tables . get ( ) + nlt ;
2002-08-03 23:06:10 +00:00
}
2007-01-23 21:21:30 +00:00
if ( table ) // update last used language if a table was loaded
last_used_lang = lang ;
2002-09-29 20:25:15 +00:00
return table ;
}
2010-03-24 17:22:56 +00:00
const TCHAR * CEXEBuild : : GetLangNameAndCP ( LANGID lang , unsigned int * codepage /*=NULL*/ ) {
2007-01-23 21:21:30 +00:00
LanguageTable * table = GetLangTable ( lang , false ) ;
if ( table & & table - > nlf . m_bLoaded ) {
if ( codepage )
* codepage = table - > nlf . m_uCodePage ;
return table - > nlf . m_szName ;
}
else {
2011-07-29 22:11:00 +00:00
// If the language table does not exist, then we default to Unicode or ANSI
// depending on the target installer type
2007-01-23 21:21:30 +00:00
if ( codepage )
2010-06-14 10:07:22 +00:00
* codepage = build_unicode ? 1200 : 1252 ; // Unicode or CP1252
2007-01-23 21:21:30 +00:00
if ( lang = = 1033 )
2010-03-24 17:22:56 +00:00
return _T ( " English " ) ;
2007-01-23 21:21:30 +00:00
else
2010-03-24 17:22:56 +00:00
return _T ( " ??? " ) ;
2007-01-23 21:21:30 +00:00
}
}
2011-07-29 22:11:00 +00:00
const TCHAR * CEXEBuild : : GetLangNameAndCPForVersionResource ( LANGID & lang , unsigned int * codepage /*=NULL*/ , bool deflangfallback /*=true*/ ) {
const TCHAR * langname = GetLangNameAndCP ( lang , codepage ) ;
if ( 0 = = lang ) {
if ( deflangfallback )
lang = last_used_lang ;
else
langname = _T ( " Neutral " ) ;
}
return langname ;
}
2010-03-24 17:22:56 +00:00
int CEXEBuild : : DefineLangString ( const TCHAR * name , int process /*=-1*/ ) {
2003-09-04 18:25:57 +00:00
int index , uindex , pos , ret , sn ;
2010-03-24 17:22:56 +00:00
/* If not exist, index and uindex will get -1. */
2003-09-04 18:25:57 +00:00
pos = build_langstrings . get ( name , & sn , & index , & uindex ) ;
if ( pos < 0 ) {
pos = build_langstrings . add ( name ) ;
}
2002-08-03 23:06:10 +00:00
2002-08-04 20:25:10 +00:00
# ifdef NSIS_CONFIG_UNINSTALL_SUPPORT
2010-03-24 17:22:56 +00:00
if ( ! this - > uninstall_mode ) {
2003-03-26 17:47:46 +00:00
# endif
2003-09-04 18:25:57 +00:00
if ( index < 0 ) {
2010-03-24 17:22:56 +00:00
// Did not exist. Increment.
index = this - > build_langstring_num + + ;
2003-09-04 18:25:57 +00:00
}
ret = - index - 1 ;
2002-09-18 19:08:53 +00:00
# ifdef NSIS_CONFIG_UNINSTALL_SUPPORT
2003-09-04 18:25:57 +00:00
}
else {
if ( uindex < 0 ) {
2010-03-24 17:22:56 +00:00
// Did not exist. Increment.
uindex = this - > ubuild_langstring_num + + ;
2003-09-04 18:25:57 +00:00
}
ret = - uindex - 1 ;
}
2002-11-01 20:34:55 +00:00
# endif
2010-03-24 17:22:56 +00:00
// Now set the new index and uindex values with the
2016-02-04 20:14:06 +00:00
// passed in process value.
2003-09-04 18:25:57 +00:00
build_langstrings . set ( pos , index , uindex , process ) ;
2002-08-03 23:06:10 +00:00
2003-09-04 18:25:57 +00:00
// set reference count for NLF strings
2010-03-24 17:22:56 +00:00
if ( this - > keep_ref & & name [ 0 ] = = _T ( ' ^ ' ) ) {
2003-09-04 18:25:57 +00:00
for ( int i = 0 ; i < NLF_STRINGS ; i + + ) {
2010-03-24 17:22:56 +00:00
if ( ! _tcscmp ( name , NLFStrings [ i ] . szLangStringName ) ) {
2003-09-04 18:25:57 +00:00
# ifdef NSIS_CONFIG_UNINSTALL_SUPPORT
2010-03-24 17:22:56 +00:00
if ( this - > uninstall_mode )
this - > NLFRefs [ i ] . iUnRef + + ;
2003-09-04 18:25:57 +00:00
else
2002-09-18 19:08:53 +00:00
# endif
2010-03-24 17:22:56 +00:00
this - > NLFRefs [ i ] . iRef + + ;
2002-08-03 23:06:10 +00:00
2003-09-04 18:25:57 +00:00
break ;
}
}
2002-08-03 23:06:10 +00:00
}
2003-09-04 18:25:57 +00:00
return ret ;
2002-08-03 23:06:10 +00:00
}
2003-09-04 18:25:57 +00:00
int CEXEBuild : : DefineInnerLangString ( int id , int process /*=-1*/ ) {
bool old_keep_ref = keep_ref ;
2002-12-20 19:14:57 +00:00
2003-09-04 18:25:57 +00:00
// set reference count for NLF strings
if ( keep_ref ) {
# ifdef NSIS_CONFIG_UNINSTALL_SUPPORT
if ( uninstall_mode )
NLFRefs [ id ] . iUnRef + + ;
else
# endif
NLFRefs [ id ] . iRef + + ;
keep_ref = false ;
2002-12-20 19:14:57 +00:00
}
2003-09-04 18:25:57 +00:00
int ret = DefineLangString ( NLFStrings [ id ] . szLangStringName , process ) ;
keep_ref = old_keep_ref ;
2002-12-20 19:14:57 +00:00
2003-09-04 18:25:57 +00:00
return ret ;
2002-12-20 19:14:57 +00:00
}
2010-03-24 17:22:56 +00:00
// A LangString is a string variable that varies in value depending on what
// language is being used. This function sets the string value for the
// variable 'name' for a given language ID.
//
// @return If the language id, the variable name or string is invalid, it will
// return a PS_ERROR. If this function call is overwriting a set user string,
// this will return a PS_WARNING.
2013-03-07 21:25:35 +00:00
int CEXEBuild : : SetLangString ( const TCHAR * name , LANGID lang , const TCHAR * str , BOOL LicenseData ) {
2010-03-24 17:22:56 +00:00
if ( ! str | | ! name ) return PS_ERROR ;
2002-09-29 20:25:15 +00:00
2003-09-04 18:25:57 +00:00
LanguageTable * table = GetLangTable ( lang ) ;
if ( ! table ) return PS_ERROR ;
2002-09-29 20:25:15 +00:00
2003-09-04 18:25:57 +00:00
int sn ;
2013-03-07 21:25:35 +00:00
if ( ! LicenseData & & _tcsclen ( str ) > NSIS_MAX_STRLEN - 1 )
2017-04-25 13:09:41 +00:00
warning_fl ( DW_LANGSTRING_OVERLONGLENGTH , _T ( " LangString \" % " ) NPRIs _T ( " \" longer than NSIS_MAX_STRLEN! " ) , name ) ;
2011-12-05 23:44:26 +00:00
2003-09-04 18:25:57 +00:00
int pos = build_langstrings . get ( name , & sn ) ;
if ( pos < 0 )
pos = build_langstrings . add ( name , & sn ) ;
2002-09-29 20:25:15 +00:00
2013-03-07 21:25:35 +00:00
if ( table - > lang_strings - > set ( sn , str ) )
2003-09-04 18:25:57 +00:00
return PS_WARNING ;
2002-12-20 15:12:23 +00:00
2002-09-29 20:25:15 +00:00
return PS_OK ;
}
2013-03-07 21:25:35 +00:00
int CEXEBuild : : SetLangString ( const TCHAR * name , LANGID lang , const TCHAR * str )
2011-12-05 23:44:26 +00:00
{
2013-03-07 21:25:35 +00:00
return SetLangString ( name , lang , str , false ) ;
2011-12-05 23:44:26 +00:00
}
2013-03-07 21:25:35 +00:00
2011-12-05 23:44:26 +00:00
2010-03-24 17:22:56 +00:00
// Sets the user string to the specific NLF_STRINGS id.
//
// @return If the id is invalid or the string is not valid, it will return a
// PS_ERROR. If this function call is overwriting a set user string, this
// will return a PS_WARNING.
2019-10-24 22:15:30 +00:00
int CEXEBuild : : SetInnerString ( int id , const TCHAR * str ) {
2010-03-24 17:22:56 +00:00
if ( ( unsigned int ) id > = NLF_STRINGS | | ! str ) return PS_ERROR ;
2003-09-04 18:25:57 +00:00
int ret = PS_OK ;
2010-03-24 17:22:56 +00:00
const TCHAR * ps = UserInnerStrings . get ( id ) ;
2003-09-04 18:25:57 +00:00
if ( ps & & * ps )
ret = PS_WARNING ;
2010-03-24 17:22:56 +00:00
UserInnerStrings . set ( id , str ) ;
2003-09-04 18:25:57 +00:00
return ret ;
2002-08-04 20:25:10 +00:00
}
2002-08-03 23:06:10 +00:00
2007-04-26 20:49:14 +00:00
int CEXEBuild : : GenerateLangTable ( LanguageTable * lt , int num_lang_tables ) {
// Add all installer language strings
int i , j , l , tabsset ;
struct langstring * lang_strings = NULL ;
TinyGrowBuf * string_ptrs = new TinyGrowBuf [ num_lang_tables ] ;
tabsset = 1 ;
while ( tabsset )
{
tabsset = 0 ;
for ( i = num_lang_tables ; i - - ; )
{
// Fill in default values for all used language strings that we can
FillLanguageTable ( & lt [ i ] ) ;
// Make sure the string lists are large enough
string_ptrs [ i ] . set_zeroing ( 1 ) ;
if ( ! uninstall_mode )
string_ptrs [ i ] . resize ( build_langstring_num * sizeof ( int ) ) ;
else
string_ptrs [ i ] . resize ( ubuild_langstring_num * sizeof ( int ) ) ;
}
// For all current language strings
if ( ! uninstall_mode )
lang_strings = build_langstrings . sort_index ( & l ) ;
else
lang_strings = build_langstrings . sort_uindex ( & l ) ;
for ( j = 0 ; j < l ; j + + )
{
int lang_string_index ;
if ( ! uninstall_mode )
lang_string_index = lang_strings [ j ] . index ;
else
lang_string_index = lang_strings [ j ] . uindex ;
// Is this language string used (in the installer)?
if ( lang_string_index > = 0 )
{
// For each language
for ( i = num_lang_tables ; i - - ; )
{
// Get the current string pointer
int * ptr = ( int * ) string_ptrs [ i ] . get ( ) + lang_string_index ;
// Not already set?
if ( ! * ptr )
{
// Get the language string and its name
2010-03-24 17:22:56 +00:00
const TCHAR * str = lt [ i ] . lang_strings - > get ( lang_strings [ j ] . sn ) ;
const TCHAR * lsn = build_langstrings . offset2name ( lang_strings [ j ] . name ) ;
// lsn = variable name, str = value
2007-04-26 20:49:14 +00:00
if ( ! str | | ! * str )
{
// No string is defined; give a warning (for user strings only)
2010-03-24 17:22:56 +00:00
if ( lsn [ 0 ] ! = _T ( ' ^ ' ) )
2007-04-26 20:49:14 +00:00
{
if ( lt [ i ] . nlf . m_bLoaded )
2017-04-25 13:09:41 +00:00
warning ( DW_LANGSTRING_NOTSETINLANG , _T ( " LangString \" % " ) NPRIs _T ( " \" is not set in language table of language % " ) NPRIs , lsn , lt [ i ] . nlf . m_szName ) ;
2007-04-26 20:49:14 +00:00
else
2017-04-25 13:09:41 +00:00
warning ( DW_LANGSTRING_NOTSETINLANG , _T ( " LangString \" % " ) NPRIs _T ( " \" is not set in language table of language %d " ) , lsn , lt [ i ] . lang_id ) ;
2007-04-26 20:49:14 +00:00
}
}
else
{
// Add the language string to the string data block
2010-03-24 17:22:56 +00:00
TCHAR fn [ 1024 ] ;
2013-12-08 14:34:38 +00:00
_stprintf ( fn , _T ( " LangString % " ) NPRIs , lsn ) ;
2007-04-26 20:49:14 +00:00
curfilename = fn ;
linecnt = lt [ i ] . lang_id ;
* ptr = add_string ( str , lang_strings [ j ] . process , ( WORD ) lt [ i ] . nlf . m_uCodePage ) ;
curfilename = 0 ;
// Indicate that we should check again for any newly referenced language strings
tabsset + + ;
}
}
}
}
}
}
// Optimize langstrings and check for recursion
for ( i = num_lang_tables ; i - - ; )
{
TinyGrowBuf rec ;
int * lst = ( int * ) string_ptrs [ i ] . get ( ) ;
2016-03-09 22:33:27 +00:00
int langstring_num = uninstall_mode ? ubuild_langstring_num : build_langstring_num ;
2007-04-26 20:49:14 +00:00
for ( j = 0 ; j < langstring_num ; j + + )
{
// Does this string reference another language string directly?
while ( lst [ j ] < 0 )
{
// Search through list of language string references
for ( l = 0 ; ( unsigned int ) l < rec . getlen ( ) / sizeof ( int ) ; l + + )
{
if ( ( ( int * ) rec . get ( ) ) [ l ] = = lst [ j ] )
{
// We have the index of a recursive language string; now find the name
2010-03-24 17:22:56 +00:00
const TCHAR * name = _T ( " (unnamed) " ) ;
2007-04-26 20:49:14 +00:00
for ( l = 0 ; l < langstring_num ; l + + )
{
2016-03-09 22:33:27 +00:00
int recidx = uninstall_mode ? lang_strings [ l ] . uindex : lang_strings [ l ] . index ;
if ( recidx = = j )
2007-04-26 20:49:14 +00:00
{
name = build_langstrings . offset2name ( lang_strings [ l ] . name ) ;
}
}
2016-03-09 22:33:27 +00:00
ERROR_MSG ( _T ( " Error: LangString % " ) NPRIs _T ( " in language %u is recursive! \n " ) , name , lt - > lang_id ) ;
2007-04-26 20:49:14 +00:00
delete [ ] string_ptrs ;
return PS_ERROR ;
}
}
// Add this reference to the list
rec . add ( & lst [ j ] , sizeof ( int ) ) ;
// and dereference it
lst [ j ] = lst [ - lst [ j ] - 1 ] ;
}
rec . resize ( 0 ) ;
}
}
// Add language tables into their datablock
for ( i = num_lang_tables ; i - - ; )
{
cur_langtables - > add ( & lt [ i ] . lang_id , sizeof ( LANGID ) ) ;
cur_langtables - > add ( & lt [ i ] . dlg_offset , sizeof ( int ) ) ;
int rtl = lt [ i ] . nlf . m_bRTL ? 1 : 0 ;
cur_langtables - > add ( & rtl , sizeof ( int ) ) ;
cur_langtables - > add ( string_ptrs [ i ] . get ( ) , string_ptrs [ i ] . getlen ( ) ) ;
string_ptrs [ i ] . resize ( 0 ) ;
}
cur_header - > blocks [ NB_LANGTABLES ] . num = num_lang_tables ;
cur_header - > langtable_size = cur_langtables - > getlen ( ) / num_lang_tables ;
delete [ ] string_ptrs ;
return PS_OK ;
}
2003-09-04 18:25:57 +00:00
int CEXEBuild : : GenerateLangTables ( ) {
2002-08-04 20:25:10 +00:00
int i ;
2003-09-04 18:25:57 +00:00
LanguageTable * lt = ( LanguageTable * ) lang_tables . get ( ) ;
2002-08-03 23:06:10 +00:00
2010-03-24 17:22:56 +00:00
SCRIPT_MSG ( _T ( " Generating language tables... " ) ) ;
2002-09-29 20:25:15 +00:00
2004-01-04 17:05:03 +00:00
if (
# ifdef NSIS_CONFIG_UNINSTALL_SUPPORT
ubuild_langstring_num > MAX_CODED | |
# endif
build_langstring_num > MAX_CODED
)
{
2010-03-24 17:22:56 +00:00
ERROR_MSG ( _T ( " \n Error: too many LangStrings. Maximum allowed is %u. \n " ) , MAX_CODED ) ;
2004-01-04 17:05:03 +00:00
return PS_ERROR ;
}
2002-08-04 20:25:10 +00:00
// If we have no tables (user didn't set any string and didn't load any NLF) create the default one
2003-09-04 18:25:57 +00:00
if ( ! lang_tables . getlen ( ) ) {
LANGID lang = NSIS_DEFAULT_LANG ;
LanguageTable * table = GetLangTable ( lang ) ;
2002-10-24 21:02:32 +00:00
if ( ! table ) return PS_ERROR ;
2003-09-04 18:25:57 +00:00
lt = ( LanguageTable * ) lang_tables . get ( ) ;
2002-10-24 21:02:32 +00:00
}
2002-08-03 23:06:10 +00:00
2003-09-06 09:59:02 +00:00
// Apply default font
if ( * build_font )
{
try {
init_res_editor ( ) ;
# define ADD_FONT(id) { \
2010-04-12 16:00:17 +00:00
BYTE * dlg = res_editor - > GetResource ( RT_DIALOG , id , NSIS_DEFAULT_LANG ) ; \
2003-09-06 09:59:02 +00:00
if ( dlg ) { \
2010-06-14 10:07:22 +00:00
CDialogTemplate td ( dlg , build_unicode ) ; \
2005-05-11 16:20:18 +00:00
res_editor - > FreeResource ( dlg ) ; \
2007-04-11 21:27:19 +00:00
td . SetFont ( build_font , ( WORD ) build_font_size ) ; \
2003-09-06 09:59:02 +00:00
DWORD dwSize ; \
dlg = td . Save ( dwSize ) ; \
2010-04-12 16:00:17 +00:00
res_editor - > UpdateResource ( RT_DIALOG , id , NSIS_DEFAULT_LANG , dlg , dwSize ) ; \
2014-08-05 13:53:20 +00:00
td . FreeSavedTemplate ( dlg ) ; \
2003-09-06 09:59:02 +00:00
} \
}
# ifdef NSIS_CONFIG_LICENSEPAGE
ADD_FONT ( IDD_LICENSE ) ;
ADD_FONT ( IDD_LICENSE_FSRB ) ;
ADD_FONT ( IDD_LICENSE_FSCB ) ;
# endif
ADD_FONT ( IDD_DIR ) ;
# ifdef NSIS_CONFIG_COMPONENTPAGE
ADD_FONT ( IDD_SELCOM ) ;
# endif
ADD_FONT ( IDD_INST ) ;
ADD_FONT ( IDD_INSTFILES ) ;
# ifdef NSIS_CONFIG_UNINSTALL_SUPPORT
ADD_FONT ( IDD_UNINST ) ;
# endif
# ifdef NSIS_CONFIG_CRC_SUPPORT
ADD_FONT ( IDD_VERIFY ) ;
# endif
# undef ADD_FONT
}
catch ( exception & err ) {
2013-12-08 14:34:38 +00:00
ERROR_MSG ( _T ( " \n Error while applying font: % " ) NPRIs _T ( " \n " ) , CtoTStrParam ( err . what ( ) ) ) ;
2003-09-06 09:59:02 +00:00
return PS_ERROR ;
}
}
2002-08-04 20:25:10 +00:00
// Fill tables with defaults (if needed) and with instruction strings
2003-04-21 13:32:34 +00:00
// Create language specific resources (currently only dialogs with different fonts)
2003-09-04 18:25:57 +00:00
int num_lang_tables = lang_tables . getlen ( ) / sizeof ( LanguageTable ) ;
2003-04-21 13:32:34 +00:00
// if there is one string table then there is no need for two sets of dialogs
2003-09-04 18:25:57 +00:00
int cur_offset = num_lang_tables = = 1 ? 0 : 100 ;
for ( i = 0 ; i < num_lang_tables ; i + + )
2003-04-21 13:32:34 +00:00
{
2013-03-16 01:28:57 +00:00
// A Unicode-only language is never displayed correctly by ANSI exehead
if ( ! build_unicode & & 1200 = = lt [ i ] . nlf . m_uCodePage )
{
2013-12-08 14:34:38 +00:00
ERROR_MSG ( _T ( " \n Error: Unicode-only language % " ) NPRIs _T ( " cannot be used in ANSI installer! \n " ) , lt [ i ] . nlf . m_szName ) ;
2013-03-16 01:28:57 +00:00
return PS_ERROR ;
}
2003-09-06 09:59:02 +00:00
if ( ( lt [ i ] . nlf . m_szFont & & ! * build_font ) | | lt [ i ] . nlf . m_bRTL )
2003-04-21 13:32:34 +00:00
{
2003-09-04 18:25:57 +00:00
lt [ i ] . dlg_offset = cur_offset ;
2010-03-24 17:22:56 +00:00
TCHAR * font = lt [ i ] . nlf . m_szFont ;
2003-09-06 09:59:02 +00:00
if ( * build_font ) font = 0 ;
2003-04-21 13:32:34 +00:00
try {
init_res_editor ( ) ;
# define ADD_FONT(id) { \
2010-04-12 16:00:17 +00:00
BYTE * dlg = res_editor - > GetResource ( RT_DIALOG , id , NSIS_DEFAULT_LANG ) ; \
2003-04-21 13:32:34 +00:00
if ( dlg ) { \
2010-06-14 10:07:22 +00:00
CDialogTemplate td ( dlg , build_unicode , lt [ i ] . nlf . m_uCodePage ) ; \
2005-05-11 16:20:18 +00:00
res_editor - > FreeResource ( dlg ) ; \
2007-04-11 21:27:19 +00:00
if ( font ) td . SetFont ( font , ( WORD ) lt [ i ] . nlf . m_iFontSize ) ; \
2006-03-04 13:48:43 +00:00
if ( lt [ i ] . nlf . m_bRTL ) { \
td . ConvertToRTL ( ) ; \
DialogItemTemplate * dir = td . GetItem ( IDC_DIR ) ; \
if ( id = = IDD_DIR & & dir ) { \
if ( ( dir - > dwStyle & ES_CENTER ) = = 0 ) dir - > dwStyle ^ = ES_RIGHT ; \
dir - > dwExtStyle & = ~ ( WS_EX_RTLREADING | WS_EX_LEFTSCROLLBAR ) ; \
} \
} \
2003-04-21 13:32:34 +00:00
DWORD dwSize ; \
dlg = td . Save ( dwSize ) ; \
2010-04-12 16:00:17 +00:00
res_editor - > UpdateResource ( RT_DIALOG , id + cur_offset , NSIS_DEFAULT_LANG , dlg , dwSize ) ; \
2014-08-05 13:53:20 +00:00
td . FreeSavedTemplate ( dlg ) ; \
2003-04-21 13:32:34 +00:00
} \
}
# ifdef NSIS_CONFIG_LICENSEPAGE
ADD_FONT ( IDD_LICENSE ) ;
2003-09-04 18:25:57 +00:00
ADD_FONT ( IDD_LICENSE_FSRB ) ;
ADD_FONT ( IDD_LICENSE_FSCB ) ;
2003-04-21 13:32:34 +00:00
# endif
ADD_FONT ( IDD_DIR ) ;
# ifdef NSIS_CONFIG_COMPONENTPAGE
ADD_FONT ( IDD_SELCOM ) ;
# endif
ADD_FONT ( IDD_INST ) ;
ADD_FONT ( IDD_INSTFILES ) ;
# ifdef NSIS_CONFIG_UNINSTALL_SUPPORT
ADD_FONT ( IDD_UNINST ) ;
# endif
# ifdef NSIS_CONFIG_CRC_SUPPORT
ADD_FONT ( IDD_VERIFY ) ;
# endif
2003-05-09 18:33:02 +00:00
# undef ADD_FONT
2003-04-21 13:32:34 +00:00
}
catch ( exception & err ) {
2013-12-08 14:34:38 +00:00
ERROR_MSG ( _T ( " \n Error while applying NLF font/RTL: % " ) NPRIs _T ( " \n " ) , CtoTStrParam ( err . what ( ) ) ) ;
2003-04-21 13:32:34 +00:00
return PS_ERROR ;
}
cur_offset + = 100 ;
}
}
2002-08-03 23:06:10 +00:00
2014-05-13 19:14:31 +00:00
const int orig_uninstall_mode = uninstall_mode ;
2004-01-20 23:20:44 +00:00
2007-04-26 20:49:14 +00:00
set_uninstall_mode ( 0 ) ;
if ( GenerateLangTable ( lt , num_lang_tables ) ! = PS_OK )
return PS_ERROR ;
2002-08-03 23:06:10 +00:00
2003-09-04 18:25:57 +00:00
# ifdef NSIS_CONFIG_UNINSTALL_SUPPORT
set_uninstall_mode ( 1 ) ;
2007-04-26 20:49:14 +00:00
if ( GenerateLangTable ( lt , num_lang_tables ) ! = PS_OK )
return PS_ERROR ;
2003-09-04 18:25:57 +00:00
# endif
2004-01-20 23:20:44 +00:00
2007-04-26 20:49:14 +00:00
set_uninstall_mode ( orig_uninstall_mode ) ;
2010-03-24 17:22:56 +00:00
SCRIPT_MSG ( _T ( " Done! \n " ) ) ;
2002-08-03 23:06:10 +00:00
2003-09-04 18:25:57 +00:00
return PS_OK ;
2002-08-03 23:06:10 +00:00
}
2013-12-08 14:34:38 +00:00
static void CreatePlatformStrfmt ( const TCHAR * templ , TCHAR * out ) {
// NOTE: Only supports plain %s with no options
for ( ; ; out + + )
{
* out = * templ + + ;
if ( ! * out ) break ;
if ( * out = = L ' % ' & & * templ = = L ' s ' )
{
out + + , templ + + ;
2014-05-19 19:23:06 +00:00
size_t cch = my_strncpy ( out , NPRIs , - 1 ) ;
2013-12-08 14:34:38 +00:00
out + = - - cch ; // --cch because for loop does out++
}
}
}
2003-09-04 18:25:57 +00:00
void CEXEBuild : : FillLanguageTable ( LanguageTable * table ) {
for ( int i = 0 ; i < NLF_STRINGS ; i + + ) {
# ifdef NSIS_CONFIG_UNINSTALL_SUPPORT
if ( ! NLFRefs [ i ] . iUnRef & & ! NLFRefs [ i ] . iRef )
continue ;
# else
if ( ! NLFRefs [ i ] . iRef )
continue ;
# endif
2003-09-12 21:40:33 +00:00
else if ( i = = NLF_SPACE_REQ | | i = = NLF_SPACE_AVAIL )
{
if ( no_space_texts )
{
continue ;
}
}
2003-09-04 18:25:57 +00:00
int sn , index ;
int pos = build_langstrings . get ( NLFStrings [ i ] . szLangStringName , & sn , & index ) ;
if ( pos > = 0 ) {
2010-03-24 17:22:56 +00:00
const TCHAR * str = table - > lang_strings - > get ( sn ) ;
2003-09-04 18:25:57 +00:00
if ( ! str | | ! * str ) {
2010-03-24 17:22:56 +00:00
const TCHAR * us = UserInnerStrings . get ( i ) ;
2003-12-17 23:22:14 +00:00
if ( i = = NLF_NAME_DA & & ( ! us | | ! * us ) )
{
// if the user didn't set NLF_NAME_DA we set it to $(^Name)
2010-03-24 17:22:56 +00:00
table - > lang_strings - > set ( sn , _T ( " $(^Name) " ) ) ;
2003-12-17 23:22:14 +00:00
}
2003-09-04 18:25:57 +00:00
if ( us & & * us ) {
2010-03-24 17:22:56 +00:00
table - > lang_strings - > set ( sn , ( TCHAR * ) us ) ;
2003-09-04 18:25:57 +00:00
}
else {
2010-03-24 17:22:56 +00:00
const TCHAR * dstr = table - > nlf . m_szStrings [ i ] ? table - > nlf . m_szStrings [ i ] : NLFStrings [ i ] . szDefault ;
2003-09-12 21:40:33 +00:00
if ( ! dstr )
continue ;
2003-09-04 18:25:57 +00:00
if ( i = = NLF_BRANDING ) {
2013-12-08 14:34:38 +00:00
TCHAR temp [ NSIS_MAX_STRLEN + sizeof ( NSIS_VERSION ) ] , temp2 [ COUNTOF ( temp ) ] ;
CreatePlatformStrfmt ( dstr , temp2 ) ; // Change %s to %ls if required
_stprintf ( temp , temp2 , NSIS_VERSION ) ;
2003-09-04 18:25:57 +00:00
table - > lang_strings - > set ( sn , temp ) ;
continue ;
}
2003-11-12 22:38:46 +00:00
else if ( i = = NLF_FONT )
2003-11-18 22:35:51 +00:00
{
2010-03-24 17:22:56 +00:00
TCHAR * font = * build_font ? build_font : table - > nlf . m_szFont ;
2003-11-18 22:35:51 +00:00
if ( font )
table - > lang_strings - > set ( sn , font ) ;
else
table - > lang_strings - > set ( sn , dstr ) ;
continue ;
}
else if ( i = = NLF_FONTSIZE )
2003-11-12 22:38:46 +00:00
{
2007-04-11 21:27:19 +00:00
WORD font_size = * build_font ? ( WORD ) build_font_size : ( WORD ) table - > nlf . m_iFontSize ;
2003-11-12 22:38:46 +00:00
if ( font_size )
{
2010-03-24 17:22:56 +00:00
TCHAR temp [ 64 ] ;
_stprintf ( temp , _T ( " %d " ) , font_size ) ;
2003-11-12 22:38:46 +00:00
table - > lang_strings - > set ( sn , temp ) ;
}
else
table - > lang_strings - > set ( sn , dstr ) ;
continue ;
}
2003-09-04 18:25:57 +00:00
table - > lang_strings - > set ( sn , dstr ) ;
}
}
2002-08-03 23:06:10 +00:00
}
}
}
2014-05-13 19:14:31 +00:00
void TrimTrailingNewlines ( TCHAR * s ) {
size_t cch = _tcslen ( s ) ;
while ( s [ cch - 1 ] = = _T ( ' \n ' ) | | s [ cch - 1 ] = = _T ( ' \r ' ) )
s [ cch - 1 ] = 0 , - - cch ;
}
2013-03-07 21:25:35 +00:00
static UINT GetNextNLFLine ( NStreamLineReader & lr , TCHAR * Buf , UINT cchBuf ) {
for ( ; ; ) {
UINT err = lr . ReadLine ( Buf , cchBuf ) ;
if ( NStream : : OK ! = err ) {
if ( lr . IsEOF ( ) ) err = NStream : : OK ;
return err ;
2002-08-03 23:06:10 +00:00
}
2013-03-07 21:25:35 +00:00
if ( NStream : : IsNewline ( * Buf , false ) ) continue ;
if ( _T ( ' # ' ) ! = * Buf & & _T ( ' ; ' ) ! = * Buf ) return err ;
2002-08-03 23:06:10 +00:00
}
2013-03-07 21:25:35 +00:00
}
static inline bool GetNextNLFLine ( NStreamLineReader & lr , TCHAR * Buf , UINT cchBuf , UINT & errlr ) {
errlr = GetNextNLFLine ( lr , Buf , cchBuf ) ;
return NStream : : OK = = errlr ;
2002-08-03 23:06:10 +00:00
}
// NSIS Language File parser
2010-03-24 17:22:56 +00:00
LanguageTable * CEXEBuild : : LoadLangFile ( TCHAR * filename ) {
2013-03-07 21:25:35 +00:00
NIStream strm ;
strm . StreamEncoding ( ) . SetCodepage ( NStreamEncoding : : ACP ) ;
if ( ! strm . OpenFileForReading ( filename ) ) {
2013-12-08 14:34:38 +00:00
ERROR_MSG ( _T ( " Error: Can't open language file - \" % " ) NPRIs _T ( " \" ! \n " ) , filename ) ;
2003-09-04 18:25:57 +00:00
return 0 ;
}
2013-03-07 21:25:35 +00:00
NStreamLineReader lr ( strm ) ;
UINT errlr ;
2011-12-05 23:44:26 +00:00
2003-09-04 18:25:57 +00:00
// Check header
2010-03-24 17:22:56 +00:00
TCHAR buf [ NSIS_MAX_STRLEN ] ;
2013-03-10 23:02:09 +00:00
if ( ! GetNextNLFLine ( lr , buf , NSIS_MAX_STRLEN , errlr ) ) {
l_readerr :
ERROR_MSG ( lr . GetErrorMessage ( errlr ) . c_str ( ) ) ;
return 0 ;
}
2010-03-24 17:22:56 +00:00
if ( _tcsncmp ( buf , _T ( " NLF v " ) , 5 ) ) {
ERROR_MSG ( _T ( " Error: Invalid language file. \n " ) ) ;
2003-09-04 18:25:57 +00:00
return 0 ;
}
2010-03-24 17:22:56 +00:00
int nlf_version = _ttoi ( buf + 5 ) ;
2003-09-04 18:25:57 +00:00
if ( nlf_version ! = NLF_VERSION ) {
if ( nlf_version ! = 2 & & nlf_version ! = 3 & & nlf_version ! = 4 & & nlf_version ! = 5 ) {
2010-03-24 17:22:56 +00:00
ERROR_MSG ( _T ( " Error: Language file version doesn't match NSIS version. \n " ) ) ;
2003-09-04 18:25:57 +00:00
return 0 ;
}
}
// Get language ID
2013-03-07 21:25:35 +00:00
if ( ! GetNextNLFLine ( lr , buf , NSIS_MAX_STRLEN , errlr ) ) goto l_readerr ;
2010-03-24 17:22:56 +00:00
LANGID lang_id = _ttoi ( buf ) ;
2003-09-04 18:25:57 +00:00
// Get appropriate table
LanguageTable * table = GetLangTable ( lang_id ) ;
2013-03-07 21:25:35 +00:00
if ( ! table ) return 0 ;
2003-09-04 18:25:57 +00:00
NLF * nlf = & table - > nlf ;
if ( nlf - > m_bLoaded ) {
2010-03-24 17:22:56 +00:00
ERROR_MSG ( _T ( " Error: can't load same language file twice. \n " ) ) ;
2003-09-04 18:25:57 +00:00
return 0 ;
}
2002-08-03 23:06:10 +00:00
2003-04-21 13:32:34 +00:00
// Generate language name
2013-03-07 21:25:35 +00:00
TCHAR * p , * p2 , * p3 , t = 0 ;
2003-04-21 13:32:34 +00:00
2010-03-24 17:22:56 +00:00
p = _tcsrchr ( filename , _T ( ' . ' ) ) ;
2003-09-06 09:59:02 +00:00
if ( p ) {
2003-04-21 13:32:34 +00:00
t = * p ;
* p = 0 ;
}
2013-03-07 21:25:35 +00:00
p2 = _tcsrchr ( filename , _T ( ' \\ ' ) ) , p3 = _tcsrchr ( filename , _T ( ' / ' ) ) ;
if ( p3 > p2 ) p2 = p3 ;
2003-09-06 09:59:02 +00:00
if ( p2 ) {
2003-04-21 13:32:34 +00:00
p2 + + ;
2010-04-13 16:14:16 +00:00
nlf - > m_szName = ( TCHAR * ) malloc ( ( _tcslen ( p2 ) + 1 ) * sizeof ( TCHAR ) ) ;
2010-03-24 17:22:56 +00:00
_tcscpy ( nlf - > m_szName , p2 ) ;
2003-04-21 13:32:34 +00:00
}
2003-09-06 09:59:02 +00:00
else {
2010-04-13 16:14:16 +00:00
nlf - > m_szName = ( TCHAR * ) malloc ( ( _tcslen ( filename ) + 1 ) * sizeof ( TCHAR ) ) ;
2010-03-24 17:22:56 +00:00
_tcscpy ( nlf - > m_szName , filename ) ;
2003-04-21 13:32:34 +00:00
}
if ( p ) * p = t ;
2003-09-06 09:59:02 +00:00
if ( nlf_version ! = NLF_VERSION ) {
2017-04-25 13:09:41 +00:00
warning_fl ( DW_NLF_OLDVERSION , _T ( " % " ) NPRIs _T ( " language file version doesn't match. Using default English texts for missing strings. " ) , nlf - > m_szName ) ;
2003-03-26 18:18:55 +00:00
}
2002-08-03 23:06:10 +00:00
2007-04-14 22:30:31 +00:00
// set ^Language
2010-03-29 15:32:24 +00:00
nlf - > m_szStrings [ NLF_LANGUAGE ] = _tcsdup ( nlf - > m_szName ) ;
2007-04-14 22:30:31 +00:00
2014-02-08 00:13:52 +00:00
size_t temp ;
2003-04-21 13:32:34 +00:00
// Get font
2013-03-07 21:25:35 +00:00
if ( ! GetNextNLFLine ( lr , buf , NSIS_MAX_STRLEN , errlr ) ) goto l_readerr ;
2003-09-06 09:59:02 +00:00
if ( ! nlf - > m_szFont ) {
2014-05-13 19:14:31 +00:00
TrimTrailingNewlines ( buf ) ;
2010-03-24 17:22:56 +00:00
if ( buf [ 0 ] ! = _T ( ' - ' ) | | buf [ 1 ] ! = 0 ) {
2010-04-13 16:14:16 +00:00
nlf - > m_szFont = ( TCHAR * ) malloc ( ( _tcslen ( buf ) + 1 ) * sizeof ( TCHAR ) ) ;
2010-03-24 17:22:56 +00:00
_tcscpy ( nlf - > m_szFont , buf ) ;
2003-09-06 09:59:02 +00:00
}
2003-04-21 13:32:34 +00:00
}
2013-03-07 21:25:35 +00:00
if ( ! GetNextNLFLine ( lr , buf , NSIS_MAX_STRLEN , errlr ) ) goto l_readerr ;
2003-09-06 09:59:02 +00:00
if ( ! nlf - > m_iFontSize ) {
2010-03-24 17:22:56 +00:00
if ( buf [ 0 ] ! = _T ( ' - ' ) | | buf [ 1 ] ! = 0 ) {
nlf - > m_iFontSize = _ttoi ( buf ) ;
2003-09-06 09:59:02 +00:00
}
2003-04-21 13:32:34 +00:00
}
// Get code page
2013-03-16 01:28:57 +00:00
bool isnlfdataucp = false ; // Unicode-only language?
2017-04-14 14:17:39 +00:00
nlf - > m_uCodePage = NSISRT_GetASCIICodepage ( ) ;
2013-03-07 21:25:35 +00:00
if ( ! GetNextNLFLine ( lr , buf , NSIS_MAX_STRLEN , errlr ) ) goto l_readerr ;
2014-05-13 19:14:31 +00:00
TrimTrailingNewlines ( buf ) ;
2010-03-24 17:22:56 +00:00
if ( buf [ 0 ] ! = _T ( ' - ' ) | | buf [ 1 ] ! = 0 ) {
nlf - > m_uCodePage = _ttoi ( buf ) ;
2013-03-16 01:28:57 +00:00
isnlfdataucp = NStreamEncoding : : IsUnicodeCodepage ( nlf - > m_uCodePage ) ;
if ( isnlfdataucp & & 1200 ! = nlf - > m_uCodePage )
{
ERROR_MSG ( _T ( " Error: Unicode-only language files must use codepage 1200! \n " ) ) ;
return 0 ;
}
2014-05-13 19:14:31 +00:00
if ( ( unsigned ) nlf - > m_uCodePage < = 1 & & ! lr . IsUnicode ( ) ) // Warn if someone uses a system specific codepage
{
2017-04-25 13:09:41 +00:00
warning_fl ( DW_NLF_SYSCP , _T ( " % " ) NPRIs _T ( " language file uses the system default codepage! " ) , nlf - > m_szName ) ;
2014-05-13 19:14:31 +00:00
}
2013-03-16 01:28:57 +00:00
if ( CP_ACP ! = nlf - > m_uCodePage & & ! isnlfdataucp & & ! IsValidCodePage ( nlf - > m_uCodePage ) )
2013-03-07 21:25:35 +00:00
{
2017-04-25 13:09:41 +00:00
warning_fl ( DW_NLF_UNSUPPORTED_CP , _T ( " % " ) NPRIs _T ( " language file uses a codepage (%d) that is not supported on this system, using ACP! " ) , nlf - > m_szName , nlf - > m_uCodePage ) ;
2003-09-04 18:25:57 +00:00
nlf - > m_uCodePage = CP_ACP ;
2013-03-07 21:25:35 +00:00
}
2003-04-21 13:32:34 +00:00
}
2013-03-16 01:28:57 +00:00
// SVN is not a big fan of UTF16 so we should always use UTF8SIG
if ( isnlfdataucp & & ! lr . StreamEncoding ( ) . IsUTF8 ( ) )
2010-05-28 13:10:16 +00:00
{
2017-04-25 13:09:41 +00:00
warning_fl ( DW_NLF_NOT_PREFERRED_ENC , _T ( " % " ) NPRIs _T ( " Unicode language file is not UTF8SIG. " ) , nlf - > m_szName ) ;
2013-03-16 01:28:57 +00:00
}
2013-03-07 21:25:35 +00:00
2014-05-13 19:14:31 +00:00
# ifdef _UNICODE
2013-03-16 01:28:57 +00:00
if ( ! lr . IsUnicode ( ) )
{
2013-03-07 21:25:35 +00:00
if ( nlf - > m_szFont )
{
2014-05-13 19:14:31 +00:00
// Convert font name now that we know the codepage
2013-03-07 21:25:35 +00:00
TCHAR * oldfont = nlf - > m_szFont ;
2014-05-13 19:14:31 +00:00
nlf - > m_szFont = _tcsdup ( CtoTString2 ( TtoCString ( oldfont ) , nlf - > m_uCodePage ) ) ; // BUGBUG: Depends on lossless ACP -> TCHAR -> NLF CP -> TCHAR conversion!
2013-03-07 21:25:35 +00:00
free ( oldfont ) ;
2011-12-07 08:18:41 +00:00
}
2014-05-13 19:14:31 +00:00
lr . StreamEncoding ( ) . SetCodepage ( nlf - > m_uCodePage ) ; // Read the rest of this NLF file with the correct MBCS > TCHAR conversion
2010-05-28 13:10:16 +00:00
}
2014-05-13 19:14:31 +00:00
# endif
2010-05-28 13:10:16 +00:00
2003-09-04 18:25:57 +00:00
// Get RTL setting
2013-03-07 21:25:35 +00:00
if ( ! GetNextNLFLine ( lr , buf , NSIS_MAX_STRLEN , errlr ) ) goto l_readerr ;
nlf - > m_szStrings [ NLF_RTL ] = ( TCHAR * ) malloc ( 2 * sizeof ( TCHAR ) ) ;
2003-09-04 18:25:57 +00:00
nlf - > m_bRTL = false ;
2010-03-24 17:22:56 +00:00
if ( buf [ 0 ] = = _T ( ' R ' ) & & buf [ 1 ] = = _T ( ' T ' ) & & buf [ 2 ] = = _T ( ' L ' ) & & ( ! buf [ 3 ] | | buf [ 3 ] = = _T ( ' \r ' ) | | buf [ 3 ] = = _T ( ' \n ' ) ) ) {
2003-09-04 18:25:57 +00:00
nlf - > m_bRTL = true ;
}
2013-03-07 21:25:35 +00:00
_tcscpy ( nlf - > m_szStrings [ NLF_RTL ] , nlf - > m_bRTL ? _T ( " 1 " ) : _T ( " 0 " ) ) ;
2003-03-26 18:18:55 +00:00
2003-09-04 18:25:57 +00:00
// Read strings
2005-10-18 13:12:47 +00:00
for ( int i = 0 ; i < NLF_STRINGS_NO_SPECIAL ; i + + ) {
2003-04-21 13:32:34 +00:00
2003-09-04 18:25:57 +00:00
// skip virtual strings
if ( ! NLFStrings [ i ] . szDefault )
continue ;
2004-01-20 23:20:44 +00:00
2003-09-04 18:25:57 +00:00
// Fill in for missing strings
// 0 will mean default will be used from NLFStrings
switch ( i ) {
case NLF_BTN_LICENSE_AGREE :
case NLF_BTN_LICENSE_DISAGREE :
if ( nlf_version > = 3 ) break ;
case NLF_LOG_INSTALL_PROCESS :
case NLF_BYTE :
case NLF_KILO :
case NLF_MEGA :
case NLF_GIGA :
case NLF_REGISTERING :
case NLF_UNREGISTERING :
if ( nlf_version > = 4 ) break ;
case NLF_FILE_ERROR_NOIGNORE :
if ( nlf_version > = 5 ) break ;
case NLF_USUBCAPTION_OPTIONS :
case NLF_USUBCAPTION_DIR :
case NLF_CLICK_NEXT :
case NLF_CLICK_INSTALL :
case NLF_CLICK_UNINSTALL :
case NLF_LICENSE_TEXT :
case NLF_LICENSE_TEXT_FSCB :
case NLF_LICENSE_TEXT_FSRB :
case NLF_ULICENSE_TEXT :
case NLF_ULICENSE_TEXT_FSCB :
case NLF_ULICENSE_TEXT_FSRB :
case NLF_COMP_TEXT :
case NLF_UCOMP_TEXT :
case NLF_UCOMP_SUBTEXT1 :
case NLF_UCOMP_SUBTEXT1_NO_INST_TYPES :
case NLF_UCOMP_SUBTEXT2 :
case NLF_DIR_TEXT :
case NLF_DIR_BROWSETEXT :
case NLF_UDIR_TEXT :
case NLF_UDIR_SUBTEXT :
case NLF_UDIR_BROWSETEXT :
case NLF_UNINST_TEXT :
if ( nlf_version > = 6 ) break ;
nlf - > m_szStrings [ i ] = 0 ;
2014-05-13 19:14:31 +00:00
continue ; // This applies to the for loop and not this switch!
2003-05-26 17:55:15 +00:00
}
2013-03-07 21:25:35 +00:00
errlr = GetNextNLFLine ( lr , buf , NSIS_MAX_STRLEN ) ;
2010-04-13 16:14:16 +00:00
if ( _tcslen ( buf ) = = NSIS_MAX_STRLEN - 1 ) {
2013-12-08 14:34:38 +00:00
ERROR_MSG ( _T ( " Error: String too long (string #%d - \" % " ) NPRIs _T ( " \" ) \n " ) , i , NLFStrings [ i ] . szLangStringName ) ;
2003-09-04 18:25:57 +00:00
return 0 ;
2002-08-03 23:06:10 +00:00
}
2013-03-07 21:25:35 +00:00
if ( NStream : : OK ! = errlr ) goto l_readerr ;
2010-04-13 16:14:16 +00:00
temp = _tcslen ( buf ) ;
2014-05-13 19:14:31 +00:00
// Not using TrimTrailingNewlines because we need temp to be correct for the quote trimming
2010-03-24 17:22:56 +00:00
while ( buf [ temp - 1 ] = = _T ( ' \n ' ) | | buf [ temp - 1 ] = = _T ( ' \r ' ) ) {
2003-09-04 18:25:57 +00:00
buf [ - - temp ] = 0 ;
}
2010-03-24 17:22:56 +00:00
TCHAR * in = buf ;
2003-09-04 18:25:57 +00:00
// trim quotes
2010-03-24 17:22:56 +00:00
if ( buf [ 0 ] = = _T ( ' " ' ) & & buf [ temp - 1 ] = = _T ( ' " ' ) ) {
2003-09-04 18:25:57 +00:00
in + + ;
buf [ - - temp ] = 0 ;
2002-08-03 23:06:10 +00:00
}
2003-09-04 18:25:57 +00:00
2010-03-24 17:22:56 +00:00
nlf - > m_szStrings [ i ] = ( TCHAR * ) malloc ( ( temp + 1 ) * sizeof ( TCHAR ) ) ;
TCHAR * out ;
2004-03-12 20:43:54 +00:00
for ( out = nlf - > m_szStrings [ i ] ; * in ; in + + , out + + ) {
2010-03-24 17:22:56 +00:00
if ( * in = = _T ( ' \\ ' ) ) {
2002-08-06 11:24:49 +00:00
in + + ;
switch ( * in ) {
2010-03-24 17:22:56 +00:00
case _T ( ' n ' ) :
* out = _T ( ' \n ' ) ;
2002-08-06 11:24:49 +00:00
break ;
2010-03-24 17:22:56 +00:00
case _T ( ' r ' ) :
* out = _T ( ' \r ' ) ;
2002-08-06 11:24:49 +00:00
break ;
2010-03-24 17:22:56 +00:00
case _T ( ' t ' ) :
* out = _T ( ' \t ' ) ;
2002-08-06 11:24:49 +00:00
break ;
default :
2010-03-24 17:22:56 +00:00
* out + + = _T ( ' \\ ' ) ;
2002-08-06 11:24:49 +00:00
* out = * in ;
}
}
else * out = * in ;
}
* out = 0 ;
2002-08-03 23:06:10 +00:00
}
2003-09-04 18:25:57 +00:00
nlf - > m_bLoaded = true ;
return table ;
2002-08-03 23:06:10 +00:00
}
2003-09-04 18:25:57 +00:00
void CEXEBuild : : DeleteLangTable ( LanguageTable * table ) {
2003-09-12 11:16:33 +00:00
if ( table - > nlf . m_szName )
free ( table - > nlf . m_szName ) ;
if ( table - > nlf . m_szFont )
free ( table - > nlf . m_szFont ) ;
delete table - > lang_strings ;
2002-08-03 23:06:10 +00:00
for ( int i = 0 ; i < NLF_STRINGS ; i + + ) {
2003-09-12 11:16:33 +00:00
if ( table - > nlf . m_szStrings [ i ] )
free ( table - > nlf . m_szStrings [ i ] ) ;
2002-08-03 23:06:10 +00:00
}
2004-01-20 23:20:44 +00:00
}