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
|
||||
|
||||
- For Unicode version of NSIS
|
||||
|
||||
* type:
|
||||
scons UNICODE=yes
|
||||
|
||||
- Installing
|
||||
|
||||
* type:
|
||||
|
|
|
@ -95,6 +95,7 @@ CEXEBuild::CEXEBuild() :
|
|||
linecnt = 0;
|
||||
fp = 0;
|
||||
curfilename = 0;
|
||||
curfile_unicode = FALSE;
|
||||
|
||||
display_info=1;
|
||||
display_script=1;
|
||||
|
|
|
@ -107,7 +107,7 @@ class CEXEBuild {
|
|||
|
||||
// process a script (you can process as many scripts as you want,
|
||||
// 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);
|
||||
|
||||
// you only get to call write_output once, so use it wisely.
|
||||
|
@ -125,6 +125,7 @@ class CEXEBuild {
|
|||
|
||||
int linecnt;
|
||||
const TCHAR *curfilename;
|
||||
BOOL curfile_unicode;
|
||||
FILE *fp;
|
||||
|
||||
HWND notify_hwnd;
|
||||
|
@ -166,7 +167,7 @@ class CEXEBuild {
|
|||
int parseScript();
|
||||
int includeScript(TCHAR *f);
|
||||
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
|
||||
void ps_addtoline(const TCHAR *str, GrowBuf &linedata, StringList &hist, bool bIgnoreDefines = false);
|
||||
#else
|
||||
|
@ -319,7 +320,7 @@ class CEXEBuild {
|
|||
* return aPS_ERROR. If this function call is overwriting a set user string,
|
||||
* 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.
|
||||
|
|
|
@ -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 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) {
|
||||
int CEXEBuild::SetLangString(TCHAR *name, LANGID lang, TCHAR *str, BOOL unicode) {
|
||||
if (!str || !name) return PS_ERROR;
|
||||
|
||||
LanguageTable *table = GetLangTable(lang);
|
||||
|
@ -490,7 +490,7 @@ int CEXEBuild::SetLangString(TCHAR *name, LANGID lang, TCHAR *str) {
|
|||
if (pos < 0)
|
||||
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_OK;
|
||||
|
@ -912,7 +912,8 @@ TCHAR SkipComments(FILE *f) {
|
|||
|
||||
// NSIS Language File parser
|
||||
LanguageTable * CEXEBuild::LoadLangFile(TCHAR *filename) {
|
||||
FILE *f = FOPENTEXT(filename, "r");
|
||||
BOOL unicode;
|
||||
FILE *f = FOPENTEXT2(filename, "r", &unicode);
|
||||
if (!f) {
|
||||
ERROR_MSG(_T("Error: Can't open language file - \"%s\"!\n"),filename);
|
||||
return 0;
|
||||
|
@ -1014,6 +1015,15 @@ LanguageTable * CEXEBuild::LoadLangFile(TCHAR *filename) {
|
|||
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
|
||||
nlf->m_szStrings[NLF_RTL] = (TCHAR *)malloc(2*sizeof(TCHAR));
|
||||
nlf->m_bRTL = false;
|
||||
|
@ -1121,6 +1131,14 @@ LanguageTable * CEXEBuild::LoadLangFile(TCHAR *filename) {
|
|||
else *out = *in;
|
||||
}
|
||||
*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);
|
||||
|
||||
|
|
|
@ -197,7 +197,8 @@ static tstring get_home()
|
|||
|
||||
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 (build.display_script)
|
||||
|
@ -205,7 +206,7 @@ static int process_config(CEXEBuild& build, tstring& conf)
|
|||
_ftprintf(g_output,_T("Processing config: \n"));
|
||||
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);
|
||||
if (ret != PS_OK && ret != PS_EOF)
|
||||
{
|
||||
|
@ -484,6 +485,7 @@ int _tmain(int argc, TCHAR **argv)
|
|||
|
||||
{
|
||||
TCHAR sfile[1024];
|
||||
BOOL unicode=FALSE;
|
||||
if (!_tcscmp(argv[argpos],_T("-")) && !in_files)
|
||||
{
|
||||
fp=stdin;
|
||||
|
@ -492,11 +494,11 @@ int _tmain(int argc, TCHAR **argv)
|
|||
else
|
||||
{
|
||||
_tcscpy(sfile,argv[argpos]);
|
||||
fp=FOPENTEXT(sfile,"rt");
|
||||
fp=FOPENTEXT2(sfile,"rt",&unicode);
|
||||
if (!fp)
|
||||
{
|
||||
_stprintf(sfile,_T("%s.nsi"),argv[argpos]);
|
||||
fp=FOPENTEXT(sfile,"rt");
|
||||
fp=FOPENTEXT2(sfile,"rt",&unicode);
|
||||
if (!fp)
|
||||
{
|
||||
if (build.display_errors)
|
||||
|
@ -522,7 +524,7 @@ int _tmain(int argc, TCHAR **argv)
|
|||
_ftprintf(g_output,_T("Processing script file: \"%s\"\n"),sfile);
|
||||
fflush(g_output);
|
||||
}
|
||||
int ret=build.process_script(fp,sfile);
|
||||
int ret=build.process_script(fp,sfile,unicode);
|
||||
if (fp != stdin) fclose(fp);
|
||||
|
||||
if (ret != PS_EOF && ret != PS_OK)
|
||||
|
|
|
@ -202,11 +202,12 @@ void CEXEBuild::del_date_time_predefines()
|
|||
}
|
||||
#endif
|
||||
|
||||
int CEXEBuild::process_script(FILE *filepointer, const TCHAR *filename)
|
||||
int CEXEBuild::process_script(FILE *filepointer, const TCHAR *filename, BOOL unicode)
|
||||
{
|
||||
linecnt = 0;
|
||||
fp = filepointer;
|
||||
curfilename = filename;
|
||||
curfile_unicode = unicode;
|
||||
|
||||
if (has_called_write_output)
|
||||
{
|
||||
|
@ -232,6 +233,7 @@ int CEXEBuild::process_script(FILE *filepointer, const TCHAR *filename)
|
|||
|
||||
fp = 0;
|
||||
curfilename = 0;
|
||||
curfile_unicode = FALSE;
|
||||
|
||||
if (m_linebuild.getlen())
|
||||
{
|
||||
|
@ -745,7 +747,8 @@ int CEXEBuild::parseScript()
|
|||
int CEXEBuild::includeScript(TCHAR *f)
|
||||
{
|
||||
SCRIPT_MSG(_T("!include: \"%s\"\n"),f);
|
||||
FILE *incfp=FOPENTEXT(f,"rt");
|
||||
BOOL unicode;
|
||||
FILE *incfp=FOPENTEXT2(f,"rt",&unicode);
|
||||
if (!incfp)
|
||||
{
|
||||
ERROR_MSG(_T("!include: could not open file: \"%s\"\n"),f);
|
||||
|
@ -765,7 +768,9 @@ int CEXEBuild::includeScript(TCHAR *f)
|
|||
int last_linecnt=linecnt;
|
||||
linecnt=0;
|
||||
const TCHAR *last_filename=curfilename;
|
||||
BOOL last_unicode=curfile_unicode;
|
||||
curfilename=f;
|
||||
curfile_unicode=unicode;
|
||||
FILE *last_fp=fp;
|
||||
fp=incfp;
|
||||
|
||||
|
@ -787,6 +792,7 @@ int CEXEBuild::includeScript(TCHAR *f)
|
|||
|
||||
linecnt=last_linecnt;
|
||||
curfilename=last_filename;
|
||||
curfile_unicode=last_unicode;
|
||||
fp=last_fp;
|
||||
|
||||
build_include_depth--;
|
||||
|
@ -825,9 +831,9 @@ int CEXEBuild::MacroExists(const TCHAR *macroname)
|
|||
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)
|
||||
{
|
||||
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);
|
||||
LANGID lang = line.gettoken_int(2);
|
||||
TCHAR *str = line.gettoken_str(3);
|
||||
int ret = SetLangString(name, lang, str);
|
||||
int ret = SetLangString(name, lang, str, curfile_unicode);
|
||||
if (ret == PS_WARNING)
|
||||
warning_fl(_T("LangString \"%s\" set multiple times for %d, wasting space"), name, lang);
|
||||
else if (ret == PS_ERROR) {
|
||||
|
@ -1620,12 +1626,13 @@ int CEXEBuild::doCommand(int which_token, LineParser &line)
|
|||
|
||||
TCHAR *data = NULL;
|
||||
MANAGE_WITH(data, free);
|
||||
BOOL unicode;
|
||||
|
||||
int ret = LoadLicenseFile(file, &data, line);
|
||||
int ret = LoadLicenseFile(file, &data, line, &unicode);
|
||||
if (ret != PS_OK)
|
||||
return ret;
|
||||
|
||||
ret = SetLangString(name, lang, data);
|
||||
ret = SetLangString(name, lang, data, unicode);
|
||||
if (ret == PS_WARNING)
|
||||
warning_fl(_T("LicenseLangString \"%s\" set multiple times for %d, wasting space"), name, lang);
|
||||
else if (ret == PS_ERROR)
|
||||
|
@ -1895,7 +1902,8 @@ int CEXEBuild::doCommand(int which_token, LineParser &line)
|
|||
|
||||
if (!idx)
|
||||
{
|
||||
int ret = LoadLicenseFile(file, &filedata, line);
|
||||
BOOL unicode;
|
||||
int ret = LoadLicenseFile(file, &filedata, line, &unicode);
|
||||
if (ret != PS_OK)
|
||||
return ret;
|
||||
data = filedata;
|
||||
|
|
|
@ -19,10 +19,11 @@
|
|||
#include "util.h"
|
||||
#include <vector>
|
||||
|
||||
FILE* FileOpenUnicodeText(const TCHAR* file, const TCHAR* mode)
|
||||
FILE* FileOpenUnicodeText(const TCHAR* file, const TCHAR* mode, BOOL* unicode)
|
||||
{
|
||||
extern FILE *g_output;
|
||||
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
|
||||
// is first.
|
||||
|
@ -92,7 +93,7 @@ FILE* FileOpenUnicodeText(const TCHAR* file, const TCHAR* mode)
|
|||
break;
|
||||
default:
|
||||
// Looks like fopen() doesn't support other encodings of Unicode.
|
||||
strMode.append(_T(", ccs=UNICODE"));
|
||||
if (unicode) *unicode = FALSE;
|
||||
break;
|
||||
}
|
||||
|
||||
|
|
|
@ -29,20 +29,24 @@ typedef std::wstring tstring;
|
|||
typedef std::wofstream tofstream;
|
||||
typedef std::wifstream tifstream;
|
||||
// Use the following macros to open text files.
|
||||
FILE* FileOpenUnicodeText(const TCHAR* file, const TCHAR* mode);
|
||||
#define FOPENTEXT(file, mode) FileOpenUnicodeText(file, _T(mode))
|
||||
FILE* FileOpenUnicodeText(const TCHAR* file, const TCHAR* mode, BOOL* unicode);
|
||||
#define FOPENTEXT(file, mode) FileOpenUnicodeText(file, _T(mode), NULL)
|
||||
#define FOPENTEXT2(file, mode, unicode) FileOpenUnicodeText(file, _T(mode), unicode)
|
||||
#else
|
||||
typedef std::string tstring;
|
||||
typedef std::ofstream tofstream;
|
||||
typedef std::ifstream tifstream;
|
||||
// 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
|
||||
|
||||
#ifndef _UNICODE
|
||||
#define CtoTString(str) (str)
|
||||
#define CtoTString2(str,cp) (str)
|
||||
#define TtoCString(str) (str)
|
||||
#else
|
||||
#define CtoTString2(str,cp) CtoTString(str,cp)
|
||||
|
||||
// This is a helpful little function for converting exceptions or
|
||||
// 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));
|
||||
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)
|
||||
{
|
||||
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