Unicode port: Generate Unicode LangStrings even if source was an ANSI file
git-svn-id: https://svn.code.sf.net/p/nsis/code/NSIS/trunk@6093 212acab6-be3b-0410-9dea-997c60f758d6
This commit is contained in:
parent
e097a25855
commit
90e05acdd3
8 changed files with 70 additions and 24 deletions
5
INSTALL
5
INSTALL
|
@ -25,6 +25,11 @@ This is a trimmed version of Appendix "Building NSIS" of the documentation.
|
||||||
|
|
||||||
set ZLIB_W32=C:\Dev\zlib-1.2.4
|
set ZLIB_W32=C:\Dev\zlib-1.2.4
|
||||||
|
|
||||||
|
- For Unicode version of NSIS
|
||||||
|
|
||||||
|
* type:
|
||||||
|
scons UNICODE=yes
|
||||||
|
|
||||||
- Installing
|
- Installing
|
||||||
|
|
||||||
* type:
|
* type:
|
||||||
|
|
|
@ -95,6 +95,7 @@ CEXEBuild::CEXEBuild() :
|
||||||
linecnt = 0;
|
linecnt = 0;
|
||||||
fp = 0;
|
fp = 0;
|
||||||
curfilename = 0;
|
curfilename = 0;
|
||||||
|
curfile_unicode = FALSE;
|
||||||
|
|
||||||
display_info=1;
|
display_info=1;
|
||||||
display_script=1;
|
display_script=1;
|
||||||
|
|
|
@ -107,7 +107,7 @@ class CEXEBuild {
|
||||||
|
|
||||||
// process a script (you can process as many scripts as you want,
|
// process a script (you can process as many scripts as you want,
|
||||||
// it is as if they are concatenated)
|
// it is as if they are concatenated)
|
||||||
int process_script(FILE *fp, const TCHAR *curfilename);
|
int process_script(FILE *filepointer, const TCHAR *filename, BOOL unicode);
|
||||||
int process_oneline(TCHAR *line, const TCHAR *curfilename, int lineptr);
|
int process_oneline(TCHAR *line, const TCHAR *curfilename, int lineptr);
|
||||||
|
|
||||||
// you only get to call write_output once, so use it wisely.
|
// you only get to call write_output once, so use it wisely.
|
||||||
|
@ -125,6 +125,7 @@ class CEXEBuild {
|
||||||
|
|
||||||
int linecnt;
|
int linecnt;
|
||||||
const TCHAR *curfilename;
|
const TCHAR *curfilename;
|
||||||
|
BOOL curfile_unicode;
|
||||||
FILE *fp;
|
FILE *fp;
|
||||||
|
|
||||||
HWND notify_hwnd;
|
HWND notify_hwnd;
|
||||||
|
@ -166,7 +167,7 @@ class CEXEBuild {
|
||||||
int parseScript();
|
int parseScript();
|
||||||
int includeScript(TCHAR *f);
|
int includeScript(TCHAR *f);
|
||||||
int MacroExists(const TCHAR *macroname);
|
int MacroExists(const TCHAR *macroname);
|
||||||
int LoadLicenseFile(TCHAR *file, TCHAR** pdata, LineParser &line);
|
int LoadLicenseFile(TCHAR *file, TCHAR** pdata, LineParser &line, BOOL* unicode);
|
||||||
#ifdef NSIS_FIX_DEFINES_IN_STRINGS
|
#ifdef NSIS_FIX_DEFINES_IN_STRINGS
|
||||||
void ps_addtoline(const TCHAR *str, GrowBuf &linedata, StringList &hist, bool bIgnoreDefines = false);
|
void ps_addtoline(const TCHAR *str, GrowBuf &linedata, StringList &hist, bool bIgnoreDefines = false);
|
||||||
#else
|
#else
|
||||||
|
@ -319,7 +320,7 @@ class CEXEBuild {
|
||||||
* return aPS_ERROR. If this function call is overwriting a set user string,
|
* return aPS_ERROR. If this function call is overwriting a set user string,
|
||||||
* this will return a PS_WARNING.
|
* this will return a PS_WARNING.
|
||||||
*/
|
*/
|
||||||
int SetLangString(TCHAR *name, LANGID lang, TCHAR *str);
|
int SetLangString(TCHAR *name, LANGID lang, TCHAR *str, BOOL unicode);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Sets the user string to the specific NLF_STRINGS id.
|
* Sets the user string to the specific NLF_STRINGS id.
|
||||||
|
|
|
@ -478,7 +478,7 @@ int CEXEBuild::DefineInnerLangString(int id, int process/*=-1*/) {
|
||||||
// @return If the language id, the variable name or string is invalid, it will
|
// @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,
|
// return a PS_ERROR. If this function call is overwriting a set user string,
|
||||||
// this will return a PS_WARNING.
|
// this will return a PS_WARNING.
|
||||||
int CEXEBuild::SetLangString(TCHAR *name, LANGID lang, TCHAR *str) {
|
int CEXEBuild::SetLangString(TCHAR *name, LANGID lang, TCHAR *str, BOOL unicode) {
|
||||||
if (!str || !name) return PS_ERROR;
|
if (!str || !name) return PS_ERROR;
|
||||||
|
|
||||||
LanguageTable *table = GetLangTable(lang);
|
LanguageTable *table = GetLangTable(lang);
|
||||||
|
@ -490,7 +490,7 @@ int CEXEBuild::SetLangString(TCHAR *name, LANGID lang, TCHAR *str) {
|
||||||
if (pos < 0)
|
if (pos < 0)
|
||||||
pos = build_langstrings.add(name, &sn);
|
pos = build_langstrings.add(name, &sn);
|
||||||
|
|
||||||
if (table->lang_strings->set(sn, str))
|
if (table->lang_strings->set(sn, unicode ? str : CtoTString2(TtoCString(str),table->nlf.m_uCodePage)))
|
||||||
return PS_WARNING;
|
return PS_WARNING;
|
||||||
|
|
||||||
return PS_OK;
|
return PS_OK;
|
||||||
|
@ -912,7 +912,8 @@ TCHAR SkipComments(FILE *f) {
|
||||||
|
|
||||||
// NSIS Language File parser
|
// NSIS Language File parser
|
||||||
LanguageTable * CEXEBuild::LoadLangFile(TCHAR *filename) {
|
LanguageTable * CEXEBuild::LoadLangFile(TCHAR *filename) {
|
||||||
FILE *f = FOPENTEXT(filename, "r");
|
BOOL unicode;
|
||||||
|
FILE *f = FOPENTEXT2(filename, "r", &unicode);
|
||||||
if (!f) {
|
if (!f) {
|
||||||
ERROR_MSG(_T("Error: Can't open language file - \"%s\"!\n"),filename);
|
ERROR_MSG(_T("Error: Can't open language file - \"%s\"!\n"),filename);
|
||||||
return 0;
|
return 0;
|
||||||
|
@ -1014,6 +1015,15 @@ LanguageTable * CEXEBuild::LoadLangFile(TCHAR *filename) {
|
||||||
nlf->m_uCodePage = CP_ACP;
|
nlf->m_uCodePage = CP_ACP;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifdef _UNICODE
|
||||||
|
if (!unicode) // convert font name from ANSI to Unicode now that we know the language codepage
|
||||||
|
{
|
||||||
|
TCHAR* str = nlf->m_szFont;
|
||||||
|
nlf->m_szFont = _tcsdup(CtoTString2(TtoCString(str),table->nlf.m_uCodePage));
|
||||||
|
free(str);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
// Get RTL setting
|
// Get RTL setting
|
||||||
nlf->m_szStrings[NLF_RTL] = (TCHAR *)malloc(2*sizeof(TCHAR));
|
nlf->m_szStrings[NLF_RTL] = (TCHAR *)malloc(2*sizeof(TCHAR));
|
||||||
nlf->m_bRTL = false;
|
nlf->m_bRTL = false;
|
||||||
|
@ -1121,6 +1131,14 @@ LanguageTable * CEXEBuild::LoadLangFile(TCHAR *filename) {
|
||||||
else *out = *in;
|
else *out = *in;
|
||||||
}
|
}
|
||||||
*out = 0;
|
*out = 0;
|
||||||
|
#ifdef _UNICODE
|
||||||
|
if (!unicode)
|
||||||
|
{
|
||||||
|
TCHAR* str = nlf->m_szStrings[i];
|
||||||
|
nlf->m_szStrings[i] = _tcsdup(CtoTString2(TtoCString(str),table->nlf.m_uCodePage));
|
||||||
|
free(str);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
fclose(f);
|
fclose(f);
|
||||||
|
|
||||||
|
|
|
@ -197,7 +197,8 @@ static tstring get_home()
|
||||||
|
|
||||||
static int process_config(CEXEBuild& build, tstring& conf)
|
static int process_config(CEXEBuild& build, tstring& conf)
|
||||||
{
|
{
|
||||||
FILE *cfg=FOPENTEXT(conf.c_str(),"rt");
|
BOOL unicode;
|
||||||
|
FILE *cfg=FOPENTEXT2(conf.c_str(),"rt",&unicode);
|
||||||
if (cfg)
|
if (cfg)
|
||||||
{
|
{
|
||||||
if (build.display_script)
|
if (build.display_script)
|
||||||
|
@ -205,7 +206,7 @@ static int process_config(CEXEBuild& build, tstring& conf)
|
||||||
_ftprintf(g_output,_T("Processing config: \n"));
|
_ftprintf(g_output,_T("Processing config: \n"));
|
||||||
fflush(g_output);
|
fflush(g_output);
|
||||||
}
|
}
|
||||||
int ret=build.process_script(cfg,(TCHAR*)conf.c_str());
|
int ret=build.process_script(cfg,(TCHAR*)conf.c_str(),unicode);
|
||||||
fclose(cfg);
|
fclose(cfg);
|
||||||
if (ret != PS_OK && ret != PS_EOF)
|
if (ret != PS_OK && ret != PS_EOF)
|
||||||
{
|
{
|
||||||
|
@ -484,6 +485,7 @@ int _tmain(int argc, TCHAR **argv)
|
||||||
|
|
||||||
{
|
{
|
||||||
TCHAR sfile[1024];
|
TCHAR sfile[1024];
|
||||||
|
BOOL unicode=FALSE;
|
||||||
if (!_tcscmp(argv[argpos],_T("-")) && !in_files)
|
if (!_tcscmp(argv[argpos],_T("-")) && !in_files)
|
||||||
{
|
{
|
||||||
fp=stdin;
|
fp=stdin;
|
||||||
|
@ -492,11 +494,11 @@ int _tmain(int argc, TCHAR **argv)
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
_tcscpy(sfile,argv[argpos]);
|
_tcscpy(sfile,argv[argpos]);
|
||||||
fp=FOPENTEXT(sfile,"rt");
|
fp=FOPENTEXT2(sfile,"rt",&unicode);
|
||||||
if (!fp)
|
if (!fp)
|
||||||
{
|
{
|
||||||
_stprintf(sfile,_T("%s.nsi"),argv[argpos]);
|
_stprintf(sfile,_T("%s.nsi"),argv[argpos]);
|
||||||
fp=FOPENTEXT(sfile,"rt");
|
fp=FOPENTEXT2(sfile,"rt",&unicode);
|
||||||
if (!fp)
|
if (!fp)
|
||||||
{
|
{
|
||||||
if (build.display_errors)
|
if (build.display_errors)
|
||||||
|
@ -522,7 +524,7 @@ int _tmain(int argc, TCHAR **argv)
|
||||||
_ftprintf(g_output,_T("Processing script file: \"%s\"\n"),sfile);
|
_ftprintf(g_output,_T("Processing script file: \"%s\"\n"),sfile);
|
||||||
fflush(g_output);
|
fflush(g_output);
|
||||||
}
|
}
|
||||||
int ret=build.process_script(fp,sfile);
|
int ret=build.process_script(fp,sfile,unicode);
|
||||||
if (fp != stdin) fclose(fp);
|
if (fp != stdin) fclose(fp);
|
||||||
|
|
||||||
if (ret != PS_EOF && ret != PS_OK)
|
if (ret != PS_EOF && ret != PS_OK)
|
||||||
|
|
|
@ -202,11 +202,12 @@ void CEXEBuild::del_date_time_predefines()
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
int CEXEBuild::process_script(FILE *filepointer, const TCHAR *filename)
|
int CEXEBuild::process_script(FILE *filepointer, const TCHAR *filename, BOOL unicode)
|
||||||
{
|
{
|
||||||
linecnt = 0;
|
linecnt = 0;
|
||||||
fp = filepointer;
|
fp = filepointer;
|
||||||
curfilename = filename;
|
curfilename = filename;
|
||||||
|
curfile_unicode = unicode;
|
||||||
|
|
||||||
if (has_called_write_output)
|
if (has_called_write_output)
|
||||||
{
|
{
|
||||||
|
@ -232,6 +233,7 @@ int CEXEBuild::process_script(FILE *filepointer, const TCHAR *filename)
|
||||||
|
|
||||||
fp = 0;
|
fp = 0;
|
||||||
curfilename = 0;
|
curfilename = 0;
|
||||||
|
curfile_unicode = FALSE;
|
||||||
|
|
||||||
if (m_linebuild.getlen())
|
if (m_linebuild.getlen())
|
||||||
{
|
{
|
||||||
|
@ -745,7 +747,8 @@ int CEXEBuild::parseScript()
|
||||||
int CEXEBuild::includeScript(TCHAR *f)
|
int CEXEBuild::includeScript(TCHAR *f)
|
||||||
{
|
{
|
||||||
SCRIPT_MSG(_T("!include: \"%s\"\n"),f);
|
SCRIPT_MSG(_T("!include: \"%s\"\n"),f);
|
||||||
FILE *incfp=FOPENTEXT(f,"rt");
|
BOOL unicode;
|
||||||
|
FILE *incfp=FOPENTEXT2(f,"rt",&unicode);
|
||||||
if (!incfp)
|
if (!incfp)
|
||||||
{
|
{
|
||||||
ERROR_MSG(_T("!include: could not open file: \"%s\"\n"),f);
|
ERROR_MSG(_T("!include: could not open file: \"%s\"\n"),f);
|
||||||
|
@ -765,7 +768,9 @@ int CEXEBuild::includeScript(TCHAR *f)
|
||||||
int last_linecnt=linecnt;
|
int last_linecnt=linecnt;
|
||||||
linecnt=0;
|
linecnt=0;
|
||||||
const TCHAR *last_filename=curfilename;
|
const TCHAR *last_filename=curfilename;
|
||||||
|
BOOL last_unicode=curfile_unicode;
|
||||||
curfilename=f;
|
curfilename=f;
|
||||||
|
curfile_unicode=unicode;
|
||||||
FILE *last_fp=fp;
|
FILE *last_fp=fp;
|
||||||
fp=incfp;
|
fp=incfp;
|
||||||
|
|
||||||
|
@ -787,6 +792,7 @@ int CEXEBuild::includeScript(TCHAR *f)
|
||||||
|
|
||||||
linecnt=last_linecnt;
|
linecnt=last_linecnt;
|
||||||
curfilename=last_filename;
|
curfilename=last_filename;
|
||||||
|
curfile_unicode=last_unicode;
|
||||||
fp=last_fp;
|
fp=last_fp;
|
||||||
|
|
||||||
build_include_depth--;
|
build_include_depth--;
|
||||||
|
@ -825,9 +831,9 @@ int CEXEBuild::MacroExists(const TCHAR *macroname)
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
int CEXEBuild::LoadLicenseFile(TCHAR *file, TCHAR** pdata, LineParser &line) // caller must free *pdata, even on error result
|
int CEXEBuild::LoadLicenseFile(TCHAR *file, TCHAR** pdata, LineParser &line, BOOL* unicode) // caller must free *pdata, even on error result
|
||||||
{
|
{
|
||||||
FILE *fp=FOPENTEXT(file,"rt");
|
FILE *fp=FOPENTEXT2(file,"rt",unicode);
|
||||||
if (!fp)
|
if (!fp)
|
||||||
{
|
{
|
||||||
ERROR_MSG(_T("%s: open failed \"%s\"\n"),line.gettoken_str(0),file);
|
ERROR_MSG(_T("%s: open failed \"%s\"\n"),line.gettoken_str(0),file);
|
||||||
|
@ -1593,7 +1599,7 @@ int CEXEBuild::doCommand(int which_token, LineParser &line)
|
||||||
TCHAR *name = line.gettoken_str(1);
|
TCHAR *name = line.gettoken_str(1);
|
||||||
LANGID lang = line.gettoken_int(2);
|
LANGID lang = line.gettoken_int(2);
|
||||||
TCHAR *str = line.gettoken_str(3);
|
TCHAR *str = line.gettoken_str(3);
|
||||||
int ret = SetLangString(name, lang, str);
|
int ret = SetLangString(name, lang, str, curfile_unicode);
|
||||||
if (ret == PS_WARNING)
|
if (ret == PS_WARNING)
|
||||||
warning_fl(_T("LangString \"%s\" set multiple times for %d, wasting space"), name, lang);
|
warning_fl(_T("LangString \"%s\" set multiple times for %d, wasting space"), name, lang);
|
||||||
else if (ret == PS_ERROR) {
|
else if (ret == PS_ERROR) {
|
||||||
|
@ -1620,12 +1626,13 @@ int CEXEBuild::doCommand(int which_token, LineParser &line)
|
||||||
|
|
||||||
TCHAR *data = NULL;
|
TCHAR *data = NULL;
|
||||||
MANAGE_WITH(data, free);
|
MANAGE_WITH(data, free);
|
||||||
|
BOOL unicode;
|
||||||
|
|
||||||
int ret = LoadLicenseFile(file, &data, line);
|
int ret = LoadLicenseFile(file, &data, line, &unicode);
|
||||||
if (ret != PS_OK)
|
if (ret != PS_OK)
|
||||||
return ret;
|
return ret;
|
||||||
|
|
||||||
ret = SetLangString(name, lang, data);
|
ret = SetLangString(name, lang, data, unicode);
|
||||||
if (ret == PS_WARNING)
|
if (ret == PS_WARNING)
|
||||||
warning_fl(_T("LicenseLangString \"%s\" set multiple times for %d, wasting space"), name, lang);
|
warning_fl(_T("LicenseLangString \"%s\" set multiple times for %d, wasting space"), name, lang);
|
||||||
else if (ret == PS_ERROR)
|
else if (ret == PS_ERROR)
|
||||||
|
@ -1895,7 +1902,8 @@ int CEXEBuild::doCommand(int which_token, LineParser &line)
|
||||||
|
|
||||||
if (!idx)
|
if (!idx)
|
||||||
{
|
{
|
||||||
int ret = LoadLicenseFile(file, &filedata, line);
|
BOOL unicode;
|
||||||
|
int ret = LoadLicenseFile(file, &filedata, line, &unicode);
|
||||||
if (ret != PS_OK)
|
if (ret != PS_OK)
|
||||||
return ret;
|
return ret;
|
||||||
data = filedata;
|
data = filedata;
|
||||||
|
|
|
@ -19,10 +19,11 @@
|
||||||
#include "util.h"
|
#include "util.h"
|
||||||
#include <vector>
|
#include <vector>
|
||||||
|
|
||||||
FILE* FileOpenUnicodeText(const TCHAR* file, const TCHAR* mode)
|
FILE* FileOpenUnicodeText(const TCHAR* file, const TCHAR* mode, BOOL* unicode)
|
||||||
{
|
{
|
||||||
extern FILE *g_output;
|
extern FILE *g_output;
|
||||||
CValidateUnicode::FILE_TYPE ftype = CValidateUnicode::UTF_8; // default file format is UTF-8
|
CValidateUnicode::FILE_TYPE ftype = CValidateUnicode::UTF_8; // default file format is UTF-8
|
||||||
|
if (unicode) *unicode = TRUE;
|
||||||
|
|
||||||
// If we are reading an existing file, check to see what type of file it
|
// If we are reading an existing file, check to see what type of file it
|
||||||
// is first.
|
// is first.
|
||||||
|
@ -92,7 +93,7 @@ FILE* FileOpenUnicodeText(const TCHAR* file, const TCHAR* mode)
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
// Looks like fopen() doesn't support other encodings of Unicode.
|
// Looks like fopen() doesn't support other encodings of Unicode.
|
||||||
strMode.append(_T(", ccs=UNICODE"));
|
if (unicode) *unicode = FALSE;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -29,20 +29,24 @@ typedef std::wstring tstring;
|
||||||
typedef std::wofstream tofstream;
|
typedef std::wofstream tofstream;
|
||||||
typedef std::wifstream tifstream;
|
typedef std::wifstream tifstream;
|
||||||
// Use the following macros to open text files.
|
// Use the following macros to open text files.
|
||||||
FILE* FileOpenUnicodeText(const TCHAR* file, const TCHAR* mode);
|
FILE* FileOpenUnicodeText(const TCHAR* file, const TCHAR* mode, BOOL* unicode);
|
||||||
#define FOPENTEXT(file, mode) FileOpenUnicodeText(file, _T(mode))
|
#define FOPENTEXT(file, mode) FileOpenUnicodeText(file, _T(mode), NULL)
|
||||||
|
#define FOPENTEXT2(file, mode, unicode) FileOpenUnicodeText(file, _T(mode), unicode)
|
||||||
#else
|
#else
|
||||||
typedef std::string tstring;
|
typedef std::string tstring;
|
||||||
typedef std::ofstream tofstream;
|
typedef std::ofstream tofstream;
|
||||||
typedef std::ifstream tifstream;
|
typedef std::ifstream tifstream;
|
||||||
// Use the following macros to open text files.
|
// Use the following macros to open text files.
|
||||||
#define FOPENTEXT(file, mode) fopen(file, mode)
|
#define FOPENTEXT(file, mode) fopen(file, mode)
|
||||||
|
#define FOPENTEXT2(file, mode, unicode) *unicode=FALSE, fopen(file, mode)
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifndef _UNICODE
|
#ifndef _UNICODE
|
||||||
#define CtoTString(str) (str)
|
#define CtoTString(str) (str)
|
||||||
|
#define CtoTString2(str,cp) (str)
|
||||||
#define TtoCString(str) (str)
|
#define TtoCString(str) (str)
|
||||||
#else
|
#else
|
||||||
|
#define CtoTString2(str,cp) CtoTString(str,cp)
|
||||||
|
|
||||||
// This is a helpful little function for converting exceptions or
|
// This is a helpful little function for converting exceptions or
|
||||||
// other system type things that come back ANSI and must be
|
// other system type things that come back ANSI and must be
|
||||||
|
@ -56,6 +60,12 @@ public:
|
||||||
m_wStr = (wchar_t*) GlobalAlloc(GPTR, len*sizeof(wchar_t));
|
m_wStr = (wchar_t*) GlobalAlloc(GPTR, len*sizeof(wchar_t));
|
||||||
MultiByteToWideChar(CP_ACP, 0, str, -1, m_wStr, len);
|
MultiByteToWideChar(CP_ACP, 0, str, -1, m_wStr, len);
|
||||||
}
|
}
|
||||||
|
CtoTString(const char* str, UINT cp)
|
||||||
|
{
|
||||||
|
int len = MultiByteToWideChar(cp, 0, str, -1, NULL, 0);
|
||||||
|
m_wStr = (wchar_t*) GlobalAlloc(GPTR, len*sizeof(wchar_t));
|
||||||
|
MultiByteToWideChar(cp, 0, str, -1, m_wStr, len);
|
||||||
|
}
|
||||||
CtoTString(const std::string& str)
|
CtoTString(const std::string& str)
|
||||||
{
|
{
|
||||||
int len = MultiByteToWideChar(CP_ACP, 0, str.c_str(), str.length()+1, NULL, 0);
|
int len = MultiByteToWideChar(CP_ACP, 0, str.c_str(), str.length()+1, NULL, 0);
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue