[prev in list] [next in list] [prev in thread] [next in thread] 

List:       nsis-commits
Subject:    [NSIS-commits] SF.net SVN: nsis:[6100] NSIS/trunk
From:       wizou () users ! sourceforge ! net
Date:       2010-06-14 10:07:23
Message-ID: E1OO6Zf-0001rH-GY () sfp-svn-6 ! v30 ! ch3 ! sourceforge ! com
[Download RAW message or body]

Revision: 6100
          http://nsis.svn.sourceforge.net/nsis/?rev=6100&view=rev
Author:   wizou
Date:     2010-06-14 10:07:22 +0000 (Mon, 14 Jun 2010)

Log Message:
-----------
Unicode port: Unicode version of NSIS can now generate both ANSI & Unicode installers \
(using new instruction UnicodeInstaller on/off). Stubs & Plugins differentiation is \
done automatically using a 'W' suffix. SConscripts need to be reviewed to generate \
both variants of Plugins & pluginapi.lib under Unicode compilation.

Modified Paths:
--------------
    NSIS/trunk/Contrib/ExDLL/SConscript
    NSIS/trunk/Contrib/InstallOptions/InstallOptions.nsh
    NSIS/trunk/Contrib/Makensisw/makensisw.cpp
    NSIS/trunk/SCons/Config/default
    NSIS/trunk/SCons/Config/gnu
    NSIS/trunk/SCons/Config/hpc++
    NSIS/trunk/SCons/Config/ms
    NSIS/trunk/SConstruct
    NSIS/trunk/Source/DialogTemplate.cpp
    NSIS/trunk/Source/DialogTemplate.h
    NSIS/trunk/Source/Plugins.cpp
    NSIS/trunk/Source/Plugins.h
    NSIS/trunk/Source/build.cpp
    NSIS/trunk/Source/build.h
    NSIS/trunk/Source/exehead/Ui.c
    NSIS/trunk/Source/exehead/fileform.h
    NSIS/trunk/Source/lang.cpp
    NSIS/trunk/Source/script.cpp
    NSIS/trunk/Source/strlist.cpp
    NSIS/trunk/Source/strlist.h
    NSIS/trunk/Source/tokens.cpp
    NSIS/trunk/Source/tokens.h
    NSIS/trunk/Source/writer.cpp
    NSIS/trunk/Source/writer.h

Modified: NSIS/trunk/Contrib/ExDLL/SConscript
===================================================================
--- NSIS/trunk/Contrib/ExDLL/SConscript	2010-06-11 16:33:10 UTC (rev 6099)
+++ NSIS/trunk/Contrib/ExDLL/SConscript	2010-06-14 10:07:22 UTC (rev 6100)
@@ -24,19 +24,27 @@
 	extdll.inc
 """)
 
-Import('env plugin_env')
+Import('env plugin_env plugin_uenv')
 
 # build library
+# in Unicode compilation, we should really build both variants but I can't get it to \
work [Wizou] +if env['UNICODE']:
+	api_uenv = plugin_uenv.Clone()
+	api_uenv.Append(CPPPATH = ['#Source/exehead'])
+	libW = api_uenv.Library(lib_target+'W', lib_files)
+	lib = libW
+else:
+	api_env = plugin_env.Clone()
+	api_env.Append(CPPPATH = ['#Source/exehead'])
+	lib = api_env.Library(lib_target, lib_files)
 
-api_env = env.Clone()
-api_env.Append(CPPPATH = ['#Source/exehead'])
-lib = api_env.Library(lib_target, lib_files)
-
 # distribute library, files and examples
 
 env.DistributeExamples(api_files, path='Plugin/nsis')
 
 if env['PLATFORM'] == 'win32':
+	if env['UNICODE']:
+		env.DistributeExamples(libW, lib_target+".lib", path='Plugin/nsis')
 	env.DistributeExamples(lib, path='Plugin/nsis')
 
 else:
@@ -57,3 +65,6 @@
 plugin_env.Append(CPPPATH = ['#$BUILD_PREFIX/api'])
 plugin_env.Append(LIBPATH = ['#$BUILD_PREFIX/api/nsis'])
 plugin_env.Append(LIBS = [lib_target])
+plugin_uenv.Append(CPPPATH = ['#$BUILD_PREFIX/api'])
+plugin_uenv.Append(LIBPATH = ['#$BUILD_PREFIX/api/nsis'])
+plugin_uenv.Append(LIBS = [lib_target+'W'])

Modified: NSIS/trunk/Contrib/InstallOptions/InstallOptions.nsh
===================================================================
--- NSIS/trunk/Contrib/InstallOptions/InstallOptions.nsh	2010-06-11 16:33:10 UTC (rev \
                6099)
+++ NSIS/trunk/Contrib/InstallOptions/InstallOptions.nsh	2010-06-14 10:07:22 UTC (rev \
6100) @@ -126,7 +126,7 @@
   InitPluginsDir
   File "/oname=$PLUGINSDIR\${FILE}" "${FILE}"
 !ifdef NSIS_UNICODE
-  InstallOptions::make_unicode "$PLUGINSDIR\${FILE}"
+  InstallOptionsW::make_unicode "$PLUGINSDIR\${FILE}"
 !endif
   !insertmacro INSTALLOPTIONS_WRITE "${FILE}" "Settings" "RTL" "$(^RTL)"
 
@@ -139,7 +139,7 @@
   InitPluginsDir
   File "/oname=$PLUGINSDIR\${FILENAME}" "${FILE}"
 !ifdef NSIS_UNICODE
-  InstallOptions::make_unicode "$PLUGINSDIR\${FILENAME}"
+  InstallOptionsW::make_unicode "$PLUGINSDIR\${FILENAME}"
 !endif
   !insertmacro INSTALLOPTIONS_WRITE "${FILENAME}" "Settings" "RTL" "$(^RTL)"
 

Modified: NSIS/trunk/Contrib/Makensisw/makensisw.cpp
===================================================================
--- NSIS/trunk/Contrib/Makensisw/makensisw.cpp	2010-06-11 16:33:10 UTC (rev 6099)
+++ NSIS/trunk/Contrib/Makensisw/makensisw.cpp	2010-06-14 10:07:22 UTC (rev 6100)
@@ -706,7 +706,9 @@
 }
 
 DWORD WINAPI MakeNSISProc(LPVOID p) {
+#ifdef _UNICODE
   TCHAR buf[1024];
+#endif
   char iobuf[1024];           //i/o buffer
   STARTUPINFO si={sizeof(si),};
   SECURITY_ATTRIBUTES sa={sizeof(sa),};

Modified: NSIS/trunk/SCons/Config/default
===================================================================
--- NSIS/trunk/SCons/Config/default	2010-06-11 16:33:10 UTC (rev 6099)
+++ NSIS/trunk/SCons/Config/default	2010-06-14 10:07:22 UTC (rev 6100)
@@ -53,4 +53,4 @@
 
 # return
 
-Return('stub_env makensis_env plugin_env util_env cp_util_env test_env')
+Return('stub_env makensis_env plugin_env util_env cp_util_env test_env stub_env \
plugin_env')

Modified: NSIS/trunk/SCons/Config/gnu
===================================================================
--- NSIS/trunk/SCons/Config/gnu	2010-06-11 16:33:10 UTC (rev 6099)
+++ NSIS/trunk/SCons/Config/gnu	2010-06-14 10:07:22 UTC (rev 6100)
@@ -309,4 +309,4 @@
 
 ### return
 
-Return('stub_env makensis_env plugin_env util_env cp_util_env test_env')
+Return('stub_env makensis_env plugin_env util_env cp_util_env test_env stub_env \
plugin_env')

Modified: NSIS/trunk/SCons/Config/hpc++
===================================================================
--- NSIS/trunk/SCons/Config/hpc++	2010-06-11 16:33:10 UTC (rev 6099)
+++ NSIS/trunk/SCons/Config/hpc++	2010-06-14 10:07:22 UTC (rev 6100)
@@ -125,4 +125,4 @@
 
 # return
 
-Return('stub_env makensis_env plugin_env util_env cp_util_env test_env')
+Return('stub_env makensis_env plugin_env util_env cp_util_env test_env stub_env \
plugin_env')

Modified: NSIS/trunk/SCons/Config/ms
===================================================================
--- NSIS/trunk/SCons/Config/ms	2010-06-11 16:33:10 UTC (rev 6099)
+++ NSIS/trunk/SCons/Config/ms	2010-06-14 10:07:22 UTC (rev 6100)
@@ -41,8 +41,9 @@
 	defenv.Append(LINKFLAGS = ['/debug'])
 
 ### unicode
-if defenv['UNICODE']:
-	defenv.Append(CPPDEFINES = ['_UNICODE', 'UNICODE'])
+tdefenv = defenv.Clone()
+if tdefenv['UNICODE']:
+	tdefenv.Append(CPPDEFINES = ['_UNICODE', 'UNICODE'])
 
 ### workarounds
 
@@ -101,19 +102,19 @@
 
 stub_env.Append(LINKFLAGS = ['/opt:nowin98'])      # 512 bytes align
 
-if defenv['UNICODE']:
-	stub_env.Append(LINKFLAGS = ['/entry:wWinMain'])   # Unicode entry point
-else:
-	stub_env.Append(LINKFLAGS = ['/entry:WinMain'])    # ANSI entry point
-
 stub_env.Append(LINKFLAGS = ['$NODEFLIBS_FLAG'])   # no default libraries
 stub_env.Append(LINKFLAGS = ['$MAP_FLAG'])         # generate map file
 stub_env.Append(CCFLAGS = ['/FAcs'])               # full listing files
 stub_env.Append(CCFLAGS = ['/Fa${TARGET}.lst'])    # listing file name
 
+stub_uenv = stub_env.Clone()
+stub_uenv.Append(LINKFLAGS = ['/entry:wWinMain'])  # Unicode entry point
+stub_uenv.Append(CPPDEFINES = ['_UNICODE', 'UNICODE'])
+stub_env.Append(LINKFLAGS = ['/entry:WinMain'])    # ANSI entry point
+
 ### makensis environment
 
-makensis_env = defenv.Clone()
+makensis_env = tdefenv.Clone()
 
 makensis_env.Append(CPPPATH = ['#$BUILD_CONFIG'])
 
@@ -140,9 +141,12 @@
 plugin_env.Append(LINKFLAGS = ['/opt:nowin98'])    # 512 bytes align
 plugin_env.Append(LINKFLAGS = ['$MAP_FLAG'])       # generate map file
 
+plugin_uenv = plugin_env.Clone()
+plugin_uenv.Append(CPPDEFINES = ['_UNICODE', 'UNICODE'])
+
 ### util environment
 
-util_env = defenv.Clone()
+util_env = tdefenv.Clone()
 
 if not defenv['DEBUG']:
 	util_env.Append(CCFLAGS = ['/O1'])            # optimize for speed
@@ -209,8 +213,10 @@
 def add_file(file):
 	file = File(file)
 	add_file_to_emitter(stub_env, 'PROGEMITTER', file)
+	add_file_to_emitter(stub_uenv, 'PROGEMITTER', file)
 	add_file_to_emitter(util_env, 'PROGEMITTER', file)
 	add_file_to_emitter(plugin_env, 'SHLIBEMITTER', file)
+	add_file_to_emitter(plugin_uenv, 'SHLIBEMITTER', file)
 
 #
 # MSVC 6 SP6 doesn't like direct shifting of 64-bit integers.
@@ -240,6 +246,7 @@
 
 if not conf.TryLink(int64test, '.c'):
 	stub_env.Append(CPPDEFINES = ['_NSIS_NO_INT64_SHR'])
+	stub_uenv.Append(CPPDEFINES = ['_NSIS_NO_INT64_SHR'])
 
 conf.Finish()	
 
@@ -256,4 +263,4 @@
 
 ### return
 
-Return('stub_env makensis_env plugin_env util_env cp_util_env test_env')
+Return('stub_env makensis_env plugin_env util_env cp_util_env test_env stub_uenv \
plugin_uenv')

Modified: NSIS/trunk/SConstruct
===================================================================
--- NSIS/trunk/SConstruct	2010-06-11 16:33:10 UTC (rev 6099)
+++ NSIS/trunk/SConstruct	2010-06-14 10:07:22 UTC (rev 6100)
@@ -420,8 +420,10 @@
 util_env = envs[3]
 cp_util_env = envs[4]
 test_env = envs[5]
+stub_uenv = envs[6]
+plugin_uenv = envs[7]
 
-Export('stub_env makensis_env plugin_env util_env cp_util_env test_env')
+Export('stub_env makensis_env plugin_env plugin_uenv util_env cp_util_env test_env')
 
 ######################################################################
 #######  Distribution                                              ###
@@ -484,13 +486,18 @@
 #######  Stubs                                                     ###
 ######################################################################
 
-def BuildStub(compression, solid):
-	env = stub_env.Clone()
+def BuildStub(compression, solid, unicode):
 
 	suffix = ''
 	if solid:
 		suffix = '_solid'
+	if unicode:
+		suffix += 'W'
+		env = stub_uenv.Clone()
+	else:
+		env = stub_env.Clone()
 
+
 	build_dir = '$BUILD_PREFIX/stub_%s%s' % (compression, suffix)
 
 	exports = { 'env' : env, 'compression' : compression, 'solid_compression' : solid }
@@ -507,8 +514,12 @@
 	if stub in defenv['SKIPSTUBS']:
 		continue
 
-	BuildStub(stub, False)
-	BuildStub(stub, True)
+	if defenv['UNICODE']:
+		BuildStub(stub, False, True)
+		BuildStub(stub, True, True)
+	
+	BuildStub(stub, False, False)
+	BuildStub(stub, True, False)
 
 defenv.DistributeStubs('Source/exehead/uninst.ico',names='uninst')
 
@@ -569,11 +580,25 @@
 #######  Plug-ins                                                  ###
 ######################################################################
 
+def BuildPluginBoth(target, source, libs, examples = None, docs = None,
+                entry = 'DllMain', res = None, resources = None,
+                defines = None, flags = None, nodeflib = True,
+                cppused = False):
+	# this function should build the ANSI & Unicode variant of the DLL, but I can't get \
it to work... help!!! [Wizou] +	if defenv['UNICODE']:
+		#VariantDir('$BUILD_PREFIX/' + plugin + 'W', path)
+		BuildPlugin(target, source, libs, examples, docs, entry, res, resources, defines, \
flags, nodeflib, cppused, True) +	else:
+		BuildPlugin(target, source, libs, examples, docs, entry, res, resources, defines, \
flags, nodeflib, cppused, False) +	
 def BuildPlugin(target, source, libs, examples = None, docs = None,
                 entry = 'DllMain', res = None, resources = None,
                 defines = None, flags = None, nodeflib = True,
-                cppused = False):
-	env = plugin_env.Clone()
+                cppused = False, unicode = False):
+	if unicode:
+		env = plugin_uenv.Clone()
+	else:
+		env = plugin_env.Clone()
 
 	if cppused and env['CPP_REQUIRES_STDLIB']:
 		nodeflib = False
@@ -595,7 +620,10 @@
 			plugin = i
 			break
 	env.DistributePlugin(plugin)
+	if unicode:
+		env.DistributePlugin(plugin, str(plugin)[:-4]+"W.dll")		# tweak to generate both \
plugin.dll & pluginW.dll (until we get to build really both variant)  
+	#if not unicode:	# distribute extras only for ANSI builds
 	DistributeExtras(env, target, examples, docs)
 
 for plugin in plugin_libs + plugins:
@@ -604,8 +632,10 @@
 
 	path = 'Contrib/' + plugin
 	build_dir = '$BUILD_PREFIX/' + plugin
-	exports = {'BuildPlugin' : BuildPlugin, 'env' : plugin_env.Clone()}
-
+	if defenv['UNICODE']:
+		exports = {'BuildPlugin' : BuildPluginBoth, 'env' : plugin_uenv.Clone()}
+	else:
+		exports = {'BuildPlugin' : BuildPlugin, 'env' : plugin_env.Clone()}
 	defenv.SConscript(dirs = path, build_dir = build_dir, duplicate = False, exports = \
exports)  
 ######################################################################

Modified: NSIS/trunk/Source/DialogTemplate.cpp
===================================================================
--- NSIS/trunk/Source/DialogTemplate.cpp	2010-06-11 16:33:10 UTC (rev 6099)
+++ NSIS/trunk/Source/DialogTemplate.cpp	2010-06-14 10:07:22 UTC (rev 6100)
@@ -91,8 +91,9 @@
 // Construction/Destruction
 //////////////////////////////////////////////////////////////////////
 
-CDialogTemplate::CDialogTemplate(BYTE* pbData, unsigned int uCodePage) {
+CDialogTemplate::CDialogTemplate(BYTE* pbData, bool build_unicode, unsigned int \
uCodePage) {  m_uCodePage = uCodePage;
+  m_build_unicode = build_unicode;
 
   m_dwHelpId = 0;
   m_szClass = 0;
@@ -598,7 +599,7 @@
     // Write class variant length array
     WCHAR *szClass = m_vItems[i]->szClass;
 #ifdef _UNICODE
-    if (!IS_INTRESOURCE(szClass) && !_wcsicmp(szClass, L"RichEdit20A"))
+    if (!IS_INTRESOURCE(szClass) && m_build_unicode && !_wcsicmp(szClass, \
                L"RichEdit20A"))
         szClass = L"RichEdit20W"; // transmute ANSI RichEdit control into Unicode \
RichEdit  #endif
     WriteStringOrId(szClass);

Modified: NSIS/trunk/Source/DialogTemplate.h
===================================================================
--- NSIS/trunk/Source/DialogTemplate.h	2010-06-11 16:33:10 UTC (rev 6099)
+++ NSIS/trunk/Source/DialogTemplate.h	2010-06-14 10:07:22 UTC (rev 6100)
@@ -107,7 +107,7 @@
 
 class CDialogTemplate {
 public:
-  CDialogTemplate(BYTE* pbData, unsigned int uCodePage=CP_ACP);
+  CDialogTemplate(BYTE* pbData, bool build_unicode, unsigned int uCodePage=CP_ACP);
   virtual ~CDialogTemplate();
 
   short GetWidth();
@@ -136,6 +136,7 @@
 
 private:
   bool  m_bExtended;
+  bool  m_build_unicode;
 
   DWORD m_dwHelpId; // Extended only
 

Modified: NSIS/trunk/Source/Plugins.cpp
===================================================================
--- NSIS/trunk/Source/Plugins.cpp	2010-06-11 16:33:10 UTC (rev 6099)
+++ NSIS/trunk/Source/Plugins.cpp	2010-06-14 10:07:22 UTC (rev 6100)
@@ -47,7 +47,7 @@
 
   for (dir_reader::iterator files_itr = dr->files().begin();
        files_itr != dr->files().end();
-       files_itr++)
+       files_itr++) // note: files are listed alphabetically, so plugin.dll will be \
listed before pluginW.dll  {
     if (!dir_reader::matches(*files_itr, _T("*.dll")))
       continue;
@@ -109,7 +109,10 @@
     return;
   }
 
-  const tstring dllName = remove_file_extension(get_file_name(pathToDll));
+  tstring dllName = remove_file_extension(get_file_name(pathToDll));
+#ifdef _UNICODE
+  bool unicodeDll = dllName[dllName.size()-1] == 'W';
+#endif
 
   FIX_ENDIAN_INT16_INPLACE(NTHeaders->FileHeader.Characteristics);
   if (NTHeaders->FileHeader.Characteristics & IMAGE_FILE_DLL)
@@ -143,6 +146,12 @@
           const tstring lcsig = lowercase(signature);
           m_command_to_path[lcsig] = pathToDll;
           m_command_lowercase_to_command[lcsig] = signature;
+#ifdef _UNICODE
+          const tstring lcsigA = lowercase(dllName.substr(0,dllName.size()-1) + \
_T("::") + tstring(CtoTString(name))); +          if (unicodeDll && \
m_command_to_path.find(lcsigA) != m_command_to_path.end()) +            \
m_unicode_variant[lcsigA] = signature; +          else
+#endif
           if (displayInfo)
             _ftprintf(g_output, _T(" - %s\n"), signature.c_str());
         }
@@ -180,6 +189,10 @@
   return get_value(m_command_lowercase_to_command, lowercase(command));
 }
 
+tstring Plugins::UseUnicodeVariant(const tstring& command) const {
+  return get_value(m_unicode_variant, lowercase(command), command);
+}
+
 int Plugins::GetPluginHandle(bool uninst, const tstring& command) const {
   if (uninst) {
     return get_value(m_command_to_uninstall_data_handle, command, -1);

Modified: NSIS/trunk/Source/Plugins.h
===================================================================
--- NSIS/trunk/Source/Plugins.h	2010-06-11 16:33:10 UTC (rev 6099)
+++ NSIS/trunk/Source/Plugins.h	2010-06-14 10:07:22 UTC (rev 6100)
@@ -30,6 +30,7 @@
     tstring NormalizedCommand(const tstring& command) const;
     int GetPluginHandle(bool uninst, const tstring& command) const;
     tstring GetPluginPath(const tstring& command) const;
+    tstring UseUnicodeVariant(const tstring& lcsig) const;
     void SetDllDataHandle(bool uninst, const tstring& command, int dataHandle);
 
   private: // methods
@@ -38,6 +39,7 @@
   private: // data members
     std::map<tstring, tstring> m_command_lowercase_to_command;
     std::map<tstring, tstring> m_command_to_path;
+    std::map<tstring, tstring> m_unicode_variant;
     std::map<tstring, int> m_command_to_data_handle;
     std::map<tstring, int> m_command_to_uninstall_data_handle;
 };

Modified: NSIS/trunk/Source/build.cpp
===================================================================
--- NSIS/trunk/Source/build.cpp	2010-06-11 16:33:10 UTC (rev 6099)
+++ NSIS/trunk/Source/build.cpp	2010-06-14 10:07:22 UTC (rev 6100)
@@ -116,12 +116,8 @@
 
   definedlist.add(_T("NSIS_VERSION"), NSIS_VERSION);
 
-#ifdef _UNICODE
-  definedlist.add(_T("NSIS_UNICODE"));
-  definedlist.add(_T("NSIS_CHAR_SIZE"), _T("2"));
-#else
-  definedlist.add(_T("NSIS_CHAR_SIZE"), _T("1"));
-#endif
+  build_unicode=false;
+  definedlist.add(_T("NSIS_CHAR_SIZE"), _T("1"));   // this can change after a \
UnicodeInstaller instruction is found  
   // automatically generated header file containing all defines
 #include <nsis-defines.h>
@@ -230,8 +226,8 @@
 
   uninstaller_writes_used=0;
 
-  build_strlist.add(_T(""),0);
-  ubuild_strlist.add(_T(""),0);
+  build_strlist.add(_T(""), CP_ACP, false, build_unicode);
+  ubuild_strlist.add(_T(""), CP_ACP, false, build_unicode);
 
   build_langstring_num=0;
   ubuild_langstring_num=0;
@@ -469,11 +465,11 @@
     if (idx < 0) return idx;
   }
 
-  if (!process) return cur_strlist->add(string,2);
+  if (!process) return cur_strlist->add(string, codepage, false, build_unicode);
 
   TCHAR buf[NSIS_MAX_STRLEN*4];
   preprocess_string(buf,string,codepage);
-  return cur_strlist->add(buf,2);
+  return cur_strlist->add(buf,codepage, true, build_unicode);
 }
 
 int CEXEBuild::add_intstring(const int i) // returns offset in stringblock
@@ -483,6 +479,35 @@
   return add_string(i_str);
 }
 
+#ifdef _UNICODE
+char* convert_processed_string_to_ansi(char *out, const TCHAR *in, WORD codepage)
+{
+    const TCHAR *p=in;
+    for (;;)
+    {
+        _TUCHAR i = (_TUCHAR)*p++;
+        if (NS_IS_CODE(i)) // Note: this include '\0'
+        {
+            // convert all character up to, and including this code
+            int cb = WideCharToMultiByte(codepage, 0, in, p-in, out, (p-in)*2, NULL, \
NULL); +            out += cb;
+            if (i == _T('\0'))
+                break;
+            else if (i == NS_SKIP_CODE)
+                *out++ = (char) *in++; // simply copy escaped code (01..04)
+            else
+            {
+                WORD w = *p++; // special NSIS code is following by a WORD we need \
to output unchanged +                *out++ = LOBYTE(w);
+                *out++ = HIBYTE(w);
+            }
+            in = p;
+        }
+    }
+    return out;
+}
+#endif
+
 // based on Dave Laundon's code
 int CEXEBuild::preprocess_string(TCHAR *out, const TCHAR *in, WORD \
codepage/*=CP_ACP*/)  {
@@ -1498,7 +1523,7 @@
       else
       {
         // normal string
-        section_name = cur_strlist->get() + x;
+        section_name = cur_strlist->getTchar() + x;
       }
       if (x) wsprintf(fname,_T("%s section \"%s\" (%d)"),str,section_name,cnt);
       else wsprintf(fname,_T("unnamed %s section (%d)"),str,cnt);
@@ -2080,7 +2105,7 @@
 #define REMOVE_ICON(id) if (disable_window_icon) { \
     BYTE* dlg = res_editor->GetResource(RT_DIALOG, id, NSIS_DEFAULT_LANG); \
     if (dlg) { \
-      CDialogTemplate dt(dlg,uDefCodePage); \
+      CDialogTemplate dt(dlg,build_unicode,uDefCodePage); \
       res_editor->FreeResource(dlg); \
       if (dt.RemoveItem(IDC_ULICON)) { \
         DialogItemTemplate* text = dt.GetItem(IDC_INTROTEXT); \
@@ -2210,7 +2235,7 @@
 void CEXEBuild::PrepareHeaders(IGrowBuf *hdrbuf)
 {
   GrowBuf blocks_buf;
-  growbuf_writer_sink sink(&blocks_buf);
+  growbuf_writer_sink sink(&blocks_buf, build_unicode);
 
 #ifdef NSIS_CONFIG_VISIBLE_SUPPORT
   cur_header->blocks[NB_PAGES].offset = sizeof(header) + blocks_buf.getlen();
@@ -2224,7 +2249,12 @@
   entry_writer::write_block(cur_entries, &sink);
 
   cur_header->blocks[NB_STRINGS].offset = sizeof(header) + blocks_buf.getlen();
-  blocks_buf.add(cur_strlist->get(), cur_strlist->getcount()*sizeof(TCHAR));
+#ifdef _UNICODE
+  if (!build_unicode)
+      blocks_buf.add(cur_strlist->getAnsi(), cur_strlist->getcount());
+  else
+#endif
+    blocks_buf.add(cur_strlist->getTchar(), cur_strlist->getcount()*sizeof(TCHAR));
 
   cur_header->blocks[NB_LANGTABLES].offset = sizeof(header) + blocks_buf.getlen();
   lang_table_writer::write_block(cur_langtables, &sink, cur_header->langtable_size);
@@ -2244,7 +2274,7 @@
   }
 #endif
 
-  growbuf_writer_sink sink2(hdrbuf);
+  growbuf_writer_sink sink2(hdrbuf, build_unicode);
   header_writer header(&sink2);
   header.write(cur_header);
 
@@ -2259,7 +2289,8 @@
     VerifyDeclaredUserVarRefs(&m_UserVarNames);
     int MaxUserVars = m_UserVarNames.getnum();
     // -1 because the default size is 1
-    if (!res_editor->AddExtraVirtualSize2PESection(NSIS_VARS_SECTION, (MaxUserVars - \
1) * sizeof(NSIS_STRING))) +    int stringSize = \
NSIS_MAX_STRLEN*(build_unicode?sizeof(TCHAR):sizeof(char)); +    if \
(!res_editor->AddExtraVirtualSize2PESection(NSIS_VARS_SECTION, (MaxUserVars - 1) * \
stringSize))  {
       ERROR_MSG(_T("Internal compiler error #12346: invalid exehead cannot find \
section \"%s\"!\n"), _T(NSIS_VARS_SECTION));  return PS_ERROR;
@@ -2658,7 +2689,7 @@
   int ne=build_header.blocks[NB_ENTRIES].num;
   INFO_MSG(_T("%d instruction%s (%d bytes), \
"),ne,ne==1?_T(""):_T("s"),ne*sizeof(entry));  int ns=build_strlist.getnum();
-  INFO_MSG(_T("%d string%s (%d bytes), \
"),ns,ns==1?_T(""):_T("s"),build_strlist.getcount()*sizeof(TCHAR)); +  \
INFO_MSG(_T("%d string%s (%d bytes), \
"),ns,ns==1?_T(""):_T("s"),build_strlist.getcount()*(build_unicode ? sizeof(CHAR) : \
sizeof(TCHAR)));  int nlt=build_header.blocks[NB_LANGTABLES].num;
   INFO_MSG(_T("%d language table%s (%d \
bytes).\n"),nlt,nlt==1?_T(""):_T("s"),build_langtables.getlen());  if \
(ubuild_entries.getlen()) @@ -2687,7 +2718,7 @@
     ne=build_uninst.blocks[NB_ENTRIES].num;
     INFO_MSG(_T("%d instruction%s (%d bytes), \
"),ne,ne==1?_T(""):_T("s"),ubuild_entries.getlen());  ns=ubuild_strlist.getnum();
-    INFO_MSG(_T("%d string%s (%d bytes), \
"),ns,ns==1?_T(""):_T("s"),ubuild_strlist.getcount()*sizeof(TCHAR)); +    \
INFO_MSG(_T("%d string%s (%d bytes), \
"),ns,ns==1?_T(""):_T("s"),ubuild_strlist.getcount()*(build_unicode ? sizeof(CHAR) : \
sizeof(TCHAR)));  nlt=build_uninst.blocks[NB_LANGTABLES].num;
     INFO_MSG(_T("%d language table%s (%d \
bytes).\n"),nlt,nlt==1?_T(""):_T("s"),ubuild_langtables.getlen());  }
@@ -3014,7 +3045,7 @@
     MMapBuf udata;
 
     {
-      growbuf_writer_sink sink(&udata);
+      growbuf_writer_sink sink(&udata, build_unicode);
       firstheader_writer w(&sink);
       w.write(&fh);
     }
@@ -3532,12 +3563,40 @@
   }
 }
 
+#ifdef _UNICODE
+int CEXEBuild::set_build_unicode(bool unicode_installer)
+{
+  build_unicode = unicode_installer;
+  definedlist.del(_T("NSIS_UNICODE"));
+  definedlist.del(_T("NSIS_CHAR_SIZE"));
+  if (unicode_installer) // update defines depending on target installer type
+  {
+    definedlist.add(_T("NSIS_UNICODE"));
+    definedlist.add(_T("NSIS_CHAR_SIZE"), _T("2"));
+  }
+  else
+  {
+    definedlist.add(_T("NSIS_CHAR_SIZE"), _T("1"));
+  }
+  return load_stub();
+}
+#endif
+
 int CEXEBuild::set_compressor(const tstring& compressor, const bool solid) {
-  tstring stub = stubs_dir + PLATFORM_PATH_SEPARATOR_STR + compressor;
+  stub_filename = stubs_dir + PLATFORM_PATH_SEPARATOR_STR + compressor;
   if (solid)
-    stub += _T("_solid");
+    stub_filename += _T("_solid");
+  return load_stub();
+}
 
-  return update_exehead(stub, &m_exehead_original_size);
+int CEXEBuild::load_stub()
+{
+#ifdef _UNICODE
+  if (build_unicode)
+    return update_exehead(stub_filename+_T('W'), &m_exehead_original_size);
+  else
+#endif
+    return update_exehead(stub_filename, &m_exehead_original_size);
 }
 
 int CEXEBuild::update_exehead(const tstring& file, size_t *size/*=NULL*/) {

Modified: NSIS/trunk/Source/build.h
===================================================================
--- NSIS/trunk/Source/build.h	2010-06-11 16:33:10 UTC (rev 6099)
+++ NSIS/trunk/Source/build.h	2010-06-14 10:07:22 UTC (rev 6100)
@@ -136,7 +136,9 @@
     int prepare_uninstaller();
     int pack_exe_header();
 
+    int set_build_unicode(bool unicode_installer);
     int set_compressor(const tstring& compressor, const bool solid);
+    int load_stub();
     int update_exehead(const tstring& file, size_t *size=NULL);
     void update_exehead(const unsigned char *new_exehead, size_t new_size);
 
@@ -377,6 +379,7 @@
     // a whole bunch O data.
 
     tstring stubs_dir;
+    tstring stub_filename;
 
 #ifdef NSIS_CONFIG_COMPRESSION_SUPPORT
     ICompressor *compressor;
@@ -392,6 +395,7 @@
     int build_compress_dict_size;
 
     bool no_space_texts;
+    bool build_unicode;
 
     bool has_called_write_output;
 
@@ -442,7 +446,7 @@
     GrowBuf build_instruction_entry_map,ubuild_instruction_entry_map, \
*cur_instruction_entry_map;  TinyGrowBuf build_functions, ubuild_functions, \
*cur_functions;  TinyGrowBuf build_labels, ubuild_labels, *cur_labels;
-    StringList build_strlist, ubuild_strlist, *cur_strlist;
+    MLStringList build_strlist, ubuild_strlist, *cur_strlist;
     GrowBuf build_langtables, ubuild_langtables, *cur_langtables;
     TinyGrowBuf build_pages, ubuild_pages, *cur_pages;
     TinyGrowBuf build_ctlcolors, ubuild_ctlcolors, *cur_ctlcolors;

Modified: NSIS/trunk/Source/exehead/Ui.c
===================================================================
--- NSIS/trunk/Source/exehead/Ui.c	2010-06-11 16:33:10 UTC (rev 6099)
+++ NSIS/trunk/Source/exehead/Ui.c	2010-06-14 10:07:22 UTC (rev 6100)
@@ -722,7 +722,7 @@
   return 0;
 }
 #ifdef _UNICODE
-// on-the-fly conversion of Unicode to ANSI (because Windows don't recognize Unicode \
RTF data) +// on-the-fly conversion of Unicode to ANSI (because Windows doesn't \
recognize Unicode RTF data)  DWORD CALLBACK StreamLicenseRTF(DWORD dwCookie, LPBYTE \
pbBuff, LONG cb, LONG *pcb)  {
   size_t len = lstrlen(((LPWSTR) dwCookie)+dwRead);

Modified: NSIS/trunk/Source/exehead/fileform.h
===================================================================
--- NSIS/trunk/Source/exehead/fileform.h	2010-06-11 16:33:10 UTC (rev 6099)
+++ NSIS/trunk/Source/exehead/fileform.h	2010-06-14 10:07:22 UTC (rev 6100)
@@ -489,17 +489,10 @@
 
 // We are doing this to store an integer value into a char string and we
 // don't want false end of string values
-#if _UNICODE
-#define CODE_SHORT(x) ((WORD)x + 1)
-#define MAX_CODED 0xFFFE
-// This macro takes a pointer to WCHAR
-#define DECODE_SHORT(c) (c[0]-1)
-#else
 #define CODE_SHORT(x) (WORD)((((WORD)(x) & 0x7F) | (((WORD)(x) & 0x3F80) << 1) | \
0x8080))  #define MAX_CODED 0x3FFF
 // This macro takes a pointer to CHAR
-#define DECODE_SHORT(c) (((c[1] & 0x7F) << 7) | (c[0] & 0x7F))
-#endif
+#define DECODE_SHORT(c) (((((char*)c)[1] & 0x7F) << 7) | (((char*)c)[0] & 0x7F))
 
 #define NSIS_INSTDIR_INVALID 1
 #define NSIS_INSTDIR_NOT_ENOUGH_SPACE 2

Modified: NSIS/trunk/Source/lang.cpp
===================================================================
--- NSIS/trunk/Source/lang.cpp	2010-06-11 16:33:10 UTC (rev 6099)
+++ NSIS/trunk/Source/lang.cpp	2010-06-14 10:07:22 UTC (rev 6100)
@@ -381,15 +381,10 @@
     return table->nlf.m_szName;
   }
   else {
-	 // If the language table does not exist, then we default to Unicode in the
-	 // Unicode version and English in the ANSI version.
-#ifdef _UNICODE
+	 // If the language table does not exist, then we default to Unicode or ANSI
+	 // depending on the target installer type
     if (codepage)
-      *codepage = 1200; // Unicode
-#else
-    if (codepage)
-      *codepage = 1252; // ANSI CP1252
-#endif
+      *codepage = build_unicode ? 1200 : 1252; // Unicode or CP1252
 
     if (lang == 1033)
       return _T("English");
@@ -703,7 +698,7 @@
 #define ADD_FONT(id) { \
         BYTE* dlg = res_editor->GetResource(RT_DIALOG, id, NSIS_DEFAULT_LANG); \
         if (dlg) { \
-          CDialogTemplate td(dlg); \
+          CDialogTemplate td(dlg,build_unicode); \
           res_editor->FreeResource(dlg); \
           td.SetFont(build_font, (WORD) build_font_size); \
           DWORD dwSize; \
@@ -758,7 +753,7 @@
 #define ADD_FONT(id) { \
           BYTE* dlg = res_editor->GetResource(RT_DIALOG, id, NSIS_DEFAULT_LANG); \
           if (dlg) { \
-            CDialogTemplate td(dlg,lt[i].nlf.m_uCodePage); \
+            CDialogTemplate td(dlg,build_unicode,lt[i].nlf.m_uCodePage); \
             res_editor->FreeResource(dlg); \
             if (font) td.SetFont(font, (WORD) lt[i].nlf.m_iFontSize); \
             if (lt[i].nlf.m_bRTL) { \

Modified: NSIS/trunk/Source/script.cpp
===================================================================
--- NSIS/trunk/Source/script.cpp	2010-06-11 16:33:10 UTC (rev 6099)
+++ NSIS/trunk/Source/script.cpp	2010-06-14 10:07:22 UTC (rev 6100)
@@ -867,12 +867,10 @@
   }
   if (!memcmp(data+1,_T("{\\rtf"),5*sizeof(TCHAR)))
     *data = SF_RTF;
+  else if (unicode)
+    *data = SF_TEXT|SF_UNICODE;
   else
-#ifdef _UNICODE
-    *data = SF_TEXT|SF_UNICODE;
-#else
     *data = SF_TEXT;
-#endif
   return PS_OK;
 }
 
@@ -2155,7 +2153,7 @@
 
           BYTE* dlg = res_editor->GetResource(RT_DIALOG, IDD_INSTFILES, \
NSIS_DEFAULT_LANG);  if (!dlg) throw runtime_error("IDD_INSTFILES doesn't exist!");
-          CDialogTemplate dt(dlg,uDefCodePage);
+          CDialogTemplate dt(dlg,build_unicode,uDefCodePage);
           free(dlg);
           DialogItemTemplate* progress = dt.GetItem(IDC_PROGRESS);
           if (!progress) {
@@ -2448,7 +2446,7 @@
         init_res_editor();
 
         // Search for required items
-        #define GET(x) dlg = uire->GetResource(RT_DIALOG, x, 0); if (!dlg) return \
PS_ERROR; CDialogTemplate UIDlg(dlg, uDefCodePage); +        #define GET(x) dlg = \
uire->GetResource(RT_DIALOG, x, 0); if (!dlg) return PS_ERROR; CDialogTemplate \
UIDlg(dlg, build_unicode, uDefCodePage);  #define SEARCH(x) if (!UIDlg.GetItem(x)) \
{ERROR_MSG(_T("Error: Can't find %s (%u) in the custom UI!\n"), _T(#x), x);delete [] \
                dlg;delete uire;return PS_ERROR;}
         #define SAVE(x) dwSize = UIDlg.GetSize(); \
res_editor->UpdateResource(RT_DIALOG, x, NSIS_DEFAULT_LANG, dlg, dwSize); delete [] \
dlg;  
@@ -2568,7 +2566,7 @@
         init_res_editor();
         BYTE* dlg = res_editor->GetResource(RT_DIALOG, IDD_INST, NSIS_DEFAULT_LANG);
 
-        CDialogTemplate dt(dlg, uDefCodePage);
+        CDialogTemplate dt(dlg, build_unicode, uDefCodePage);
 
         res_editor->FreeResource(dlg);
 
@@ -2687,6 +2685,25 @@
     }
     return PS_OK;
 
+#ifdef _UNICODE
+    case TOK_UNICODEINSTALLER:
+    {
+      if (build_compressor_set) {
+        ERROR_MSG(_T("Error: can't change type of installer after data already got \
compressed or header already changed!\n")); +        return PS_ERROR;
+      }
+      int param=line.gettoken_enum(1,_T("off\0on\0"));
+      if (param==-1) PRINTHELP()
+      SCRIPT_MSG(_T("UnicodeInstaller: %s\n"),line.gettoken_str(1));
+      if (set_build_unicode(param != 0) != PS_OK)
+      {
+        ERROR_MSG(_T("Error: error while setting type of installer! (stub not \
found?)\n")); +        return PS_ERROR;
+      }
+    }
+    return PS_OK;
+#endif
+
     // Ability to change compression methods from within the script
     case TOK_SETCOMPRESSOR:
 #ifdef NSIS_CONFIG_COMPRESSION_SUPPORT
@@ -3681,7 +3698,7 @@
           init_res_editor();
 
           BYTE* dlg = res_editor->GetResource(RT_DIALOG, IDD_INST, \
                NSIS_DEFAULT_LANG);
-          CDialogTemplate td(dlg,uDefCodePage);
+          CDialogTemplate td(dlg,build_unicode,uDefCodePage);
           free(dlg);
 
           if (trim) {
@@ -5913,8 +5930,13 @@
     {
       int ret;
 
-      const tstring command = m_plugins.NormalizedCommand(line.gettoken_str(0));
-      const tstring dllPath = m_plugins.GetPluginPath(command);
+      tstring command = m_plugins.NormalizedCommand(line.gettoken_str(0));
+#ifdef _UNICODE
+      if (build_unicode)
+        command = m_plugins.UseUnicodeVariant(command);
+#endif
+      tstring dllPath = m_plugins.GetPluginPath(command);
+      tstring dllName = get_file_name(dllPath);
       int data_handle = m_plugins.GetPluginHandle(uninstall_mode?true:false, \
command);  
       if (uninstall_mode) uninst_plugin_used = true;
@@ -5930,7 +5952,6 @@
 
       // DLL name on the user machine
       TCHAR tempDLL[NSIS_MAX_STRLEN];
-      tstring dllName = get_file_name(dllPath);
       wsprintf(tempDLL, _T("$PLUGINSDIR\\%s"), dllName.c_str());
 
       // Add the DLL to the installer

Modified: NSIS/trunk/Source/strlist.cpp
===================================================================
--- NSIS/trunk/Source/strlist.cpp	2010-06-11 16:33:10 UTC (rev 6099)
+++ NSIS/trunk/Source/strlist.cpp	2010-06-14 10:07:22 UTC (rev 6100)
@@ -18,6 +18,97 @@
 
 #include "strlist.h"
 
+MLStringList::MLStringList()
+{
+    m_gr.set_zeroing(1);
+#ifdef _UNICODE
+    m_grAnsi.set_zeroing(1);
+#endif
+}
+
+#ifdef _UNICODE
+char* convert_processed_string_to_ansi(char *out, const TCHAR *in, WORD codepage); \
// defined in build.cpp +
+// use 2 for case sensitive end-of-string matches too
+int MLStringList::findAnsi(const char *str, int case_sensitive) const // returns -1 \
if not found +{
+  const char *s=(const char*) m_grAnsi.get();
+  int ml=getcount();
+  int offs=0;
+
+  size_t str_slen = strlen(str);
+  size_t offs_slen;
+
+  while (offs < ml)
+  {
+    // Check if the whole string matches str.
+    if ((case_sensitive && !strcmp(s+offs,str)) ||
+        (!case_sensitive && !stricmp(s+offs,str)))
+    {
+      return offs;
+    }
+
+    offs_slen = strlen(s+offs);
+
+    // Check if just the end of the string matches str.
+    if (case_sensitive==2 &&
+        str_slen < offs_slen &&  // check for end of string
+        !strcmp(s + offs + offs_slen - str_slen,str))
+    {
+      return offs + offs_slen - str_slen;
+    }
+    offs += offs_slen + 1;
+  }
+  return -1;
+}
+#endif
+
+int MLStringList::add(const TCHAR *str, WORD codepage /*= CP_ACP*/, bool processed, \
bool build_unicode) +{
+#ifndef _UNICODE
+  int a=find(str,2);
+  if (a >= 0)
+      return a;
+  int len = _tcslen(str)+1;
+  return m_gr.add(str,len*sizeof(TCHAR))/sizeof(TCHAR);
+#else
+  if (build_unicode)
+  {
+    int a=find(str,2);
+    if (a >= 0)
+      return a;
+  }
+  // convert to ANSI
+  int len = _tcslen(str)+1;
+  char* ansiBuf = new char[len*2];
+  int cbMultiByte;
+  if (processed)
+    cbMultiByte = convert_processed_string_to_ansi(ansiBuf, str, codepage)-ansiBuf;
+  else
+    cbMultiByte = WideCharToMultiByte(codepage, 0, str, len, ansiBuf, len*2, NULL, \
NULL); +  if (!build_unicode)
+  {
+    int a=findAnsi(ansiBuf,2);
+    if (a >= 0)
+    {
+      delete[] ansiBuf;
+      return a;
+    }
+  }
+  // string not found, add it
+  int a=m_gr.add(str,len*sizeof(TCHAR))/sizeof(TCHAR);
+  m_grAnsi.add(ansiBuf,cbMultiByte);
+  delete[] ansiBuf;
+  if (len != cbMultiByte)
+  { // resize buffers to align future strings on same offsets
+    len = a+max(len,cbMultiByte);
+    m_gr.resize(len*sizeof(TCHAR));
+    m_grAnsi.resize(len);
+  }
+  return a;
+#endif
+}
+
 int StringList::add(const TCHAR *str, int case_sensitive)
 {
   int a=find(str,case_sensitive);
@@ -103,16 +194,7 @@
   return idx;
 }
 
-const TCHAR *StringList::get() const
-{
-  return (const TCHAR*) m_gr.get();
-}
 
-int StringList::getcount() const
-{
-	return m_gr.getlen() / sizeof(TCHAR);
-}
-
 // ==========
 // DefineList
 // ==========

Modified: NSIS/trunk/Source/strlist.h
===================================================================
--- NSIS/trunk/Source/strlist.h	2010-06-11 16:33:10 UTC (rev 6099)
+++ NSIS/trunk/Source/strlist.h	2010-06-14 10:07:22 UTC (rev 6100)
@@ -104,19 +104,44 @@
 	* Get the buffer straight as a const TCHAR pointer.  Very unwise to use.
 	* @return m_gr.m_s cast as a TCHAR*.
 	*/
-  const TCHAR *get() const;
+  const TCHAR *get() const { return (const TCHAR*) m_gr.get(); }
 
   /**
 	* Get the buffer size (number of TCHARs).
 	* @return The buffer size (number of TCHARs).
 	*/
-  int getcount() const;
+  int getcount() const { return m_gr.getlen() / sizeof(TCHAR); }
 
-private:
+protected:
   GrowBuf m_gr;
 };
 
 /**
+ * Similar to StringList with case_sensitive=2, but stores strings as both Unicode \
AND ANSI (codepaged) + */
+class MLStringList : private StringList
+{
+private: // don't copy instances
+  MLStringList(const MLStringList&);
+  void operator=(const MLStringList&);
+
+public:
+  MLStringList();
+  ~MLStringList() {}
+
+  int add(const TCHAR *str, WORD codepage, bool processed, bool build_unicode);
+  int getnum() const                { return StringList::getnum(); }
+  int getcount() const              { return StringList::getcount(); }
+  const TCHAR *getTchar() const     { return (const TCHAR*) m_gr.get(); }
+#ifdef _UNICODE
+  const char *getAnsi() const       { return (const char*) m_grAnsi.get(); }
+  int findAnsi(const char *str, int case_sensitive) const;
+private:
+  GrowBuf m_grAnsi;
+#endif
+};
+
+/**
  * This class maintains a list of T types in a GrowBuf sorted by T.name which
  * is assumed to be a string (TCHAR*).  So it's really sort of a 
  * map<TCHAR*, X> where X is whatever else is defined in T.  But T must define

Modified: NSIS/trunk/Source/tokens.cpp
===================================================================
--- NSIS/trunk/Source/tokens.cpp	2010-06-11 16:33:10 UTC (rev 6099)
+++ NSIS/trunk/Source/tokens.cpp	2010-06-14 10:07:22 UTC (rev 6100)
@@ -216,6 +216,9 @@
 {TOK_STRCPY,_T("StrCpy"),2,2,_T("$(user_var: output) str [maxlen] \
[startoffset]"),TP_CODE},  {TOK_STRLEN,_T("StrLen"),2,0,_T("$(user_var: length \
output) str"),TP_CODE},  {TOK_SUBCAPTION,_T("SubCaption"),2,0,_T("page_number(0-4) \
new_subcaption"),TP_GLOBAL}, +#ifdef _UNICODE
+{TOK_UNICODEINSTALLER,_T("UnicodeInstaller"),1,0,_T("(on|off)"),TP_GLOBAL},
+#endif
 {TOK_UNINSTALLEXENAME,_T("UninstallExeName"),0,0,_T("no longer supported, use \
WriteUninstaller from section."),TP_ALL},  \
{TOK_UNINSTCAPTION,_T("UninstallCaption"),1,0,_T("uninstaller_caption"),TP_GLOBAL},  \
{TOK_UNINSTICON,_T("UninstallIcon"),1,0,_T("icon_on_local_system.ico"),TP_GLOBAL},

Modified: NSIS/trunk/Source/tokens.h
===================================================================
--- NSIS/trunk/Source/tokens.h	2010-06-11 16:33:10 UTC (rev 6099)
+++ NSIS/trunk/Source/tokens.h	2010-06-14 10:07:22 UTC (rev 6100)
@@ -70,6 +70,9 @@
   TOK_DEFVAR,
   TOK_VI_ADDKEY,
   TOK_VI_SETPRODUCTVERSION,
+#ifdef _UNICODE
+  TOK_UNICODEINSTALLER,
+#endif
 
   TOK_MISCBUTTONTEXT,
   TOK_DETAILSBUTTONTEXT,

Modified: NSIS/trunk/Source/writer.cpp
===================================================================
--- NSIS/trunk/Source/writer.cpp	2010-06-11 16:33:10 UTC (rev 6099)
+++ NSIS/trunk/Source/writer.cpp	2010-06-14 10:07:22 UTC (rev 6100)
@@ -54,18 +54,29 @@
 void writer_sink::write_string(const TCHAR *s, size_t size)
 {
 #ifdef _UNICODE
-  bool strEnd = false;
-  TCHAR ch;
-  for (; size ; size--)
+  if (m_build_unicode)
   {
-    if (!strEnd)
+    bool strEnd = false;
+    TCHAR ch;
+    for (; size ; size--)
     {
-      ch = *s++;
-      if (ch == _T('\0'))
-        strEnd = true;
+      if (!strEnd)
+      {
+        ch = *s++;
+        if (ch == _T('\0'))
+          strEnd = true;
+      }
+      write_short(ch);
     }
-    write_short(ch);
   }
+  else
+  {
+    char *wb = new char[size];
+    memset(wb, 0, size);
+    WideCharToMultiByte(CP_ACP, 0, s, -1, wb, size, NULL, NULL);
+    write_data(wb, size);
+    delete [] wb;
+ }
 #else
   char *wb = new char[size];
   memset(wb, 0, size);

Modified: NSIS/trunk/Source/writer.h
===================================================================
--- NSIS/trunk/Source/writer.h	2010-06-11 16:33:10 UTC (rev 6099)
+++ NSIS/trunk/Source/writer.h	2010-06-14 10:07:22 UTC (rev 6100)
@@ -27,7 +27,7 @@
 
 class writer_sink {
 public:
-  writer_sink() {}
+  writer_sink() : m_build_unicode(false) {}
   virtual ~writer_sink() {}
 
   virtual void write_byte(const unsigned char b);
@@ -38,7 +38,8 @@
   virtual void write_growbuf(const IGrowBuf *b);
 
   virtual void write_data(const void *data, const size_t size) = 0;
-
+protected:
+  bool m_build_unicode;
 };
 
 class writer {
@@ -53,7 +54,7 @@
 
 class growbuf_writer_sink : public writer_sink {
 public:
-  growbuf_writer_sink(IGrowBuf *buf) : m_buf(buf) {}
+  growbuf_writer_sink(IGrowBuf *buf, bool build_unicode) : m_buf(buf) { \
m_build_unicode=build_unicode; }  
   virtual void write_data(const void *data, const size_t size);
 


This was sent by the SourceForge.net collaborative development platform, the world's \
largest Open Source development site.

------------------------------------------------------------------------------
ThinkGeek and WIRED's GeekDad team up for the Ultimate 
GeekDad Father's Day Giveaway. ONE MASSIVE PRIZE to the 
lucky parental unit.  See the prize list and enter to win: 
http://p.sf.net/sfu/thinkgeek-promo
_______________________________________________
NSIS-commits mailing list
NSIS-commits@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/nsis-commits


[prev in list] [next in list] [prev in thread] [next in thread] 

Configure | About | News | Add a list | Sponsored by KoreLogic