Source code used: nsis-code-6415-NSIS-trunk

Command line used: scons SKIPSTUBS=all SKIPPLUGINS=all SKIPUTILS=all SKIPMISC=all

Diff patch used:

	

    Index: Source/DialogTemplate.cpp
    ===================================================================
    --- Source/DialogTemplate.cpp   (revision 6411)
    +++ Source/DialogTemplate.cpp   (working copy)
    @@ -46,7 +46,7 @@
     #define ALIGN(dwToAlign, dwAlignOn) dwToAlign = (dwToAlign%dwAlignOn == 0) ? dwToAlign : dwToAlign - (dwToAlign%dwAlignOn) + dwAlignOn
     
     // Reads a variant length array from seeker into readInto and advances seeker
    -void ReadVarLenArr(LPBYTE &seeker, WCHAR* &readInto, unsigned int uCodePage) {
    +void ReadVarLenArr(LPBYTE &seeker, WINWCHAR* &readInto, unsigned int uCodePage) {
       WORD* arr = (WORD*)seeker;
       switch (ConvertEndianness(arr[0])) {
       case 0x0000:
    @@ -59,8 +59,8 @@
         break;
       default:
         {
    -      readInto = wcsdup((WCHAR *) arr);
    -      PWCHAR wseeker = PWCHAR(seeker);
    +      readInto = WinWStrDupFromWinWStr((WINWCHAR *) arr);
    +      WINWCHAR *wseeker = (WINWCHAR* ) seeker;
           while (*wseeker++);
           seeker = LPBYTE(wseeker);
         }
    @@ -78,14 +78,14 @@
           seeker += sizeof(WORD); \
         } \
         else { \
    -      wcscpy((WCHAR *) seeker, x); \
    -      seeker += wcslen((WCHAR *) seeker) * sizeof(WCHAR) + sizeof(WCHAR); \
    +      WinWStrCpy((WCHAR *) seeker, x); \
    +      seeker += WinWStrLen((WCHAR *) seeker) * sizeof(WCHAR) + sizeof(WCHAR); \
         } \
       else \
         seeker += sizeof(WORD);
     
     // A macro that adds the size of x (which can be a string a number, or nothing) to dwSize
    -#define AddStringOrIdSize(x) dwSize += x ? (IS_INTRESOURCE(x) ? sizeof(DWORD) : (wcslen(x) + 1) * sizeof(WCHAR)) : sizeof(WORD)
    +#define AddStringOrIdSize(x) dwSize += x ? (IS_INTRESOURCE(x) ? sizeof(DWORD) : (WinWStrLen(x) + 1) * sizeof(WCHAR)) : sizeof(WORD)
     
     //////////////////////////////////////////////////////////////////////
     // Construction/Destruction
    @@ -220,23 +220,22 @@
       }
     }
     
    +static void free_template_string(WCHAR*s)
    +{
    +  if (s && !IS_INTRESOURCE(s)) free(s);
    +}
    +
     CDialogTemplate::~CDialogTemplate() {
    -  if (m_szMenu && !IS_INTRESOURCE(m_szMenu))
    -    delete [] m_szMenu;
    -  if (m_szClass && !IS_INTRESOURCE(m_szClass))
    -    delete [] m_szClass;
    -  if (m_szTitle)
    -    delete [] m_szTitle;
    -  if (m_szFont)
    -    free(m_szFont);
    +  free_template_string(m_szMenu);
    +  free_template_string(m_szClass);
    +  free(m_szTitle);
    +  free(m_szFont);
     
       for (unsigned int i = 0; i < m_vItems.size(); i++) {
    -    if (m_vItems[i]->szClass && !IS_INTRESOURCE(m_vItems[i]->szClass))
    -      delete [] m_vItems[i]->szClass;
    -    if (m_vItems[i]->szTitle && !IS_INTRESOURCE(m_vItems[i]->szTitle))
    -      delete [] m_vItems[i]->szTitle;
    -    if (m_vItems[i]->szCreationData)
    -      delete [] m_vItems[i]->szCreationData;
    +    free_template_string(m_vItems[i]->szClass);
    +    free_template_string(m_vItems[i]->szTitle);
    +    if (m_vItems[i]->szCreationData) delete [] m_vItems[i]->szCreationData;
    +    //BUGBUG: delete m_vItems[i];?
       }
     }
     
    @@ -293,7 +292,7 @@
       m_bCharset = DEFAULT_CHARSET;
       m_dwStyle |= DS_SETFONT;
       if (m_szFont) free(m_szFont);
    -  m_szFont = wcsdup_fromTchar(szFaceName, m_uCodePage);
    +  m_szFont = WinWStrDupFromTChar(szFaceName, m_uCodePage);
       m_sFontSize = wFontSize;
     }
     
    @@ -303,10 +302,10 @@
       CopyMemory(newItem, &item, sizeof(DialogItemTemplate));
     
       if (item.szClass && !IS_INTRESOURCE(item.szClass)) {
    -    newItem->szClass = _wcsdup(item.szClass);
    +    newItem->szClass = WinWStrDupFromWinWStr(item.szClass);
       }
       if (item.szTitle && !IS_INTRESOURCE(item.szTitle)) {
    -    newItem->szTitle = _wcsdup(item.szTitle);
    +    newItem->szTitle = WinWStrDupFromWinWStr(item.szTitle);
       }
       if (item.wCreateDataSize) {
         newItem->szCreationData = new char[item.wCreateDataSize];
    @@ -475,18 +474,18 @@
             m_vItems[i]->dwStyle |= SS_CENTERIMAGE;
           }
         }
    -    else if (!IS_INTRESOURCE(m_vItems[i]->szClass) && !_wcsnicmp(m_vItems[i]->szClass, L"RichEdit20", 10)) {
    +    else if (!IS_INTRESOURCE(m_vItems[i]->szClass) && !WinWStrNICmpASCII(m_vItems[i]->szClass, "RichEdit20", 10)) {
           if ((m_vItems[i]->dwStyle & ES_CENTER) == 0) {
             m_vItems[i]->dwStyle ^= ES_RIGHT;
           }
         }
    -    else if (!IS_INTRESOURCE(m_vItems[i]->szClass) && !_wcsicmp(m_vItems[i]->szClass, L"SysTreeView32")) {
    +    else if (!IS_INTRESOURCE(m_vItems[i]->szClass) && !WinWStrICmpASCII(m_vItems[i]->szClass, "SysTreeView32")) {
           m_vItems[i]->dwStyle |= TVS_RTLREADING;
           m_vItems[i]->dwExtStyle |= WS_EX_LAYOUTRTL;
           addExStyle = true;
           addExLeftScrollbar = false;
         }
    -    else if (!IS_INTRESOURCE(m_vItems[i]->szClass) && !_wcsicmp(m_vItems[i]->szClass, L"SysListView32")) {
    +    else if (!IS_INTRESOURCE(m_vItems[i]->szClass) && !WinWStrICmpASCII(m_vItems[i]->szClass, "SysListView32")) {
           m_vItems[i]->dwExtStyle |= WS_EX_LAYOUTRTL;
           addExLeftScrollbar = false;
         }
    @@ -605,10 +604,12 @@
         // Write class variant length array
         const WCHAR *szClass = m_vItems[i]->szClass;
     #ifdef _UNICODE
    +    static const WCHAR clsRE20W[] = {'R','i','c','h','E','d','i','t','2','0','W',0};
    +    static const WCHAR clsRE20A[] = {'R','i','c','h','E','d','i','t','2','0','A',0};
         if (!IS_INTRESOURCE(szClass)) {
           // transmute RichEdit20A/W control into RichEdit20T that matches the target
    -      if (m_build_unicode && !_wcsicmp(szClass, L"RichEdit20A")) szClass = L"RichEdit20W";
    -      if (!m_build_unicode && !_wcsicmp(szClass, L"RichEdit20W")) szClass = L"RichEdit20A";
    +      if (m_build_unicode && !WinWStrICmpASCII(szClass, "RichEdit20A")) szClass = clsRE20W;
    +      if (!m_build_unicode && !WinWStrICmpASCII(szClass, "RichEdit20W")) szClass = clsRE20A;
         }
     #endif
         WriteStringOrId(szClass);
    Index: Source/script.cpp
    ===================================================================
    --- Source/script.cpp   (revision 6414)
    +++ Source/script.cpp   (working copy)
    @@ -2693,7 +2693,7 @@
                     check = true;
                   }
                 } else {
    -              check = _wcsicmp(dlgItem->szClass, L"Static") == 0;
    +              check = WinWStrICmpASCII(dlgItem->szClass, "Static") == 0;
                 }
     
                 if (check) {
    @@ -3222,12 +3222,7 @@
             int cmpv=line.gettoken_int(3,&success);
             if (!success && comp != 4) PRINTHELP()
             SCRIPT_MSG(_T("!system: \"%s\"\n"),exec);
    -#ifdef _WIN32
             int ret=sane_system(exec);
    -#else
    -        PATH_CONVERT(exec);
    -        int ret=system(exec);
    -#endif
             if (comp == 0 && ret < cmpv);
             else if (comp == 1 && ret > cmpv);
             else if (comp == 2 && ret != cmpv);
    @@ -3259,9 +3254,7 @@
             }
     #endif
     #else
    -        TCHAR *execfixed = my_convert(exec);
    -        system(execfixed);
    -        my_convert_free(execfixed);
    +        sane_system(exec);
     #endif
           }
         case TOK_P_ADDINCLUDEDIR:
    Index: Source/utf.cpp
    ===================================================================
    --- Source/utf.cpp      (revision 6415)
    +++ Source/utf.cpp      (working copy)
    @@ -212,10 +212,10 @@
       {
         if (NStreamEncoding::UTF16BE == m_TE) goto l_swapUTF16;
         cbSrc /= sizeof(wchar_t);
    -    UINT cbDest = WideCharToMultiByte(m_TE, 0, (LPWSTR)Src, cbSrc, 0, 0, 0, 0);
    +    UINT cbDest = WideCharToMultiByte(m_TE, 0, (wchar_t*)Src, cbSrc, 0, 0, 0, 0);
         char *p = (char*) realloc(m_Result, (cbDest + 1) * sizeof(char));
         if (p) m_Result = p; else return 0;
    -    if (!(cbDest = WideCharToMultiByte(m_TE, 0, (LPWSTR)Src, cbSrc, p, cbDest, 0, 0))) return 0;
    +    if (!(cbDest = WideCharToMultiByte(m_TE, 0, (wchar_t*)Src, cbSrc, p, cbDest, 0, 0))) return 0;
         if (p[--cbDest]) p[++cbDest] = '\0'; // Always \0 terminate
         if (cbOut) *cbOut = cbDest; // cbOut never includes the \0 terminator
       }
    @@ -253,7 +253,7 @@
     }
     
     #if !defined(_WIN32) || !defined(_UNICODE)
    -bool WCToUTF16LEHlpr::Create(const TCHAR*in)
    +bool WCToUTF16LEHlpr::Create(const TCHAR*in, unsigned int codepage)
     {
       CharEncConv cec;
       if (!cec.Initialize(NStreamEncoding::UTF16LE, -1)) return false;
    Index: Source/build.h
    ===================================================================
    --- Source/build.h      (revision 6413)
    +++ Source/build.h      (working copy)
    @@ -143,7 +143,7 @@
     
         DefineList definedlist; // List of identifiers marked as "defined" like
                                 // C++ macro definitions such as _UNICODE.
    -    void define(const TCHAR *p, const TCHAR *v=TEXT("")); // to add a defined thing.
    +    void define(const TCHAR *p, const TCHAR *v=_T("")); // to add a defined thing.
     
         int display_errors;
         int display_script;
    Index: Source/build.cpp
    ===================================================================
    --- Source/build.cpp    (revision 6413)
    +++ Source/build.cpp    (working copy)
    @@ -2944,12 +2944,12 @@
       {
         for (struct postbuild_cmd *cmd=postbuild_cmds; cmd; cmd = cmd->next)
         {
    -      LPTSTR cmdstr = cmd->cmd, cmdstrbuf = NULL;
    -      LPTSTR arg = _tcsstr(cmdstr, _T("%1"));
    +      TCHAR *cmdstr = cmd->cmd, *cmdstrbuf = NULL;
    +      TCHAR *arg = _tcsstr(cmdstr, _T("%1"));
           if (arg)    // if found, replace %1 by build_output_filename
           {
             const UINT cchbldoutfile = _tcslen(build_output_filename);
    -        cmdstrbuf = (LPTSTR) malloc( (_tcslen(cmdstr) + cchbldoutfile + 1)*sizeof(TCHAR) );
    +        cmdstrbuf = (TCHAR*) malloc( (_tcslen(cmdstr) + cchbldoutfile + 1)*sizeof(TCHAR) );
             if (!cmdstrbuf)
             {
               ERROR_MSG(_T("Error: can't allocate memory for finalize command\n"));
    @@ -2960,17 +2960,12 @@
             cmdstr = cmdstrbuf;
             memmove(arg+cchbldoutfile, arg+2, (_tcslen(arg+2)+1)*sizeof(TCHAR));
             memmove(arg, build_output_filename, cchbldoutfile*sizeof(TCHAR));
    +        //BUGBUG: Should we call PathConvertWinToPosix on build_output_filename?
           }
     
           SCRIPT_MSG(_T("\nFinalize command: %s\n"),cmdstr);
    -#ifdef _WIN32
    -      int ret=sane_system(cmdstr);
    -#else
    -      PATH_CONVERT(cmdstr);
    -      int ret=system(cmdstr);
    -#endif
    -      if (ret != 0)
    -        INFO_MSG(_T("Finalize command returned %d\n"),ret);
    +      int ret = sane_system(cmdstr);
    +      if (ret != 0) INFO_MSG(_T("Finalize command returned %d\n"),ret);
           free(cmdstrbuf);
         }
       }
    Index: Source/utf.h
    ===================================================================
    --- Source/utf.h        (revision 6415)
    +++ Source/utf.h        (working copy)
    @@ -141,7 +141,7 @@
     public:
       WCToUTF16LEHlpr() : m_s(0) {}
     
    -  bool Create(const TCHAR*in)
    +  bool Create(const TCHAR*in, unsigned int codepage = CP_ACP)
     #if !defined(_WIN32) || !defined(_UNICODE)
       ;
     #else
    @@ -159,6 +159,8 @@
       const unsigned short* Get() const { return m_s; }
       UINT GetLen() const { return StrLenUTF16(m_s); }
       UINT GetSize() const { return (GetLen()+1) * 2; }
    +  unsigned short* Detach() { unsigned short *r = m_s; m_s = 0; return r; }
    +  void CopyTo(unsigned short*Dest) const { memcpy(Dest, Get(), GetSize()); }
     };
     
     class NStreamEncoding {
    Index: Source/makenssi.cpp
    ===================================================================
    --- Source/makenssi.cpp (revision 6392)
    +++ Source/makenssi.cpp (working copy)
    @@ -29,6 +29,7 @@
     #include "build.h"
     #include "util.h"
     #include "utf.h"
    +#include "winchar.h"
     
     #include <nsis-version.h>
     #include <fcntl.h>
    @@ -276,7 +277,9 @@
     #ifdef NSIS_HPUX_ALLOW_UNALIGNED_DATA_ACCESS
       allow_unaligned_data_access();
     #endif
    -  assert(sizeof(wchar_t) > 1 && sizeof(wchar_t) <= 4 && sizeof(WORD) == 2);
    +  assert(sizeof(wchar_t) > 1 && sizeof(wchar_t) <= 4);
    +  assert(sizeof(WINWCHAR) == 2 && sizeof(WORD) == 2);
    +  assert(sizeof(WINWCHAR) == sizeof(WCHAR));
     
       HWND hostnotifyhandle=0;
       const TCHAR*stdoutredirname=0;
    @@ -479,10 +482,8 @@
               {HIGH_PRIORITY_CLASS,         HIGH_PRIORITY_CLASS},
               {REALTIME_PRIORITY_CLASS,     REALTIME_PRIORITY_CLASS}
             };
    -        if (SetPriorityClass(hProc, classes[p].priority) == FALSE)
    -        {
    +        if (!SetPriorityClass(hProc, classes[p].priority))
               SetPriorityClass(hProc, classes[p].fallback);
    -        }
             if (p == 5) build.warning(_T("makensis is running in REALTIME priority mode!"));
     #else
             build.warning(badnonwinswitchfmt,_T("Px"));
    Index: Source/util.cpp
    ===================================================================
    --- Source/util.cpp     (revision 6398)
    +++ Source/util.cpp     (working copy)
    @@ -34,6 +34,11 @@
     #  include <fcntl.h> // for open(2)
     #  include <iconv.h>
     #  include <locale.h>
    +#  include <stdlib.h>
    +#  include <limits.h>
    +#  ifdef _UNICODE
    +#    include <wchar.h>
    +#  endif
     #endif
     
     #ifdef __APPLE__
    @@ -152,6 +157,12 @@
     }
     
     #ifndef _WIN32
    +BOOL IsDBCSLeadByteEx(unsigned int CodePage, unsigned char TestChar)
    +{
    +  if (CP_UTF8 == CodePage) return false; //blogs.msdn.com/b/michkap/archive/2007/04/19/2190207.aspx
    +  const char buf[] = {(char)TestChar, 'a', 'b', '\0'}; // Untested and probably not the best way to do this!
    +  return CharNextExA(CodePage, buf, 0) > &buf[1];
    +}
     TCHAR *CharPrev(const TCHAR *s, const TCHAR *p) {
       if (!s || !p || p < s)
         return NULL;
    @@ -171,25 +182,21 @@
       return (char *) s + l;
     }
     
    -WCHAR *CharNextW(const WCHAR *s) {
    -  // BUGBUG: Is this the best we can do?
    +wchar_t *CharNextW(const wchar_t *s) {
    +  if (sizeof(*s)==2 && IsLeadSurrogateUTF16(*s)) ++s; //BUGBUG: This assumes that 16bit wchar_t == UTF16
    +  // else if(...) BUGBUG: Is this the best we can do? What about combining characters/diacritics etc?
       return s + 1;
     }
     
     char *CharNextExA(WORD codepage, const char *s, int flags) {
    +  // blogs.msdn.com/b/michkap/archive/2007/04/19/2190207.aspx implies that
    +  // CharNextExA uses IsDBCSLeadByteEx, should we do the same?
       char buf[30];
       snprintf(buf, 30, "CP%d", codepage);
    -  const char* orglocct = setlocale(LC_CTYPE, buf);
    -
    -  const char* np;
    +  const char* orglocct = setlocale(LC_CTYPE, buf), *np;
       int len = mblen(s, strlen(s));
    -  if (len > 0)
    -    np = s + len;
    -  else
    -    np = s + 1;
    -
    +  if (len > 0) np = s + len; else np = s + 1;
       setlocale(LC_CTYPE, orglocct);
    -
       return (char *) np;
     }
     
    @@ -201,6 +208,93 @@
       return res;
     }
     
    +void PathConvertWinToPosix(char*p);
    +#define NSISRT_free free
    +static char* NSISRT_wctomb(const wchar_t *Str, bool ConvPath = false)
    +{
    +  const char *orglocct = setlocale(LC_CTYPE, "");
    +  char *d = 0;
    +  const wchar_t *s = Str;
    +  errno = 0;
    +  size_t cb = wcsrtombs(0, &s, 0, 0);
    +  if ((size_t) -1 != cb && (d = (char*) malloc(++cb)))
    +  {
    +    cb = wcsrtombs(d, &Str, cb, 0);
    +    if ((size_t) -1 == cb) { NSISRT_free(d); d = 0; }
    +  }
    +  if (!errno) errno = ENOMEM;
    +  if (ConvPath && d) PathConvertWinToPosix(d);
    +  setlocale(LC_CTYPE, orglocct);
    +  return d;
    +}
    +
    +#include <wctype.h>
    +int _wcsnicmp(const wchar_t *a, const wchar_t *b, size_t n)
    +{
    +  // TODO: POSIX has strcasecmp(), can we use that? POSIX locale issues?
    +  for ( int diff ; n--; ++a, ++b )
    +    if (!(diff = (int) towlower(*a) - (int) towlower(*b)) || !*a) return diff;
    +}
    +int _wcsicmp(const wchar_t *a, const wchar_t *b)
    +{
    +  return _wcsnicmp(a, b, (size_t)-1);
    +}
    +
    +wchar_t* _wgetenv(const wchar_t *wname)
    +{
    +  mbstate_t ps = 0;
    +  char *nval, *nval2, nname[200]; // Hopefully this is enough
    +  size_t cbnn = wcsrtombs(nname, &wname, sizeof(nname), &ps);
    +  if ((size_t)-1 == cbnn || !(nval = getenv(nname))) return NULL;
    +  static wchar_t *g_wval = 0; // Not thread safe!
    +  for ( unsigned int cch = 200;; cch *= 2 )
    +  {
    +    if (!(g_wval = (wchar_t*) realloc(g_wval, cch * sizeof(wchar_t)))) break;
    +    ps = 0, nval2 = nval;
    +    size_t cchwv = mbsrtowcs(g_wval, const_cast<const char**>(&nval2), cch, &ps);
    +    if ((size_t)-1 == cchwv) return NULL;
    +    if (!nval2) return g_wval;
    +  }
    +  return (errno = ENOMEM, NULL);
    +}
    +
    +wchar_t* _wcsdup(const wchar_t *s)
    +{
    +  wchar_t *d = (wchar_t*) malloc(wcslen(s) * sizeof(wchar_t));
    +  if (d) wcscpy(d, s);
    +  return d;
    +}
    +
    +int _wtoi(const wchar_t *s)
    +{
    +  errno = 0;
    +  long int r = wcstol(s, 0, 10);
    +  if (errno) r = 0;
    +  if (LONG_MIN == r) r = INT_MIN;
    +  if (LONG_MAX == r) r = INT_MAX;
    +  return (int) r;
    +}
    +
    +int _wremove(const wchar_t *Path)
    +{
    +  const char *path = NSISRT_wctomb(Path, true);
    +  if (!path) return -1;
    +  const int retval = remove(path);
    +  NSISRT_free(path);
    +  return retval;
    +}
    +
    +static int NSISRT_wsystem(const wchar_t *wcmd)
    +{
    +  if (!wcmd) return system(NULL);
    +  // NOTE: Only the first drive in the path will be converted to posix style (c:\foo d:\bar > /c/foo d:/bar)
    +  const char *cmd = NSISRT_wctomb(wcmd, true);
    +  if (!cmd) return -1;
    +  const int retval = system(cmd);
    +  NSISRT_free(path);
    +  return retval;
    +}
    +
     bool nsis_iconv_reallociconv(iconv_t CD, char**In, size_t*cbInLeft, char**Mem, size_t&cbConverted)
     {
       char *in, *heap = *Mem;
    @@ -243,90 +337,60 @@
       _sntprintf(buf, len, _T("CP%d"), code_page);
     }
     
    -int WideCharToMultiByte(UINT CodePage, DWORD dwFlags, LPCWSTR lpWideCharStr,
    +int WideCharToMultiByte(UINT CodePage, DWORD dwFlags, const wchar_t* lpWideCharStr,
         int cchWideChar, LPSTR lpMultiByteStr, int cbMultiByte, LPCSTR lpDefaultChar,
         LPBOOL lpUsedDefaultChar) {
       static char buffer[4096]; // BUGBUG: Should this be 4*NSIS_MAX_STRLEN for large string build?
     
       char cp[128];
       create_code_page_string(cp, sizeof(cp), CodePage);
    -
       iconv_t cd = iconv_open(cp, "wchar_t");
    -  if (cd == (iconv_t) -1) {
    -    return 0;
    -  }
    +  if (cd == (iconv_t) -1) return 0;
    +  if (cchWideChar < 0) cchWideChar = (int) _wcslen(lpWideCharStr) + 1;
    +  if (cbMultiByte == 0) cbMultiByte = sizeof(buffer), lpMultiByteStr = buffer;
     
    -  if (cchWideChar < 0) {
    -    cchWideChar = (int) _wcslen(lpWideCharStr) + 1;
    -  }
    +  char *in = (char *) lpWideCharStr, *out = lpMultiByteStr;
    +  size_t inbytes = cchWideChar * sizeof(wchar_t), outbytes = cbMultiByte;
     
    -  if (cbMultiByte == 0) {
    -    cbMultiByte = sizeof(buffer);
    -    lpMultiByteStr = buffer;
    -  }
    -
    -  char *in = (char *) lpWideCharStr;
    -  char *out = lpMultiByteStr;
    -  size_t inbytes = cchWideChar * sizeof(WCHAR);
    -  size_t outbytes = cbMultiByte;
    -
       if (nsis_iconv_adaptor(iconv, cd, &in, &inbytes, &out, &outbytes) == (size_t) -1) {
         iconv_close(cd);
         return 0;
       }
     
       iconv_close(cd);
    -
       return cbMultiByte - outbytes;
     }
     
     int MultiByteToWideChar(UINT CodePage, DWORD dwFlags, LPCSTR lpMultiByteStr,
    -    int cbMultiByte, LPWSTR lpWideCharStr, int cchWideChar) {
    -  static WCHAR buffer[4096]; // BUGBUG: Should this be 4*NSIS_MAX_STRLEN for large string build?
    +    int cbMultiByte, wchar_t* lpWideCharStr, int cchWideChar) {
    +  static wchar_t buffer[4096]; // BUGBUG: Should this be 4*NSIS_MAX_STRLEN for large string build?
     
       char cp[128];
       create_code_page_string(cp, sizeof(cp), CodePage);
    -
       iconv_t cd = iconv_open("wchar_t", cp);
    -  if (cd == (iconv_t) -1) {
    -    return 0;
    -  }
    +  if (cd == (iconv_t) -1) return 0;
    +  if (cbMultiByte < 0) cbMultiByte = strlen(lpMultiByteStr) + 1;
    +  if (cchWideChar == 0) cchWideChar = sizeof(buffer), lpWideCharStr = buffer;
     
    -  if (cbMultiByte < 0) {
    -    cbMultiByte = strlen(lpMultiByteStr) + 1;
    -  }
    +  char *in = (char *) lpMultiByteStr, *out = (char *) lpWideCharStr;
    +  size_t inbytes = cbMultiByte, outbytes = cchWideChar * sizeof(wchar_t);
     
    -  if (cchWideChar == 0) {
    -    cchWideChar = sizeof(buffer);
    -    lpWideCharStr = buffer;
    -  }
    -
    -  char *in = (char *) lpMultiByteStr;
    -  char *out = (char *) lpWideCharStr;
    -  size_t inbytes = cbMultiByte;
    -  size_t outbytes = cchWideChar * sizeof(WCHAR);
    -
       if (nsis_iconv_adaptor(iconv, cd, &in, &inbytes, &out, &outbytes) == (size_t) -1) {
         iconv_close(cd);
         return 0;
       }
     
       iconv_close(cd);
    -
    -  return cchWideChar - (outbytes / sizeof (WCHAR));
    +  return cchWideChar - (outbytes / sizeof (wchar_t));
     }
     
     BOOL IsValidCodePage(UINT CodePage)
     {
       TCHAR cp[128];
       create_code_page_string(cp, sizeof(cp), CodePage);
    -
       iconv_t cd = iconv_open(_T("wchar_t"), cp);
    -  if (cd == (iconv_t) -1)
    -    return FALSE;
    -
    +  if (cd == (iconv_t) -1) return FALSE;
       iconv_close(cd);
    -
       return TRUE;
     }
     
    @@ -356,7 +420,7 @@
       if (_T('\"') == *p) ++p; // Skip opening quote if any (For !system)
       size_t len = _tcsclen(p);
     
    -  /* Replace drive letter X: by /X */
    +  /* Replace drive letter X: by /x */
       if (len >= 2 && _T(':') == p[1])
       {
         p[1] = (TCHAR) tolower((int) p[0]);
    @@ -411,24 +475,12 @@
       for (int i=0; ; ++i) if (0 == (tmode[i] = mode[i])) break;
       f = _wfopen(path, tmode);
     #else
    -  const char* orglocct = setlocale(LC_CTYPE, "");
    -  const wchar_t* srcW = path;
    -  size_t cb = wcsrtombs(0,&srcW,0,0);
    -  if (-1 != cb)
    +  char *nativepath = NSISRT_wctomb(path, true);
    +  if (nativepath)
       {
    -    char* nativepath = (char*) malloc(++cb);
    -    if (nativepath)
    -    {
    -      cb = wcsrtombs(nativepath,&path,cb,0);
    -      if (-1 != cb)
    -      {
    -        PathConvertWinToPosix(nativepath);
    -        f = fopen(nativepath, mode);
    -      }
    -      free(nativepath);
    -    }
    +    f = fopen(nativepath, mode);
    +    NSISRT_free(nativepath);
       }
    -  setlocale(LC_CTYPE, orglocct);
     #endif
     #endif
       return f;
    @@ -759,7 +811,7 @@
       // which obviously fails...
       //
       // to avoid the stripping, a harmless string is prefixed to the command line.
    -  const TCHAR* prefix = _T("IF 1==1 ");
    +  const TCHAR*const prefix = _T("IF 1==1 ");
     #ifdef _UNICODE
       if (!command) return 0;
       if (!*command) return 1;
    @@ -771,11 +823,15 @@
     #else
       tstring fixedcmd = prefix + _T("") + command;
       return _tsystem(fixedcmd.c_str());
    -#endif
    -
    +#endif // ~_UNICODE
    +#else // !_WIN32
    +#ifndef _UNICODE
    +  PATH_CONVERT(command);
    +  return _tsystem(command);
     #else
    -  return _tsystem(command);
    +  return NSISRT_wsystem(command);
     #endif
    +#endif // ~_WIN32
     }
     
     #ifdef _WIN32
    Index: Source/ResourceVersionInfo.cpp
    ===================================================================
    --- Source/ResourceVersionInfo.cpp      (revision 6392)
    +++ Source/ResourceVersionInfo.cpp      (working copy)
    @@ -21,6 +21,7 @@
     #include "Platform.h"
     #include "util.h"
     #include "winchar.h"
    +#include "utf.h"
     
     #ifdef NSIS_SUPPORT_VERSION_INFO
     
    @@ -140,10 +141,10 @@
         wType = *(WORD*)p;
         p += sizeof(WORD);
         szKey = (WCHAR*)p;
    -    p += (wcslen(szKey) + 1) * sizeof (WCHAR);
    +    p += (WinWStrLen(szKey) + 1) * sizeof (WCHAR);
         while ( ((ULONG_PTR)p % 4) != 0 )
             p++;
    -    return p - baseP;    
    +    return p - baseP;
     }
     
     DWORD ZEROS = 0;
    @@ -162,7 +163,7 @@
     // @param wType If type is 1, it's a wchar_t string, so save value length appropriately.
     // @param key The string key
     // @param value The value mapped to string key.
    -void SaveVersionHeader (GrowBuf &strm, WORD wLength, WORD wValueLength, WORD wType, const WCHAR *key, void *value)
    +void SaveVersionHeaderUTF16LE(GrowBuf &strm, WORD wLength, WORD wValueLength, WORD wType, const WCHAR *key, void *value)
     {
         WORD valueLen;
         WORD keyLen;
    @@ -171,7 +172,7 @@
         
         strm.add (&wValueLength, sizeof (wValueLength));
         strm.add (&wType, sizeof (wType));
    -    keyLen = WORD((wcslen(key) + 1) * sizeof (WCHAR));
    +    keyLen = WORD((StrLenUTF16(key) + 1) * sizeof (WCHAR));
         strm.add ((void*)key, keyLen);
         
         PadStream(strm);
    @@ -184,16 +185,22 @@
             strm.add (value, valueLen);
         }
     }
    +void SaveVersionHeader(GrowBuf &strm, WORD wLength, WORD wValueLength, WORD wType, const wchar_t *key, void *value)
    +{
    +  WCToUTF16LEHlpr cnv;
    +  if (!cnv.Create(key)) throw std::runtime_error("Unicode conversion failed");
    +  SaveVersionHeaderUTF16LE(strm, wLength, wValueLength, wType, cnv.Get(), value);
    +  cnv.Destroy();
    +}
     
     void CResourceVersionInfo::ExportToStream(GrowBuf &strm, int Index)
     {
         DWORD v;
         WORD wSize;  
         int p, p1;
    -    WCHAR *KeyName, *KeyValue;
     
         strm.resize(0);
    -    SaveVersionHeader (strm, 0, sizeof (VS_FIXEDFILEINFO), 0, L"VS_VERSION_INFO", &m_FixedInfo);
    +    SaveVersionHeader(strm, 0, sizeof (VS_FIXEDFILEINFO), 0, L"VS_VERSION_INFO", &m_FixedInfo);
         
         DefineList *pChildStrings = m_ChildStringLists.get_strings(Index);
         if ( pChildStrings->getnum() > 0 )
    @@ -201,20 +208,19 @@
           GrowBuf stringInfoStream;
           int codepage = m_ChildStringLists.get_codepage(Index);
           LANGID langid = m_ChildStringLists.get_lang(Index);
    -      WCHAR Buff[16];
    +      wchar_t Buff[16];
           _snwprintf(Buff, COUNTOF(Buff), L"%04x%04x", langid, codepage);
    -      SaveVersionHeader (stringInfoStream, 0, 0, 0, Buff, &ZEROS);
    +      SaveVersionHeader(stringInfoStream, 0, 0, 0, Buff, &ZEROS);
           
           for ( int i = 0; i < pChildStrings->getnum(); i++ )
           {
             PadStream (stringInfoStream);
    -        
    +        WCToUTF16LEHlpr cnvName, cnvValue;
    +        if (!cnvName.Create(pChildStrings->getname(i), codepage)) throw std::runtime_error("Unicode conversion failed");
    +        if (!cnvValue.Create(pChildStrings->getvalue(i), codepage)) throw std::runtime_error("Unicode conversion failed");
             p = stringInfoStream.getlen();
    -        KeyName = wcsdup_fromTchar(pChildStrings->getname(i), codepage);
    -        KeyValue = wcsdup_fromTchar(pChildStrings->getvalue(i), codepage);
    -        SaveVersionHeader (stringInfoStream, 0, WORD(wcslen(KeyValue) + 1), 1, KeyName, (void*)KeyValue);
    -        free(KeyName);
    -        free(KeyValue);
    +        SaveVersionHeaderUTF16LE(stringInfoStream, 0, WORD(WinWStrLen(cnvValue.Get()) + 1), 1, cnvName.Get(), (void*)cnvValue.Get());
    +        cnvName.Destroy(), cnvValue.Destroy();
             wSize = WORD(stringInfoStream.getlen() - p);
             
             *(WORD*)((PBYTE)stringInfoStream.get()+p)=wSize;
    @@ -225,7 +231,7 @@
           
           PadStream (strm);
           p = strm.getlen();
    -      SaveVersionHeader (strm, 0, 0, 0, L"StringFileInfo", &ZEROS);
    +      SaveVersionHeader(strm, 0, 0, 0, L"StringFileInfo", &ZEROS);
           strm.add (stringInfoStream.get(), stringInfoStream.getlen());
           wSize = WORD(strm.getlen() - p);
           
    @@ -237,11 +243,11 @@
         {
           PadStream (strm);
           p = strm.getlen();
    -      SaveVersionHeader (strm, 0, 0, 0, L"VarFileInfo", &ZEROS);
    +      SaveVersionHeader(strm, 0, 0, 0, L"VarFileInfo", &ZEROS);
           PadStream (strm);
           
           p1 = strm.getlen();
    -      SaveVersionHeader (strm, 0, 0, 0, L"Translation", &ZEROS);
    +      SaveVersionHeader(strm, 0, 0, 0, L"Translation", &ZEROS);
           
           // First add selected code language translation
           v = MAKELONG(m_ChildStringLists.get_lang(Index), m_ChildStringLists.get_codepage(Index));
    Index: Source/winchar.h
    ===================================================================
    --- Source/winchar.h    (revision 6392)
    +++ Source/winchar.h    (working copy)
    @@ -18,17 +18,38 @@
     
     #include "Platform.h"
     
    +#define WINWCHAR unsigned short
    +
    +int WinWStrICmpASCII(const WINWCHAR *a, const char *b);
    +int WinWStrNICmpASCII(const WINWCHAR *a, const char *b, size_t n);
    +#ifdef _WIN32
    +#define WinWStrLen wcslen
    +#define WinWStrCpy wcscpy
    +#define WinWStrNCpy wcsncpy
    +#define WinWStrCmp wcscmp
    +#define WinWStrDupFromWinWStr wcsdup
    +#define WinWStrDupFromTChar WinWStrDupFromWinWStr
    +#define WinWStrToInt _wtoi
    +#else // !_WIN32
    +size_t WinWStrLen(const WINWCHAR *s);
    +WINWCHAR* WinWStrCpy(WINWCHAR *d, const WINWCHAR *s);
    +WINWCHAR* WinWStrNCpy(WINWCHAR *d, const WINWCHAR *s, size_t n);
    +int WinWStrCmp(const WINWCHAR *a, const WINWCHAR *b);
    +WINWCHAR* WinWStrDupFromWinWStr(const WINWCHAR *s);
    +WINWCHAR* WinWStrDupFromTChar(const TCHAR *s);
    +int WinWStrToInt(const WINWCHAR *s);
    +#endif // ~_WIN32
    +
    +#ifdef _UNICODE
    +inline WINWCHAR* WinWStrDupFromTChar(const TCHAR *s, unsigned int codepage) { return WinWStrDupFromTChar(s); }
    +#endif
    +
    +
    +#if 0
     WCHAR *wcsdup_fromansi(const char* s, unsigned int codepage = CP_ACP);
     #ifdef _UNICODE
     #define wcsdup_fromTchar(s, codepage) _wcsdup(s)      // codepage is not used in this mode
     #else
     #define wcsdup_fromTchar(s, codepage) wcsdup_fromansi(s, codepage)
     #endif
    -
    -#if 0 // Needed by some RTL missing wchar string functions ?
    -WCHAR *wcscpy(WCHAR *ws1, const WCHAR *ws2);
    -WCHAR *wcsncpy(WCHAR *ws1, const WCHAR *ws2, size_t n);
    -size_t wcslen(const WCHAR *ws);
    -WCHAR *_wcsdup(const WCHAR *ws);
    -int wcscmp(const WCHAR *ws1, const WCHAR *ws2);
     #endif
    Index: Source/winchar.cpp
    ===================================================================
    --- Source/winchar.cpp  (revision 6392)
    +++ Source/winchar.cpp  (working copy)
    @@ -19,87 +19,104 @@
     #include "Platform.h"
     #include "winchar.h"
     #include "util.h"
    +#include "utf.h"
     
     #include <stdexcept>
    +#include <cassert>
     
     using std::runtime_error;
     
    -WCHAR *wcsdup_fromansi(const char* s, unsigned int codepage/* = CP_ACP*/)
    +int WinWStrICmpASCII(const WINWCHAR *a, const char *b)
     {
    -  int l = MultiByteToWideChar(codepage, 0, s, -1, 0, 0);
    -  if (l == 0)
    -    throw runtime_error("Unicode conversion failed");
    -
    -  WCHAR *ws = new WCHAR[l + 1];
    -
    -  if (MultiByteToWideChar(codepage, 0, s, -1, ws, l + 1) == 0)
    -    throw runtime_error("Unicode conversion failed");
    -
    -  return ws;
    +  int diff = 0;
    +  do
    +    diff = static_cast<int>(S7ChLwr(*a)) - static_cast<int>(S7ChLwr(*b++));
    +  while (*a++ && !diff);
    +  return diff;
     }
    -
    -#if 0 // Needed by some RTL missing wchar string functions ?
    -WCHAR *wcscpy(WCHAR *ws1, const WCHAR *ws2)
    +int WinWStrNICmpASCII(const WINWCHAR *a, const char *b, size_t n)
     {
    -  WCHAR *ret = ws1;
    -
    -  while (*ws2)
    +  int diff = 0;
    +  for ( ; n-- && !diff; ++a, ++b )
       {
    -    *ws1++ = *ws2++;
    +    diff = static_cast<int>(S7ChLwr(*a)) - static_cast<int>(S7ChLwr(*b));
    +    if (!*a) break;
       }
    +  return diff;
    +}
     
    -  *ws1 = 0;
    +#ifndef _WIN32
    +size_t WinWStrLen(const WINWCHAR *s)
    +{
    +  return StrLenUTF16(s);
    +}
     
    +WINWCHAR* WinWStrCpy(WINWCHAR *d, const WINWCHAR *s)
    +{
    +  WINWCHAR *ret = d;
    +  while (*s) *d++ = *s++;
    +  *d = 0;
       return ret;
     }
     
    -WCHAR *wcsncpy(WCHAR *ws1, const WCHAR *ws2, size_t n)
    +WINWCHAR* WinWStrNCpy(WINWCHAR *d, const WINWCHAR *s, size_t n)
     {
    -  WCHAR *ret = ws1;
    -
    -  while (n && *ws2)
    -  {
    -    *ws1++ = *ws2++;
    -    n--;
    -  }
    -
    -  while (n--)
    -  {
    -    *ws1++ = 0;
    -  }
    -
    +  WINWCHAR *ret = d;
    +  while (n && *s) *d++ = *s++, n--;
    +  while (n--) *d++ = 0;
       return ret;
     }
     
    -size_t wcslen(const WCHAR *ws)
    +int WinWStrCmp(const WINWCHAR *a, const WINWCHAR *b)
     {
    -  size_t len = 0;
    +  int diff = 0;
    +  do
    +    diff = static_cast<int>(*a) - static_cast<int>(*b++);
    +  while (*a++ && !diff);
    +  return diff;
    +}
     
    -  while (*ws++)
    -  {
    -    len++;
    -  }
    -
    -  return len;
    +WINWCHAR* WinWStrDupFromWinWStr(const WINWCHAR *s)
    +{
    +  WINWCHAR *d = (WINWCHAR*) malloc((WinWStrLen(s) + 1) * sizeof(WINWCHAR));
    +  if (d) WinWStrCpy(s);
    +  assert(!d || !IS_INTRESOURCE(d)); // DialogTemplate strings can be ATOMs
    +  return d;
     }
     
    -WCHAR *_wcsdup(const WCHAR *ws)
    +WINWCHAR* WinWStrDupFromTChar(const TCHAR *s)
     {
    -  WCHAR *dup = (WCHAR*) malloc(sizeof(WCHAR)*(wcslen(ws)+1)];
    -  wcscpy(dup, ws);
    -  return dup;
    +  WCToUTF16LEHlpr cnv;
    +  if (!cnv.Create(s)) throw runtime_error("Unicode conversion failed");
    +  return cnv.Detach();
     }
     
    -int wcscmp(const WCHAR *ws1, const WCHAR *ws2)
    +int WinWStrToInt(const WINWCHAR *s)
     {
    -  int diff = 0;
    -
    -  do
    +  unsigned int v = 0, base = 10, top = '9';
    +  int sign = 1
    +  if (*s == _T('-')) ++s, sign = -1;
    +  for ( int c;; )
       {
    -    diff = static_cast<int>(*ws1) - static_cast<int>(*ws2);
    +    if ((c = *s++) >= '0' && c <= top) c -= '0'; else break;
    +    v *= m, v += c;
       }
    -  while (*ws1++ && *ws2++ && !diff);
    +  return ((int)v) * sign;
    +}
    +#endif // ~!_WIN32
     
    -  return diff;
    +#if 0
    +WCHAR *wcsdup_fromansi(const char* s, unsigned int codepage/* = CP_ACP*/)
    +{
    +  int l = MultiByteToWideChar(codepage, 0, s, -1, 0, 0);
    +  if (l == 0)
    +    throw runtime_error("Unicode conversion failed");
    +
    +  WCHAR *ws = new WCHAR[l + 1];
    +
    +  if (MultiByteToWideChar(codepage, 0, s, -1, ws, l + 1) == 0)
    +    throw runtime_error("Unicode conversion failed");
    +
    +  return ws;
     }
     #endif
    Index: Source/strlist.h
    ===================================================================
    --- Source/strlist.h    (revision 6392)
    +++ Source/strlist.h    (working copy)
    @@ -308,25 +308,25 @@
         SortedStringListND() { }
         virtual ~SortedStringListND() { }
     
    -        /**
    -         * Adds name into the list of sorted strings.
    -         *
    -         * @param name String to store.
    -         * @param case_sensitive Look for string case sensitively.  Default is 0.
    -         * @param alwaysreturnpos Always return the position regardless of whether
    -         * name was inserted into the list or not.  The default is 0.
    -         *
    -         * @return Returns -1 when name already exists, otherwise the T offset
    -         * into which the struct was stored in m_gr.  If alwaysreturnpos
    -         * is true, then it will return the byte offset regardless of whether
    -         * the string was found.
    -         */
    +     /**
    +      * Adds name into the list of sorted strings.
    +      *
    +      * @param name String to store.
    +      * @param case_sensitive Look for string case sensitively.  Default is 0.
    +      * @param alwaysreturnpos Always return the position regardless of whether
    +      * name was inserted into the list or not.  The default is 0.
    +      *
    +      * @return Returns -1 when name already exists, otherwise the T offset
    +      * into which the struct was stored in m_gr.  If alwaysreturnpos
    +      * is true, then it will return the byte offset regardless of whether
    +      * the string was found.
    +      */
         int add(const TCHAR *name, int case_sensitive=0, int alwaysreturnpos=0)
         {
           int where=0;
           T newstruct={0,};
     
    -               // Find the best position to insert.
    +      // Find the best position to insert.
           int pos=find(name,-1,case_sensitive,1,&where);
     
           if (pos==-1) return alwaysreturnpos ? where : -1;
    @@ -342,46 +342,46 @@
           return pos;
         }
     
    -        /**
    -         * This function looks for the string str, in T.name in the buffer m_gr.
    -         * If it finds it, it returns the position found.  Otherwise, it returns
    -         * -1.  
    -         *
    -         * This behavior changes when returnbestpos == 1.  In this case,
    -         * it will do the reverse.  It will return -1 when it is found, noting
    -         * that there is no good place to put this duplicate string.  If it
    -         * is <b>not</b> found, it returns the position where it ought to be
    -         * placed.
    -         *
    -         * When case_sensitive == -1 and returnbestpos == 1, then when the string
    -         * is found, it returns
    -         * the position of the string so that one can overwrite it.  Very strange
    -         * special case behavior that I'm not sure if anyone actually uses.
    -         *
    -         * @param str The key string to search for.
    -         *
    -         * @param n_chars The number of characters to compare.  Use -1 to match
    -         * the entire string.
    -         *
    -         * @param case_sensitive 1 = case sensitive, 0 = case insensitive,
    -         * -1 is a special case where it is case sensitive and overrides the
    -         * returnbestpos behavior when the string is found.
    -         *
    -         * @param returnbestpos If 1, then look for the best position to add the
    -         * string.  If found in the list, return -1.
    -         *
    -         * @param where When str is found, returns the position of the string.
    -         *
    -         * @return The position of T where T.name == str.  If returnbestpos != 0
    -         * then return the best position to add T if not found, otherwise, -1.
    -         */
    +   /**
    +    * This function looks for the string str, in T.name in the buffer m_gr.
    +    * If it finds it, it returns the position found.  Otherwise, it returns
    +    * -1.  
    +    *
    +    * This behavior changes when returnbestpos == 1.  In this case,
    +    * it will do the reverse.  It will return -1 when it is found, noting
    +    * that there is no good place to put this duplicate string.  If it
    +    * is <b>not</b> found, it returns the position where it ought to be
    +    * placed.
    +    *
    +    * When case_sensitive == -1 and returnbestpos == 1, then when the string
    +    * is found, it returns
    +    * the position of the string so that one can overwrite it.  Very strange
    +    * special case behavior that I'm not sure if anyone actually uses.
    +    *
    +    * @param str The key string to search for.
    +    *
    +    * @param n_chars The number of characters to compare.  Use -1 to match
    +    * the entire string.
    +    *
    +    * @param case_sensitive 1 = case sensitive, 0 = case insensitive,
    +    * -1 is a special case where it is case sensitive and overrides the
    +    * returnbestpos behavior when the string is found.
    +    *
    +    * @param returnbestpos If 1, then look for the best position to add the
    +    * string.  If found in the list, return -1.
    +    *
    +    * @param where When str is found, returns the position of the string.
    +    *
    +    * @return The position of T where T.name == str.  If returnbestpos != 0
    +    * then return the best position to add T if not found, otherwise, -1.
    +    */
         int find
         (
    -           const TCHAR*        str,                                    /* key to search for */
    -                int                            n_chars=-1,                     /* if -1, test the entire string, otherwise just n characters */
    -                int                            case_sensitive=0,
    -                int                            returnbestpos=0,        /* if not found, return best pos */
    -                int*                           where=0                         /* */
    +      const TCHAR* str,    /* key to search for */
    +      int n_chars=-1,      /* if -1, test the entire string, otherwise just n characters */
    +      int case_sensitive=0,
    +      int returnbestpos=0, /* if not found, return best pos */
    +      int*where=0
         )
         {
           T *data=(T *) m_gr.get();
    @@ -389,7 +389,7 @@
           int ll = 0;
           int nextpos = (ul+ll)/2;
     
    -               // Do binary search on m_gr which is sorted. m_strings is NOT sorted.
    +      // Do binary search on m_gr which is sorted. m_strings is NOT sorted.
           while (ul > ll)
           {
             int res;
    @@ -436,9 +436,8 @@
         }
     
       protected:
    -    TinyGrowBuf m_gr;                  // Sorted array of Ts
    -    GrowBuf     m_strings;             // Unsorted array of TCHAR strings
    -                                                                               //  (contains the .names)
    +    TinyGrowBuf m_gr;      // Sorted array of Ts
    +    GrowBuf     m_strings; // Unsorted array of TCHAR strings (contains the .names)
     };
     
     **
    Index: Source/util.h
    ===================================================================
    --- Source/util.h       (revision 6392)
    +++ Source/util.h       (working copy)
    @@ -185,22 +185,29 @@
       static const char* GetHostEndianUCS4Code() { return "UCS-4-INTERNAL"; }
     };
     
    +BOOL IsDBCSLeadByteEx(unsigned int CodePage, unsigned char TestChar);
     TCHAR *CharPrev(const TCHAR *s, const TCHAR *p);
     char *CharNextA(const char *s);
    -WCHAR *CharNextW(const WCHAR *s);
    +wchar_t *CharNextW(const wchar_t *s);
     char *CharNextExA(WORD codepage, const char *s, int flags);
     int wsprintf(TCHAR *s, const TCHAR *format, ...);
    -int WideCharToMultiByte(UINT CodePage, DWORD dwFlags, LPCWSTR lpWideCharStr,
    +int WideCharToMultiByte(UINT CodePage, DWORD dwFlags, const wchar_t* lpWideCharStr,
         int cchWideChar, LPSTR lpMultiByteStr, int cbMultiByte, LPCSTR lpDefaultChar,
         LPBOOL lpUsedDefaultChar);
     int MultiByteToWideChar(UINT CodePage, DWORD dwFlags, LPCSTR lpMultiByteStr,
    -    int cbMultiByte, LPWSTR lpWideCharStr, int cchWideChar);
    +    int cbMultiByte, wchar_t* lpWideCharStr, int cchWideChar);
     BOOL IsValidCodePage(UINT CodePage);
     #ifdef _UNICODE
     #define CharNext CharNextW
     #else
     #define CharNext CharNextA
     #endif
    +int _wcsicmp(const wchar_t *a, const wchar_t *b);
    +int _wcsnicmp(const wchar_t *a, const wchar_t *b, size_t n);
    +wchar_t* _wgetenv(const wchar_t *wname);
    +wchar_t* _wcsdup(const wchar_t *s);
    +int _wtoi(const wchar_t *s);
    +int _wremove(const wchar_t *Path);
     
     TCHAR *my_convert(const TCHAR *path);
     void my_convert_free(TCHAR *converted_path);
    Index: Source/ResourceEditor.cpp
    ===================================================================
    --- Source/ResourceEditor.cpp   (revision 6392)
    +++ Source/ResourceEditor.cpp   (working copy)
    @@ -219,20 +219,32 @@
     
     #ifndef _UNICODE
     static WCHAR* ResStringToUnicode(const char *szString) {
    -  if (IS_INTRESOURCE(szString))
    -    return MAKEINTRESOURCEW((ULONG_PTR)szString);
    -  else
    -    return wcsdup_fromTchar(szString, CP_ACP);
    +  if (IS_INTRESOURCE(szString)) return MAKEINTRESOURCEW((ULONG_PTR)szString);
    +  WCHAR *s = WinWStrDupFromTChar(szString, CP_ACP);
    +  if (!s) throw std::bad_alloc();
    +  return s;
     }
     
     static void FreeUnicodeResString(WCHAR* szwString) {
    -  if (!IS_INTRESOURCE(szwString))
    -    free(szwString);
    +  if (!IS_INTRESOURCE(szwString)) free(szwString);
     }
    -#endif
    +#else
    +#ifndef _WIN32
    +static WCHAR* ResStringToUnicode(const TCHAR *s) {
    +  if (IS_INTRESOURCE(s)) return MAKEINTRESOURCEW((ULONG_PTR)s);
    +  WCToUTF16LEHlpr cnv;
    +  if (!cnv.Create(s)) throw std::runtime_error("Unicode conversion failed");
    +  return cnv.Detach();
    +}
    +static void FreeUnicodeResString(WCHAR* s) {
    +  if (!IS_INTRESOURCE(s)) free(s);
    +}
    +#endif // ~_WIN32
    +#endif // ~_UNICODE
     
    +
     bool CResourceEditor::UpdateResource(const TCHAR* szType, WORD szName, LANGID wLanguage, BYTE* lpData, DWORD dwSize) {
    -#ifdef _UNICODE
    +#if defined(_WIN32) && defined(_UNICODE)
       return UpdateResourceW(szType, MAKEINTRESOURCEW(szName), wLanguage, lpData, dwSize);
     #else
       WCHAR* szwType = ResStringToUnicode(szType);
    @@ -277,7 +289,7 @@
     }
     
     BYTE* CResourceEditor::GetResource(const TCHAR* szType, WORD szName, LANGID wLanguage) {
    -#ifdef _UNICODE
    +#if defined(_WIN32) && defined(_UNICODE)
       return GetResourceW(szType, MAKEINTRESOURCEW(szName), wLanguage);
     #else
       WCHAR* szwType = ResStringToUnicode(szType);
    @@ -316,7 +328,7 @@
     }
     
     int CResourceEditor::GetResourceSize(const TCHAR* szType, WORD szName, LANGID wLanguage) {
    -#ifdef _UNICODE
    +#if defined(_WIN32) && defined(_UNICODE)
       return GetResourceSizeW(szType, MAKEINTRESOURCEW(szName), wLanguage);
     #else
       WCHAR* szwType = ResStringToUnicode(szType);
    @@ -355,7 +367,7 @@
     }
     
     DWORD CResourceEditor::GetResourceOffset(const TCHAR* szType, WORD szName, LANGID wLanguage) {
    -#ifdef _UNICODE
    +#if defined(_WIN32) && defined(_UNICODE)
       return GetResourceOffsetW(szType, MAKEINTRESOURCEW(szName), wLanguage);
     #else
       WCHAR* szwType = ResStringToUnicode(szType);
    @@ -579,7 +591,7 @@
     
           size_t nameSize = ConvertEndianness(rds->Length);
           szName = new WCHAR[nameSize+1];
    -      wcsncpy(szName, rds->NameString, nameSize);
    +      WinWStrNCpy(szName, rds->NameString, nameSize);
           szName[nameSize] = 0;
         }
         // Else, set the name to this entry's id
    @@ -708,14 +720,14 @@
         PMY_IMAGE_RESOURCE_DIRECTORY_ENTRY(cRDirE->m_ulWrittenAt)->UName.NameString.NameOffset = ConvertEndianness((DWORD) (seeker - pbRsrcSec));
     
         WCHAR* szName = cRDirE->GetName();
    -    WORD iLen = wcslen(szName) + 1;
    +    WORD iLen = WinWStrLen(szName) + 1;
     
         *(WORD*)seeker = ConvertEndianness(iLen);
         CopyMemory(seeker + sizeof(WORD), szName, iLen*sizeof(WCHAR));
     
         seeker += RALIGN(iLen * sizeof(WCHAR) + sizeof(WORD), 4);
     
    -    delete [] szName;
    +    free(szName);
     
         qStrings.pop();
       }
    @@ -817,16 +829,16 @@
         WCHAR* szEntName = entry->GetName();
         for (i = 0; i < m_rdDir.NumberOfNamedEntries; i++) {
           WCHAR* szName = m_vEntries[i]->GetName();
    -      int cmp = wcscmp(szName, szEntName);
    -      delete [] szName;
    +      int cmp = WinWStrCmp(szName, szEntName);
    +      free(szName);
           if (cmp == 0) {
    -        delete [] szEntName;
    +        free(szEntName);
             return;
           }
           if (cmp > 0)
             break;
         }
    -    delete [] szEntName;
    +    free(szEntName);
         m_rdDir.NumberOfNamedEntries++;
       }
       else {
    @@ -869,8 +881,8 @@
           continue;
     
         WCHAR* szEntName = m_vEntries[i]->GetName();
    -    int cmp = wcscmp(szName, szEntName);
    -    delete [] szEntName;
    +    int cmp = WinWStrCmp(szName, szEntName);
    +    free(szEntName);
     
         if (!cmp)
           return i;
    @@ -941,7 +953,7 @@
       }
       else {
         m_bHasName = true;
    -    m_szName = _wcsdup(szName);
    +    m_szName = WinWStrDupFromWinWStr(szName);
       }
       m_bIsDataDirectory = true;
       m_rdSubDir = rdSubDir;
    @@ -955,7 +967,7 @@
       }
       else {
         m_bHasName = true;
    -    m_szName = _wcsdup(szName);
    +    m_szName = WinWStrDupFromWinWStr(szName);
       }
       m_bIsDataDirectory = false;
       m_rdeData = rdeData;
    @@ -963,7 +975,7 @@
     
     CResourceDirectoryEntry::~CResourceDirectoryEntry() {
       if (m_szName && m_bHasName)
    -    delete [] m_szName;
    +    free(m_szName);
     }
     
     //////////////////////////////////////////////////////////////////////
    @@ -978,11 +990,11 @@
     WCHAR* CResourceDirectoryEntry::GetName() {
       if (!m_bHasName)
         return 0;
    -  return _wcsdup(m_szName);
    +  return WinWStrDupFromWinWStr(m_szName);
     }
     
     int CResourceDirectoryEntry::GetNameLength() {
    -  return wcslen(m_szName);
    +  return WinWStrLen(m_szName);
     }
     
     WORD CResourceDirectoryEntry::GetId() {
    Index: Source/Platform.h
    ===================================================================
    --- Source/Platform.h   (revision 6405)
    +++ Source/Platform.h   (working copy)
    @@ -221,6 +221,13 @@
     #  ifndef RGB
     #    define RGB(r,g,b) ((DWORD)(((BYTE)(r)|((WORD)(g)<<8))|(((DWORD)(BYTE)(b))<<16)))
     #  endif
    +#  ifndef LOBYTE
    +#    define LOBYTE(w) ((BYTE)(w))
    +#    define HIBYTE(w) ((BYTE)(((WORD)(w)>>8)&0xFF))
    +#  endif
    +#  ifndef MAKEWORD
    +#    define MAKEWORD(a,b) ((WORD)(((BYTE)(a))|(((WORD)((BYTE)(b)))<<8)))
    +#  endif
     #  ifndef MAKELONG
     #    define MAKELONG(a,b) ((DWORD)(((WORD)(a))|(((DWORD)((WORD)(b)))<<16)))
     #  endif
    Index: Source/tstring.h
    ===================================================================
    --- Source/tstring.h    (revision 6392)
    +++ Source/tstring.h    (working copy)
    @@ -46,7 +46,7 @@
     
     // This is a helpful little function for converting exceptions or
     // other system type things that come back ANSI and must be
    -// utilized as either ANSI or WCHAR depending on _UNICODE.
    +// utilized as either ANSI or wchar_t depending on _UNICODE.
     class CtoTString
     {
     public:
    Index: SConstruct
    ===================================================================
    --- SConstruct  (revision 6413)
    +++ SConstruct  (working copy)
    @@ -201,10 +201,10 @@
     if defenv['TARGET_ARCH'] != 'x86':
            defenv['UNICODE'] = True
     
    -# add prefixes defines
    +# add prefixes defines BUGBUG: only apply L prefix to unicode builds
     if 'NSIS_CONFIG_CONST_DATA_PATH' in defenv['NSIS_CPPDEFINES']:
    -       defenv.Append(NSIS_CPPDEFINES = [('PREFIX_CONF', '"%s"' % defenv.subst('$PREFIX_CONF'))])
    -       defenv.Append(NSIS_CPPDEFINES = [('PREFIX_DATA', '"%s"' % defenv.subst('$PREFIX_DATA'))])
    +       defenv.Append(NSIS_CPPDEFINES = [('PREFIX_CONF', 'L"%s"' % defenv.subst('$PREFIX_CONF'))])
    +       defenv.Append(NSIS_CPPDEFINES = [('PREFIX_DATA', 'L"%s"' % defenv.subst('$PREFIX_DATA'))])
     
     # Need this early for the config header files to be placed in

Successful compiles:

build/urelease/halibut/biblio.cpp
build/urelease/halibut/bk_xhtml.cpp
build/urelease/halibut/contents.cpp
build/urelease/halibut/error.cpp
build/urelease/halibut/help.cpp
build/urelease/halibut/index.cpp
build/urelease/halibut/input.cpp
build/urelease/halibut/keywords.cpp
build/urelease/halibut/licence.cpp
build/urelease/halibut/main.cpp
build/urelease/halibut/malloc.cpp
build/urelease/halibut/misc.cpp
build/urelease/halibut/style.cpp
build/urelease/halibut/tree234.cpp
build/urelease/halibut/ustring.cpp
build/urelease/halibut/version.cpp
build/urelease/halibut/halibut
build/urelease/Docs/html/IndexPage.html
build/urelease/Docs/html/Contents.html
build/urelease/Docs/html/Chapter1.html
build/urelease/Docs/html/Chapter2.html
build/urelease/Docs/html/Chapter3.html
build/urelease/Docs/html/Chapter4.html
build/urelease/Docs/html/Chapter5.html
build/urelease/Docs/html/AppendixA.html
build/urelease/Docs/html/AppendixB.html
build/urelease/Docs/html/AppendixC.html
build/urelease/Docs/html/AppendixD.html
build/urelease/Docs/html/AppendixE.html
build/urelease/Docs/html/AppendixF.html
build/urelease/Docs/html/AppendixG.html
build/urelease/Docs/html/AppendixH.html
build/urelease/Docs/html/AppendixI.html
build/urelease/makensis/7zip/7zGuids.cpp
build/urelease/makensis/7zip/7zip/Common/OutBuffer.cpp
build/urelease/makensis/7zip/7zip/Common/StreamUtils.cpp
build/urelease/makensis/7zip/7zip/Compress/LZ/LZInWindow.cpp
build/urelease/makensis/7zip/7zip/Compress/LZMA/LZMAEncoder.cpp
build/urelease/makensis/7zip/7zip/Compress/RangeCoder/RangeCoderBit.cpp
build/urelease/makensis/7zip/Common/Alloc.cpp
build/urelease/makensis/7zip/Common/CRC.cpp
build/urelease/makensis/DialogTemplate.cpp
build/urelease/makensis/Plugins.cpp
build/urelease/makensis/ResourceVersionInfo.cpp
build/urelease/makensis/ShConstants.cpp
build/urelease/makensis/bzip2/blocksort.cpp
build/urelease/makensis/bzip2/bzlib.cpp
build/urelease/makensis/bzip2/compress.cpp
build/urelease/makensis/bzip2/huffman.cpp
build/urelease/makensis/clzma.cpp
build/urelease/makensis/crc32.cpp
build/urelease/makensis/fileform.cpp
build/urelease/makensis/growbuf.cpp
build/urelease/makensis/icon.cpp
build/urelease/makensis/lang.cpp
build/urelease/makensis/manifest.cpp
build/urelease/makensis/mmap.cpp
build/urelease/makensis/strlist.cpp
build/urelease/makensis/tokens.cpp
build/urelease/makensis/tstring.cpp
build/urelease/makensis/utf.cpp (fixes applied, see below)
build/urelease/makensis/writer.cpp

Changed parts:

Sconstruct:228: "Changed code for header config data."
# write configuration into sconf.h and defines.h
sconf_h = open(defenv.File('#$BUILD_CONFIG/nsis-sconf.h').abspath, 'w')
sconf_h.write('// This file is automatically generated by SCons\n// DO NOT EDIT THIS FILE\n')

defines_h = open(defenv.File('#$BUILD_CONFIG/nsis-defines.h').abspath, 'w')
defines_h.write('// This file is automatically generated by SCons\n// DO NOT EDIT THIS FILE\n')

for i in defenv['NSIS_CPPDEFINES']:
	if type(i) is not str:
		sconf_h.write('#define %s %s\n' % (i[0], i[1]))
		defines_h.write('#define %s %s\n' % (i[0], i[1]))
	else:
		sconf_h.write('#define %s\n' % (i))
		defines_h.write('#define %s\n' % (i))
#		defines_h.write('definedlist.add(_T("%s"));\n' % (i))
sconf_h.close()
defines_h.close()

# write version into version.h
f = open(defenv.File('#$BUILD_CONFIG/nsis-version.h').abspath, 'w')
f.write('// This file is automatically generated by SCons\n// DO NOT EDIT THIS FILE\n')
f.write('#include "%s"\n' % File('#/Source/tchar.h').abspath)

Source/Platform.h:643:1: "Added '#  define SW_SHOW 5'."

Source/ResourceEditor.cpp: Still need to fix type problems with MAKEINTRESOURCE with UpdateResource and GetResource.
Source/ResourceEditor.cpp:24: "Added '#include "utf.h"'."
Source/ResourceEditor.cpp:878: "Changed _wtoi to WinWStrToInt."

Source/build.cpp: Still need to fix type problems with MAKEINTRESOURCE with UpdateResource and GetResource.

Source/lineparse.cpp:99: "Missing function '_tstof' on linux."

Source/makenssi.cpp:36:1: "Added '#ifdef _WIN32' tags around '#include <io.h>'."

Source/utf.h:22: "Added '"#include "util.h"'."

Source/utf.cpp:18: "Removed '#include "util.h"'."
Source/utf.cpp:88: "Changed :: to ., added _T() wrapper for text."
Source/utf.cpp:90: "Changed &codpt to &CodPt."
Source/utf.cpp:132: "Changed char to TCHAR."
Source/utf.cpp:134: "Changed strcpy to _tcscpy, added _T() wrapper to text."
Source/utf.cpp:161: "Added #ifdef _WIN32 tags."
Source/utf.cpp:268: "Added typecast to cec.Detach() (unsigned short*)cec.Detached()."
Source/utf.cpp:529: "Added _T() wrapper for text, changed :: to ., changed ERR_UNSUPPORTEDENCODING to l_unsupportedencoding."

Source/util.h:153: Added missing function prototype "void create_code_page_string(TCHAR *buf, size_t len, UINT code_page);"
Source/util.h:153: Still need to convert wchar_t stuff to char as iconv_open() is char* only.
Source/util.h:188: "Changed char* to TCHAR*, added _T() wrapper to text."

Source/winchar.cpp:82: "Changed WinWStrCpy(s) to WinWStrCpy(d, s)."

Failed compiles:

Source/dirreader.cpp: In member function 'virtual void posix_dir_reader::read(const tstring&)':
Source/dirreader.cpp:203:37: error: cannot convert 'const wchar_t*' to 'const char*' for argument '1' to 'DIR* opendir(const char*)'
Source/dirreader.cpp:208:64: error: no match for 'operator+' in 'std::operator+(const std::basic_string<_CharT, _Traits, _Alloc>&, const _CharT*) [with _CharT = wchar_t, _Traits = std::char_traits<wchar_t>, _Alloc = std::allocator<wchar_t>](((const wchar_t*)"/\000\000\000\000\000\000")) + dit->dirent::d_name'
Source/dirreader.cpp:208:64: note: candidates are:
/usr/include/c++/4.6/bits/stl_iterator.h:327:5: note: template<class _Iterator> std::reverse_iterator<_Iterator> std::operator+(typename std::reverse_iterator<_Iterator>::difference_type, const std::reverse_iterator<_Iterator>&)
/usr/include/c++/4.6/bits/basic_string.h:2306:5: note: template<class _CharT, class _Traits, class _Alloc> std::basic_string<_CharT, _Traits, _Alloc> std::operator+(const std::basic_string<_CharT, _Traits, _Alloc>&, const std::basic_string<_CharT, _Traits, _Alloc>&)
/usr/include/c++/4.6/bits/basic_string.tcc:694:5: note: template<class _CharT, class _Traits, class _Alloc> std::basic_string<_CharT, _Traits, _Alloc> std::operator+(const _CharT*, const std::basic_string<_CharT, _Traits, _Alloc>&)
/usr/include/c++/4.6/bits/basic_string.tcc:710:5: note: template<class _CharT, class _Traits, class _Alloc> std::basic_string<_CharT, _Traits, _Alloc> std::operator+(_CharT, const std::basic_string<_CharT, _Traits, _Alloc>&)
/usr/include/c++/4.6/bits/basic_string.h:2343:5: note: template<class _CharT, class _Traits, class _Alloc> std::basic_string<_CharT, _Traits, _Alloc> std::operator+(const std::basic_string<_CharT, _Traits, _Alloc>&, const _CharT*)
/usr/include/c++/4.6/bits/basic_string.h:2359:5: note: template<class _CharT, class _Traits, class _Alloc> std::basic_string<_CharT, _Traits, _Alloc> std::operator+(const std::basic_string<_CharT, _Traits, _Alloc>&, _CharT)
/usr/include/c++/4.6/bits/stl_bvector.h:266:3: note: std::_Bit_iterator std::operator+(std::ptrdiff_t, const std::_Bit_iterator&)
/usr/include/c++/4.6/bits/stl_bvector.h:266:3: note:   no known conversion for argument 1 from 'std::basic_string<wchar_t>' to 'std::ptrdiff_t {aka int}'
/usr/include/c++/4.6/bits/stl_bvector.h:352:3: note: std::_Bit_const_iterator std::operator+(std::ptrdiff_t, const std::_Bit_const_iterator&)
/usr/include/c++/4.6/bits/stl_bvector.h:352:3: note:   no known conversion for argument 1 from 'std::basic_string<wchar_t>' to 'std::ptrdiff_t {aka int}'
/usr/include/c++/4.6/bits/stl_iterator.h:896:5: note: template<class _Iterator, class _Container> __gnu_cxx::__normal_iterator<_Iterator, _Container> __gnu_cxx::operator+(typename __gnu_cxx::__normal_iterator<_Iterator, _Container>::difference_type, const __gnu_cxx::__normal_iterator<_Iterator, _Container>&)
Source/dirreader.cpp:212:44: error: no matching function for call to 'posix_dir_reader::add_dir(char [256])'
Source/dirreader.cpp:212:44: note: candidate is:
Source/dirreader.cpp:138:6: note: virtual void dir_reader::add_dir(const tstring&)
Source/dirreader.cpp:138:6: note:   no known conversion for argument 1 from 'char [256]' to 'const tstring& {aka const std::basic_string<wchar_t>&}'
Source/dirreader.cpp:214:45: error: no matching function for call to 'posix_dir_reader::add_file(char [256])'
Source/dirreader.cpp:214:45: note: candidate is:
Source/dirreader.cpp:132:6: note: virtual void dir_reader::add_file(const tstring&)
Source/dirreader.cpp:132:6: note:   no known conversion for argument 1 from 'char [256]' to 'const tstring& {aka const std::basic_string<wchar_t>&}'

Source/makenssi.cpp: In function 'int change_to_script_dir(CEXEBuild&, tstring&)':
Source/makenssi.cpp:249:28: error: '_wchdir' was not declared in this scope
Source/makenssi.cpp: In function 'int wmain(int, TCHAR**)':
Source/makenssi.cpp:311:48: error: '_wtol' was not declared in this scope

Source/script.cpp: In member function 'TCHAR* CEXEBuild::set_file_predefine(const TCHAR*)':
Source/script.cpp:104:13: error: 'MAX_PATH' was not declared in this scope
Source/script.cpp:111:13: error: 'dir' was not declared in this scope
Source/script.cpp:113:14: error: 'dir' was not declared in this scope
Source/script.cpp:115:37: error: 'dir' was not declared in this scope
Source/script.cpp: In member function 'TCHAR* CEXEBuild::set_timestamp_predefine(const TCHAR*)':
Source/script.cpp:165:26: error: cannot convert 'const TCHAR* {aka const wchar_t*}' to 'const char*' for argument '1' to 'int stat(const char*, stat*)'
Source/script.cpp:166:61: error: '_wctime' was not declared in this scope
Source/script.cpp: In member function 'int CEXEBuild::doCommand(int, LineParser&)':
Source/script.cpp:1357:27: error: cannot convert 'TCHAR* {aka wchar_t*}' to 'char*' for argument '1' to 'int mkstemp(char*)'
Source/script.cpp:1417:45: error: '_wunlink' was not declared in this scope
Source/script.cpp:3371:67: error: '_wchdir' was not declared in this scope
Source/script.cpp:5278:44: error: cannot convert 'TCHAR* {aka wchar_t*}' to 'const char*' for argument '1' to 'int stat(const char*, stat*)'
Source/script.cpp: In member function 'int CEXEBuild::add_file(const tstring&, const tstring&, int, const TCHAR*, int, int*)':
Source/script.cpp:6631:21: error: cannot convert 'const TCHAR* {aka const wchar_t*}' to 'const char*' for argument '1' to 'int stat(const char*, stat*)'

Source/util.cpp: In function 'int wsprintf(TCHAR*, const TCHAR*, ...)':
Source/util.cpp:215:45: error: '_vsnwprintf' was not declared in this scope
Source/util.cpp: In function 'wchar_t* _wgetenv(const wchar_t*)':
Source/util.cpp:254:18: error: conversion from 'int' to non-scalar type 'mbstate_t {aka __mbstate_t}' requested
Source/util.cpp:262:10: error: no match for 'operator=' in 'ps = 0'
Source/util.cpp:262:10: note: candidate is:
/usr/include/wchar.h:95:3: note: __mbstate_t& __mbstate_t::operator=(const __mbstate_t&)
/usr/include/wchar.h:95:3: note:   no known conversion for argument 1 from 'int' to 'const __mbstate_t&'
Source/util.cpp:267:31: error: invalid conversion from 'int' to 'wchar_t*' [-fpermissive]
Source/util.cpp: In function 'int _wremove(const wchar_t*)':
Source/util.cpp:292:19: error: invalid conversion from 'const void*' to 'void*' [-fpermissive]
/usr/include/stdlib.h:488:13: error:   initializing argument 1 of 'void free(void*)' [-fpermissive]
Source/util.cpp: In function 'int NSISRT_wsystem(const wchar_t*)':
Source/util.cpp:303:15: error: 'path' was not declared in this scope
Source/util.cpp: In function 'void create_code_page_string(TCHAR*, size_t, UINT)':
Source/util.cpp:331:75: error: 'void create_code_page_string(TCHAR*, size_t, UINT)' was declared 'extern' and later 'static' [-fpermissive]
Source/util.h:153:6: error: previous declaration of 'void create_code_page_string(TCHAR*, size_t, UINT)' [-fpermissive]
Source/util.cpp: At global scope:
Source/util.cpp:350:5: error: expected ',' or '...' before 'int'
Source/util.cpp: In function 'int WideCharToMultiByte(UINT, DWORD, const wchar_t*)':
Source/util.cpp:355:51: error: cannot convert 'char*' to 'TCHAR* {aka wchar_t*}' for argument '1' to 'void create_code_page_string(TCHAR*, size_t, UINT)'
Source/util.cpp:358:7: error: 'cchWideChar' was not declared in this scope
Source/util.cpp:358:52: error: 'lpWideCharStr' was not declared in this scope
Source/util.cpp:358:65: error: '_wcslen' was not declared in this scope
Source/util.cpp:359:7: error: 'cbMultiByte' was not declared in this scope
Source/util.cpp:359:55: error: 'lpMultiByteStr' was not declared in this scope
Source/util.cpp:361:23: error: 'lpWideCharStr' was not declared in this scope
Source/util.cpp:361:45: error: 'lpMultiByteStr' was not declared in this scope
Source/util.cpp:362:20: error: 'cchWideChar' was not declared in this scope
Source/util.cpp:362:62: error: 'cbMultiByte' was not declared in this scope
Source/util.cpp: In function 'int MultiByteToWideChar(UINT, DWORD, LPCSTR, int, wchar_t*, int)':
Source/util.cpp:378:51: error: cannot convert 'char*' to 'TCHAR* {aka wchar_t*}' for argument '1' to 'void create_code_page_string(TCHAR*, size_t, UINT)'
Source/util.cpp: In function 'BOOL IsValidCodePage(UINT)':
Source/util.cpp:399:44: error: cannot convert 'const wchar_t*' to 'const char*' for argument '1' to 'void* iconv_open(const char*, const char*)'
Source/util.cpp: In function 'int my_open(const TCHAR*, int)':
Source/util.cpp:468:46: error: cannot convert 'TCHAR* {aka wchar_t*}' to 'const char*' for argument '1' to 'int open(const char*, int, ...)'
Source/util.cpp: In function 'tstring get_full_path(const tstring&)':
Source/util.cpp:535:37: error: cannot convert 'const wchar_t*' to 'const char*' for argument '1' to 'char* realpath(const char*, char*)'
Source/util.cpp: In function 'tstring get_executable_path(const TCHAR*)':
Source/util.cpp:595:56: error: cannot convert 'const wchar_t*' to 'const char*' for argument '1' to 'ssize_t readlink(const char*, char*, size_t)'
Source/util.cpp:602:27: error: no matching function for call to 'std::basic_string<char>::basic_string(TCHAR*&)'
Source/util.cpp:602:27: note: candidates are:
/usr/include/c++/4.6/bits/basic_string.h:527:9: note: template<class _InputIterator> std::basic_string::basic_string(_InputIterator, _InputIterator, const _Alloc&)
/usr/include/c++/4.6/bits/basic_string.tcc:221:5: note: std::basic_string<_CharT, _Traits, _Alloc>::basic_string(std::basic_string<_CharT, _Traits, _Alloc>::size_type, _CharT, const _Alloc&) [with _CharT = char, _Traits = std::char_traits<char>, _Alloc = std::allocator<char>, std::basic_string<_CharT, _Traits, _Alloc>::size_type = unsigned int]
/usr/include/c++/4.6/bits/basic_string.tcc:221:5: note:   candidate expects 3 arguments, 1 provided
/usr/include/c++/4.6/bits/basic_string.tcc:214:5: note: std::basic_string<_CharT, _Traits, _Alloc>::basic_string(const _CharT*, const _Alloc&) [with _CharT = char, _Traits = std::char_traits<char>, _Alloc = std::allocator<char>]
/usr/include/c++/4.6/bits/basic_string.tcc:214:5: note:   no known conversion for argument 1 from 'TCHAR* {aka wchar_t*}' to 'const char*'
/usr/include/c++/4.6/bits/basic_string.tcc:207:5: note: std::basic_string<_CharT, _Traits, _Alloc>::basic_string(const _CharT*, std::basic_string<_CharT, _Traits, _Alloc>::size_type, const _Alloc&) [with _CharT = char, _Traits = std::char_traits<char>, _Alloc = std::allocator<char>, std::basic_string<_CharT, _Traits, _Alloc>::size_type = unsigned int]
/usr/include/c++/4.6/bits/basic_string.tcc:207:5: note:   candidate expects 3 arguments, 1 provided
/usr/include/c++/4.6/bits/basic_string.tcc:195:5: note: std::basic_string<_CharT, _Traits, _Alloc>::basic_string(const std::basic_string<_CharT, _Traits, _Alloc>&, std::basic_string<_CharT, _Traits, _Alloc>::size_type, std::basic_string<_CharT, _Traits, _Alloc>::size_type, const _Alloc&) [with _CharT = char, _Traits = std::char_traits<char>, _Alloc = std::allocator<char>, std::basic_string<_CharT, _Traits, _Alloc> = std::basic_string<char>, std::basic_string<_CharT, _Traits, _Alloc>::size_type = unsigned int]
/usr/include/c++/4.6/bits/basic_string.tcc:195:5: note:   candidate expects 4 arguments, 1 provided
/usr/include/c++/4.6/bits/basic_string.tcc:185:5: note: std::basic_string<_CharT, _Traits, _Alloc>::basic_string(const std::basic_string<_CharT, _Traits, _Alloc>&, std::basic_string<_CharT, _Traits, _Alloc>::size_type, std::basic_string<_CharT, _Traits, _Alloc>::size_type) [with _CharT = char, _Traits = std::char_traits<char>, _Alloc = std::allocator<char>, std::basic_string<_CharT, _Traits, _Alloc> = std::basic_string<char>, std::basic_string<_CharT, _Traits, _Alloc>::size_type = unsigned int]
/usr/include/c++/4.6/bits/basic_string.tcc:185:5: note:   candidate expects 3 arguments, 1 provided
/usr/include/c++/4.6/bits/basic_string.tcc:171:5: note: std::basic_string<_CharT, _Traits, _Alloc>::basic_string(const std::basic_string<_CharT, _Traits, _Alloc>&) [with _CharT = char, _Traits = std::char_traits<char>, _Alloc = std::allocator<char>, std::basic_string<_CharT, _Traits, _Alloc> = std::basic_string<char>]
/usr/include/c++/4.6/bits/basic_string.tcc:171:5: note:   no known conversion for argument 1 from 'TCHAR* {aka wchar_t*}' to 'const std::basic_string<char>&'
/usr/include/c++/4.6/bits/basic_string.tcc:179:5: note: std::basic_string<_CharT, _Traits, _Alloc>::basic_string(const _Alloc&) [with _CharT = char, _Traits = std::char_traits<char>, _Alloc = std::allocator<char>]
/usr/include/c++/4.6/bits/basic_string.tcc:179:5: note:   no known conversion for argument 1 from 'TCHAR* {aka wchar_t*}' to 'const std::allocator<char>&'
/usr/include/c++/4.6/bits/basic_string.h:432:7: note: std::basic_string<_CharT, _Traits, _Alloc>::basic_string() [with _CharT = char, _Traits = std::char_traits<char>, _Alloc = std::allocator<char>]
/usr/include/c++/4.6/bits/basic_string.h:432:7: note:   candidate expects 0 arguments, 1 provided
Source/util.cpp:604:16: error: could not convert 'result' from 'std::string {aka std::basic_string<char>}' to 'tstring {aka std::basic_string<wchar_t>}'
Source/util.cpp: In function 'bool GetDLLVersionUsingRE(const tstring&, DWORD&, DWORD&)':
Source/util.cpp:1034:32: error: cannot convert 'WCHAR* {aka short unsigned int*}' to 'const wchar_t*' for argument '1' to 'size_t wcslen(const wchar_t*)'
Source/util.cpp: In function 'int WideCharToMultiByte(UINT, DWORD, const wchar_t*)':
Source/util.cpp:371:1: warning: control reaches end of non-void function [-Wreturn-type]
Source/util.cpp: In function 'int _wcsnicmp(const wchar_t*, const wchar_t*, size_t)':
Source/util.cpp:246:1: warning: control reaches end of non-void function [-Wreturn-type]
Source/util.cpp: In function 'int update_bitmap(CResourceEditor*, WORD, const TCHAR*, int, int, int)':
Source/util.cpp:105:41: warning: ignoring return value of 'size_t fread(void*, size_t, size_t, FILE*)', declared with attribute warn_unused_result [-Wunused-result]
Source/util.cpp:116:42: warning: ignoring return value of 'size_t fread(void*, size_t, size_t, FILE*)', declared with attribute warn_unused_result [-Wunused-result]
Source/util.cpp:128:43: warning: ignoring return value of 'size_t fread(void*, size_t, size_t, FILE*)', declared with attribute warn_unused_result [-Wunused-result]
Source/util.cpp:138:38: warning: ignoring return value of 'size_t fread(void*, size_t, size_t, FILE*)', declared with attribute warn_unused_result [-Wunused-result]

Source/winchar.cpp: In function 'int WinWStrToInt(const short unsigned int*)':
Source/winchar.cpp:102:35: warning: comparison between signed and unsigned integer expressions [-Wsign-compare]
Source/winchar.cpp:104:10: error: 'm' was not declared in this scope
Source/winchar.cpp:97:23: warning: unused variable 'base' [-Wunused-variable]
