2006-10-28 19:45:02 +00:00
/*
* lang . cpp
*
* This file is a part of NSIS .
*
2009-02-01 14:44:30 +00:00
* Copyright ( C ) 1999 - 2009 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"
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 } ,
{ _T ( " ^Kilo " ) , _T ( " K " ) , BOTH_STATIC } ,
{ _T ( " ^Mega " ) , _T ( " M " ) , BOTH_STATIC } ,
{ _T ( " ^Giga " ) , _T ( " G " ) , BOTH_STATIC } ,
{ _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
// ==============
LangStringList : : LangStringList ( ) {
count = 0 ;
}
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 ;
( ( struct langstring * ) gr . get ( ) ) [ pos ] . sn = count ;
if ( sn ) * sn = count ;
count + + ;
( ( struct langstring * ) gr . get ( ) ) [ pos ] . index = - 1 ;
( ( struct langstring * ) gr . get ( ) ) [ pos ] . uindex = - 1 ;
( ( struct langstring * ) gr . get ( ) ) [ pos ] . process = 1 ;
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 ;
if ( index ) * index = ( ( struct langstring * ) gr . get ( ) ) [ v ] . index ;
if ( uindex ) * uindex = ( ( struct langstring * ) gr . get ( ) ) [ v ] . uindex ;
if ( sn ) * sn = ( ( struct langstring * ) gr . get ( ) ) [ v ] . sn ;
if ( process ) * process = ( ( struct langstring * ) gr . get ( ) ) [ v ] . process ;
return v ;
}
void LangStringList : : set ( int pos , int index /*=-1*/ , int uindex /*=-1*/ , int process /*=-1*/ )
{
if ( ( unsigned int ) pos > ( gr . getlen ( ) / sizeof ( struct langstring ) ) )
return ;
struct langstring * data = ( struct langstring * ) gr . get ( ) ;
if ( index > = 0 )
data [ pos ] . index = index ;
if ( uindex > = 0 )
data [ pos ] . uindex = uindex ;
if ( process > = 0 )
data [ pos ] . process = process ;
}
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
{
set ( get ( name ) , index , uindex , process ) ;
}
2010-03-24 17:22:56 +00:00
const TCHAR * LangStringList : : pos2name ( int pos )
2004-10-12 21:22:55 +00:00
{
struct langstring * data = ( struct langstring * ) gr . get ( ) ;
if ( ( unsigned int ) pos > ( gr . getlen ( ) / sizeof ( struct langstring ) ) )
return 0 ;
2010-03-24 17:22:56 +00:00
return ( ( const TCHAR * ) 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
{
if ( ( unsigned int ) name > ( unsigned int ) strings . getlen ( ) )
return 0 ;
2010-03-24 17:22:56 +00:00
return ( const TCHAR * ) strings . get ( ) + name ;
2004-10-12 21:22:55 +00:00
}
int LangStringList : : getnum ( )
{
return gr . getlen ( ) / sizeof ( struct langstring ) ;
}
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 ;
sortbuf . resize ( 0 ) ;
sortbuf . add ( gr . get ( ) , gr . getlen ( ) ) ;
* num = sortbuf . getlen ( ) / sizeof ( struct langstring ) ;
qsort ( sortbuf . get ( ) , * num , sizeof ( struct langstring ) , compare_index ) ;
return ( struct langstring * ) sortbuf . get ( ) ;
}
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 ;
sortbuf . resize ( 0 ) ;
sortbuf . add ( gr . get ( ) , gr . getlen ( ) ) ;
* num = sortbuf . getlen ( ) / sizeof ( struct langstring ) ;
qsort ( sortbuf . get ( ) , * num , sizeof ( struct langstring ) , compare_uindex ) ;
return ( struct langstring * ) sortbuf . get ( ) ;
}
// ============
// StringsArray
// ============
StringsArray : : StringsArray ( )
{
offsets . set_zeroing ( 1 ) ;
2010-03-24 17:22:56 +00:00
strings . add ( _T ( " " ) , sizeof ( _T ( " " ) ) ) ;
2004-10-12 21:22:55 +00:00
}
void StringsArray : : resize ( int num )
{
offsets . resize ( num * sizeof ( int ) ) ;
}
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 ;
if ( idx > = ( int ) ( offsets . getlen ( ) / sizeof ( int ) ) )
resize ( idx + 1 ) ;
int old = ( ( int * ) offsets . get ( ) ) [ idx ] ;
2010-04-12 16:00:17 +00:00
( ( int * ) offsets . get ( ) ) [ idx ] = strings . add ( str , ( _tcsclen ( 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
{
if ( ( unsigned int ) idx > = ( offsets . getlen ( ) / sizeof ( int ) ) )
return 0 ;
2010-03-24 17:22:56 +00:00
return ( const TCHAR * ) strings . get ( ) + ( ( int * ) 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 {
if ( codepage )
* codepage = 1252 ; // English US
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
}
}
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
// passed in proces 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.
int CEXEBuild : : SetLangString ( TCHAR * name , LANGID lang , TCHAR * str ) {
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 ;
int pos = build_langstrings . get ( name , & sn ) ;
if ( pos < 0 )
pos = build_langstrings . add ( name , & sn ) ;
2002-09-29 20:25:15 +00:00
2010-03-24 17:22:56 +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 ;
}
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.
int CEXEBuild : : SetInnerString ( int id , TCHAR * str ) {
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 )
2010-03-24 17:22:56 +00:00
warning ( _T ( " LangString \" %s \" is not set in language table of language %s " ) , lsn , lt [ i ] . nlf . m_szName ) ;
2007-04-26 20:49:14 +00:00
else
2010-03-24 17:22:56 +00:00
warning ( _T ( " LangString \" %s \" 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 ] ;
_stprintf ( fn , _T ( " LangString %s " ) , 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 ( ) ;
int langstring_num ;
if ( ! uninstall_mode )
langstring_num = build_langstring_num ;
else
langstring_num = ubuild_langstring_num ;
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 + + )
{
int index ;
if ( ! uninstall_mode )
index = lang_strings [ l ] . index ;
else
index = lang_strings [ l ] . uindex ;
if ( lang_strings [ l ] . index = = j )
{
name = build_langstrings . offset2name ( lang_strings [ l ] . name ) ;
}
}
2010-03-24 17:22:56 +00:00
ERROR_MSG ( _T ( " Error: LangString %s is recursive! \n " ) , name ) ;
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 ) { \
CDialogTemplate td ( dlg ) ; \
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 ) ; \
2005-05-11 16:20:18 +00:00
delete [ ] 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 ) {
2010-03-29 15:32:24 +00:00
ERROR_MSG ( _T ( " \n Error while applying font: %s \n " ) , CtoTString ( 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
{
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 ) { \
2003-09-04 18:25:57 +00:00
CDialogTemplate td ( dlg , 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 ) ; \
2005-05-11 16:20:18 +00:00
delete [ ] 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 ) {
2010-03-29 15:32:24 +00:00
ERROR_MSG ( _T ( " \n Error while applying NLF font/RTL: %s \n " ) , CtoTString ( err . what ( ) ) ) ;
2003-04-21 13:32:34 +00:00
return PS_ERROR ;
}
cur_offset + = 100 ;
}
}
2002-08-03 23:06:10 +00:00
2007-04-26 20:49:14 +00:00
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
}
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 ) {
2010-03-24 17:22:56 +00:00
TCHAR temp [ NSIS_MAX_STRLEN + sizeof ( NSIS_VERSION ) ] ;
_stprintf ( temp , dstr , 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
}
}
}
2010-03-24 17:22:56 +00:00
TCHAR SkipComments ( FILE * f ) {
2007-04-11 21:27:19 +00:00
int c ;
2010-03-24 17:22:56 +00:00
while ( ( c = _fgettc ( f ) ) ) {
while ( c = = _T ( ' \n ' ) | | c = = _T ( ' \r ' ) ) {
c = _fgettc ( f ) ; // Skip empty lines
2002-08-03 23:06:10 +00:00
}
2010-03-24 17:22:56 +00:00
if ( c = = _T ( ' # ' ) | | c = = _T ( ' ; ' ) ) {
while ( ( c = _fgettc ( f ) ) ) {
if ( c = = _T ( ' \n ' ) ) break ;
2002-08-03 23:06:10 +00:00
}
}
else break ;
}
2010-03-24 17:22:56 +00:00
return ( TCHAR ) c ;
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 ) {
2010-03-29 15:32:24 +00:00
FILE * f = FOPENTEXT ( filename , _T ( " r " ) ) ;
2003-09-04 18:25:57 +00:00
if ( ! f ) {
2010-03-24 17:22:56 +00:00
ERROR_MSG ( _T ( " Error: Can't open language file - \" %s \" ! \n " ) , filename ) ;
2003-09-04 18:25:57 +00:00
return 0 ;
}
// Check header
2010-03-24 17:22:56 +00:00
TCHAR buf [ NSIS_MAX_STRLEN ] ;
2003-09-04 18:25:57 +00:00
buf [ 0 ] = SkipComments ( f ) ;
2010-03-24 17:22:56 +00:00
_fgetts ( buf + 1 , NSIS_MAX_STRLEN , f ) ;
2003-09-04 18:25:57 +00:00
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
buf [ 0 ] = SkipComments ( f ) ;
2010-03-24 17:22:56 +00:00
_fgetts ( buf + 1 , NSIS_MAX_STRLEN , f ) ;
LANGID lang_id = _ttoi ( buf ) ;
2003-09-04 18:25:57 +00:00
// Get appropriate table
LanguageTable * table = GetLangTable ( lang_id ) ;
if ( ! table )
return 0 ;
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
2010-03-24 17:22:56 +00:00
TCHAR * p , * p2 , 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 ;
}
2010-03-24 17:22:56 +00:00
p2 = _tcsrchr ( filename , _T ( ' \\ ' ) ) ;
2003-09-06 09:59:02 +00:00
if ( p2 ) {
2003-04-21 13:32:34 +00:00
p2 + + ;
2010-03-24 17:22:56 +00:00
nlf - > m_szName = ( TCHAR * ) malloc ( ( _tcsclen ( p2 ) + 1 ) * sizeof ( TCHAR ) ) ;
_tcscpy ( nlf - > m_szName , p2 ) ;
2003-04-21 13:32:34 +00:00
}
2003-09-06 09:59:02 +00:00
else {
2010-03-24 17:22:56 +00:00
nlf - > m_szName = ( TCHAR * ) malloc ( ( _tcsclen ( filename ) + 1 ) * sizeof ( TCHAR ) ) ;
_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 ) {
2010-03-24 17:22:56 +00:00
warning_fl ( _T ( " %s 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
2003-04-21 13:32:34 +00:00
int temp ;
// Get font
buf [ 0 ] = SkipComments ( f ) ;
2010-03-24 17:22:56 +00:00
_fgetts ( buf + 1 , NSIS_MAX_STRLEN , f ) ;
2003-09-06 09:59:02 +00:00
if ( ! nlf - > m_szFont ) {
2010-03-24 17:22:56 +00:00
temp = _tcsclen ( buf ) ;
while ( buf [ temp - 1 ] = = _T ( ' \n ' ) | | buf [ temp - 1 ] = = _T ( ' \r ' ) ) {
2003-09-06 09:59:02 +00:00
buf [ temp - 1 ] = 0 ;
temp - - ;
}
2010-03-24 17:22:56 +00:00
if ( buf [ 0 ] ! = _T ( ' - ' ) | | buf [ 1 ] ! = 0 ) {
nlf - > m_szFont = ( TCHAR * ) malloc ( ( _tcsclen ( buf ) + 1 ) * sizeof ( TCHAR ) ) ;
_tcscpy ( nlf - > m_szFont , buf ) ;
2003-09-06 09:59:02 +00:00
}
2003-04-21 13:32:34 +00:00
}
buf [ 0 ] = SkipComments ( f ) ;
2010-03-24 17:22:56 +00:00
_fgetts ( buf + 1 , NSIS_MAX_STRLEN , f ) ;
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
2003-09-04 18:25:57 +00:00
nlf - > m_uCodePage = CP_ACP ;
2003-04-21 13:32:34 +00:00
buf [ 0 ] = SkipComments ( f ) ;
2010-03-24 17:22:56 +00:00
_fgetts ( buf + 1 , NSIS_MAX_STRLEN , f ) ;
if ( buf [ 0 ] ! = _T ( ' - ' ) | | buf [ 1 ] ! = 0 ) {
nlf - > m_uCodePage = _ttoi ( buf ) ;
2003-09-04 18:25:57 +00:00
if ( ! IsValidCodePage ( nlf - > m_uCodePage ) )
nlf - > m_uCodePage = CP_ACP ;
2003-04-21 13:32:34 +00:00
}
2003-09-04 18:25:57 +00:00
// Get RTL setting
2010-03-24 17:22:56 +00:00
nlf - > m_szStrings [ NLF_RTL ] = ( TCHAR * ) malloc ( 2 * sizeof ( TCHAR ) ) ;
2003-09-04 18:25:57 +00:00
nlf - > m_bRTL = false ;
buf [ 0 ] = SkipComments ( f ) ;
2010-03-24 17:22:56 +00:00
_fgetts ( buf + 1 , NSIS_MAX_STRLEN , f ) ;
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 ;
2010-03-24 17:22:56 +00:00
_tcscpy ( nlf - > m_szStrings [ NLF_RTL ] , _T ( " 1 " ) ) ;
2003-09-04 18:25:57 +00:00
}
else {
2010-03-24 17:22:56 +00:00
_tcscpy ( nlf - > m_szStrings [ NLF_RTL ] , _T ( " 0 " ) ) ;
2003-09-04 18:25:57 +00:00
}
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 ;
2003-05-26 17:55:15 +00:00
continue ;
}
2003-04-21 13:32:34 +00:00
buf [ 0 ] = SkipComments ( f ) ;
2010-03-24 17:22:56 +00:00
_fgetts ( buf + 1 , NSIS_MAX_STRLEN , f ) ;
if ( _tcsclen ( buf ) = = NSIS_MAX_STRLEN - 1 ) {
ERROR_MSG ( _T ( " Error: String too long (string #%d - \" %s \" ) " ) , i , NLFStrings [ i ] . szLangStringName ) ;
2003-09-04 18:25:57 +00:00
return 0 ;
2002-08-03 23:06:10 +00:00
}
2010-03-24 17:22:56 +00:00
temp = _tcsclen ( buf ) ;
2003-09-04 18:25:57 +00:00
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
}
fclose ( f ) ;
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
}