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:
wizou 2010-05-28 13:10:16 +00:00
parent e097a25855
commit 90e05acdd3
8 changed files with 70 additions and 24 deletions

View file

@ -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:

View file

@ -95,6 +95,7 @@ CEXEBuild::CEXEBuild() :
linecnt = 0;
fp = 0;
curfilename = 0;
curfile_unicode = FALSE;
display_info=1;
display_script=1;

View file

@ -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.

View file

@ -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);

View file

@ -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)

View file

@ -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;

View file

@ -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;
}

View file

@ -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);